Kabuk betiğinin hangi programın çalıştığını bilmesi için bir yol var mı?


13

* Nix dünyasında, kabuk betiğinin hangi programın yürüttüğü hakkında bilgi edinmenin bir yolu var mı?


Misal:

/path/to/script1 /path/to/script_xyz

bu hayali senaryoda, script_xyzyol bilgisi ( /path/to/script1) olurdu

veya

süreç PID

uygulayan varlık.

Not: Farklı çözümler ve yaklaşımlar merak ediyorum, tam olarak bunun mümkün olmasını beklemiyorum


3
Konunuz hangi programın komut dosyasını yürüttüğünü sorar . Ama asıl sorunuz senaryoyu tercüman istiyor gibi görünüyor . Sorunuz gerçekten hangisiyle ilgili?
kasperd

@kasperd Haklısın. Soru programla ilgiliydi, ama aslında tercüman. Bu yüzden bunun ilk etapta mümkün olmadığını hissettim.
Miloš Đakonović

Yanıtlar:


23

Süreç çatallama ile yürütme arasında genellikle karışıklık vardır.

Bir bashkabuk isteminde yaptığınızda .

$ sh -c 'exec env ps'

Bu istemi veren P1 işlemi $şu anda bashkod çalıştırıyor . Bu bashkod yürüten yeni bir işlem P2'yi çatallar ve yürütür /bin/shve /usr/bin/envyürütür /bin/ps.

Yani P2 sırayla kodunu yürüttü bash, sh, envve ps.

ps(veya burada kullanacağımız komut dosyası gibi herhangi bir komutun) envkomut tarafından yürütüldüğünü bilmenin bir yolu yoktur .

Bütün yapabildiği kendi üst süreç kimliği ya olurdu bu durumda, hangi ne olduğunu öğrenmek ise P1 veya 1eğer P1 başka bir işlem aralığında veya Linux üzerinde ölen bir olarak belirlenmiş edildiğini subreaper yerine 1.

Bu süreç olduğunu emredeceğimi Daha sonra için sistem sorgulayabilir anda (olduğu gibi çalışan readlink /proc/<pid>/exeveya Linux) ne (olduğu gibi son çalıştırılan komutun argümanlarla ps -o args= -p <pid>).

Senaryonuzun neyin çağrıldığını bilmesini istiyorsanız, davetlinin bunu söylemesini sağlamak güvenilir bir yol olacaktır. Bu, örneğin bir ortam değişkeni ile yapılabilir. Örneğin script1şu şekilde yazılabilir:

#! /bin/sh -
INVOKER=$0 script2 &

Ve 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( genellikle ) için bir yol içerecektir script1. Bazı durumlarda, bu göreceli bir yol olabilir ve yol, başlangıçtaki geçerli çalışma dizinine göreli olacaktır script1. Bu nedenle , script1aramadan önce geçerli çalışma dizinini değiştirirse, aradığı şey hakkında yanlış bilgi alırsınız. Bu nedenle, aşağıdaki gibi yazarak olduğu gibi mutlak bir yol (tercihen taban adını koruyarak) içerdiğinden emin olmak tercih edilebilir:script2script2$INVOKERscript1

#! /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

POSIX mermilerinde, $PPIDkabuğun başlatılması sırasında mermiyi yürüten işlemin üst öğesinin pid'ini içerecektir. Bundan sonra, yukarıda görüldüğü gibi, kimlik süreci $PPIDölürse üst süreç değişebilir .

zshiçerisinde zsh/systemmodülü, sorgu mevcut olan akım (alt) kabuğun üst PID $sysparams[ppid]. POSIX mermilerinde, yorumlayıcıyı yürüten işlemin geçerli ppid'ini (hala çalıştığını varsayarak) alabilirsiniz ps -o ppid= -p "$$". İle bash, geçerli (alt) kabuğun ppid'ini ile alabilirsiniz ps -o ppid= -p "$BASHPID".


8

Evet, bir program ebeveyninin kim olduğunu bilebilir.

Açıklamak için iki bash betiği oluşturalım. Birincisi PID'sini rapor eder ve ikinci betiği başlatır:

$ cat s1.sh
#!/bin/bash
echo s1=$$
bash s2.sh

İkinci komut dosyası, işlem kimliğini, üst öğesinin PID'sini ve üst öğeyi çalıştırmak için kullanılan komut satırını bildirir:

$ cat s2.sh
#!/bin/bash
echo s2=$$ PPID=$PPID
echo "Parent command: $(ps -o cmd= -q $PPID)"

Şimdi çalıştıralım:

$ bash s1.sh
s1=17955
s2=17956 PPID=17955
Parent command: bash s1.sh

Gördüğünüz gibi, ikinci script aslında üst öğesinin PID'sini biliyor. Kullanılması ps, bu PID ebeveyn çağırmak için kullanılan komut satırını ortaya koymaktadır.

Daha derinlemesine PPID'nin bir tartışma için, Stéphane Chazelas görelim cevabı .


Teşekkürler. Senin örneğin alıyorum komut çalıştırma s1, s2ve PPIDsonra çoklu satırlarda, sonra değerleri ancak ERROR: Unsupported SysV option.boş değer - ve ek açıklama ve birkaç hatlarıParent command
Miloš Djakonovic

John, platformunuzda bulunmayan (veya farklı bir şekilde sağlanan) bazı ps özelliklerini kullanıyorsa ps (1) kılavuz sayfanızı kontrol edin.
Jasen

@Miloshio I kullanılarak yukarıda test psgelen procps-ngpaket versiyonu 3.3.12. Jasen'in önerdiği gibi, büyük olasılıkla ebeveynin komut satırını yazdırmak için farklı bir sözdizimi gerektirebilecek farklı bir sürüm kullanıyorsunuz. Deneyin ps -f | grep $PPID.
John1024
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.