Dalam dunia * nix, apakah ada cara bagi skrip shell untuk memiliki informasi tentang program mana yang telah menjalankannya?
Contoh:
/path/to/script1 /path/to/script_xyz
dalam skenario imajiner ini, script_xyz
akan memiliki informasi jalur ( /path/to/script1
)
atau
memproses PID
entitas yang telah menjalankannya.
Catatan: Saya ingin tahu tentang berbagai solusi dan pendekatan, saya tidak berharap ini benar-benar mungkin terjadi
shell-script
shell
process
debugging
Miloš Đakonović
sumber
sumber
Jawaban:
Sering ada kebingungan antara proses forking dan eksekusi.
Ketika Anda melakukannya pada prompt
bash
shell.Proses P1 yang mengeluarkan
$
prompt itu sedang menjalankanbash
kode. Itubash
kode garpu proses baru P2 yang mengeksekusi/bin/sh
yang kemudian mengeksekusi/usr/bin/env
, yang kemudian mengeksekusi/bin/ps
.Jadi P2 pada gilirannya dieksekusi kode
bash
,sh
,env
danps
.ps
(atau perintah lain seperti skrip yang akan kami gunakan di sini) tidak memiliki cara untuk mengetahui bahwa itu telah dieksekusi olehenv
perintah.Yang bisa dilakukan adalah mencari tahu apa proses id induknya, yang dalam hal ini akan menjadi P1 atau
1
jika P1 telah mati dalam interval atau di Linux proses lain yang telah ditunjuk sebagai subreaper bukan1
.Ia kemudian dapat meminta sistem untuk perintah apa yang sedang dijalankan proses (seperti dengan
readlink /proc/<pid>/exe
di Linux) atau argumen apa yang diteruskan ke perintah terakhir yang dijalankan (seperti denganps -o args= -p <pid>
).Jika Anda ingin skrip Anda tahu apa yang memintanya, cara yang dapat diandalkan adalah meminta penyerang memberi tahu. Itu bisa dilakukan misalnya melalui variabel lingkungan. Misalnya
script1
dapat ditulis sebagai:Dan
script2
:$INVOKER
akan ( umumnya ) berisi path kescript1
. Dalam beberapa kasus, ini mungkin merupakan jalur relatif, dan jalur tersebut akan relatif terhadap direktori kerja saat ini pada saatscript1
dimulai. Jadi jikascript1
mengubah direktori kerja saat ini sebelum memanggilscript2
,script2
akan mendapatkan informasi yang salah tentang apa yang memanggilnya. Jadi mungkin lebih baik untuk memastikan$INVOKER
berisi path absolut (lebih disukai menjaga nama dasarnya) seperti dengan menulisscript1
sebagai:Dalam shell POSIX,
$PPID
akan berisi pid dari induk dari proses yang mengeksekusi shell pada saat inisialisasi shell. Setelah itu, seperti yang terlihat di atas, proses induk dapat berubah jika proses id$PPID
mati.zsh
dalamzsh/system
modul, dapat meminta pid induk saat ini dari shell (sub-) saat ini dengan$sysparams[ppid]
. Dalam shell POSIX, Anda bisa mendapatkan ppid saat ini dari proses yang mengeksekusi penerjemah (dengan asumsi itu masih berjalan) denganps -o ppid= -p "$$"
. Denganbash
, Anda bisa mendapatkan ppid dari shell (sub-) saat ini denganps -o ppid= -p "$BASHPID"
.sumber
Ya, suatu program dapat mengetahui siapa orang tuanya.
Untuk mengilustrasikannya, mari kita buat dua skrip bash. Yang pertama melaporkan PID-nya dan memulai skrip kedua:
Skrip kedua melaporkan ID prosesnya, PID induknya, dan baris perintah yang digunakan untuk menjalankan induknya:
Sekarang, mari kita jalankan:
Seperti yang Anda lihat, skrip kedua sebenarnya tahu PID dari induknya. Menggunakan
ps
, PID itu mengungkapkan baris perintah yang digunakan untuk memanggil orang tua.Untuk diskusi tentang PPID secara lebih mendalam, lihat jawaban Stéphane Chazelas .
sumber
s1
,s2
danPPID
nilai tetapi kemudian, dalam beberapa baris setelahERROR: Unsupported SysV option.
dan beberapa baris dengan penjelasan tambahan dan - nilai kosong untukParent command
ps
dariprocps-ng
paket, versi 3.3.12. Seperti yang disarankan Jasen, Anda mungkin menggunakan versi yang berbeda yang mungkin memerlukan sintaks yang berbeda untuk mencetak baris perintah induk. Cobaps -f | grep $PPID
.