Thường có sự nhầm lẫn giữa quá trình rèn và thực hiện.
Khi bạn làm tại dấu nhắc của một bash
vỏ.
$ sh -c 'exec env ps'
Quá trình phát hành P1 đó $
hiện đang chạy bash
mã. bash
Mã đó tạo ra một quy trình P2 mới thực thi /bin/sh
, sau đó thực thi /usr/bin/env
, sau đó thực thi /bin/ps
.
Vì vậy, P2 đã lần lượt thực hiện quy tắc ứng bash
, sh
, env
và ps
.
ps
(hoặc bất kỳ lệnh nào khác như tập lệnh mà chúng ta sẽ sử dụng thay vào đây) không có cách nào để biết rằng nó đã được thực thi bởi env
lệnh.
Tất cả những gì có thể làm là tìm ra id tiến trình mẹ của nó là gì, trong trường hợp này sẽ là P1 hoặc 1
nếu P1 đã chết trong khoảng thời gian hoặc trên Linux, một quy trình khác được chỉ định là một phản ứng phụ thay vì 1
.
Sau đó, nó có thể truy vấn hệ thống về lệnh nào mà quá trình đó hiện đang chạy (như với readlink /proc/<pid>/exe
Linux) hoặc đối số nào được chuyển đến lệnh cuối cùng mà nó đã thực thi (như với ps -o args= -p <pid>
).
Nếu bạn muốn kịch bản của bạn biết cái gì đã gọi nó, một cách đáng tin cậy sẽ là người mời nói với nó. Điều đó có thể được thực hiện ví dụ thông qua một biến môi trường. Ví dụ script1
có thể được viết là:
#! /bin/sh -
INVOKER=$0 script2 &
Và script2
:
#! /bin/sh -
printf '%s\n' "I was invoked by $INVOKER"
# and in this case, we'll probably find the parent process is 1
# (if not now, at least one second later) as script1 exited just after
# invoking script2:
ps -fp "$$"
sleep 1
ps -fp "$$"
exit
$INVOKER
sẽ ( nói chung ) chứa một đường dẫn đến script1
. Trong một số trường hợp, nó có thể là một đường dẫn tương đối và đường dẫn sẽ liên quan đến thư mục làm việc hiện tại tại thời điểm script1
bắt đầu. Vì vậy, nếu script1
thay đổi thư mục làm việc hiện tại trước khi gọi script2
, script2
sẽ nhận được thông tin sai như những gì đã gọi nó. Vì vậy, có thể tốt hơn để đảm bảo $INVOKER
chứa một đường dẫn tuyệt đối (tốt nhất là giữ tên cơ sở) như bằng cách viết script1
như sau:
#! /bin/sh -
mypath=$(
mydir=$(dirname -- "$0") &&
cd -P -- "$mydir" &&
pwd -P) && mypath=$mypath/$(basename -- "$0") || mypath=$0
... some code possibly changing the current working directory
INVOKER=$mypath script2
Trong shell POSIX, $PPID
sẽ chứa pid của cha mẹ của quá trình thực thi shell tại thời điểm khởi tạo shell đó. Sau đó, như đã thấy ở trên, quy trình cha có thể thay đổi nếu quá trình id $PPID
chết.
zsh
trong zsh/system
mô-đun, có thể truy vấn pid cha hiện tại của shell (sub-) hiện tại với $sysparams[ppid]
. Trong shell POSIX, bạn có thể nhận được ppid hiện tại của quá trình thực thi trình thông dịch (giả sử nó vẫn đang chạy) ps -o ppid= -p "$$"
. Với bash
, bạn có thể lấy ppid của shell (sub-) hiện tại với ps -o ppid= -p "$BASHPID"
.