foocaller
Ruby 스크립트를 호출하는 bash 스크립트가 있습니다 foo
.
푸콜러
/path/to/foo
내에서 foo
의 경로를 얻고 싶습니다 foocaller
. 수행원이 제안, 이를 위해 다음 코드를 넣었습니다.
푸
#!/usr/bin/env ruby
puts File.read("/proc/#{Process.ppid}/cmdline")
내가 실행할 때 :
$ bash foocaller
그런 다음 원하는 것을 얻습니다.
bash^@/path/to/foocaller
하지만 내가 직접 전화할 때 foocaller
:
$ foocaller
그러면 나는 이것을 얻습니다 :
/bin/bash^@--noediting^@-i
에 대한 경로를 표시하지 않습니다 foocaller
. 을 사용하지 않고 foocaller
직접 호출하여 의 경로를 어떻게 알 수 있나요 ?foocaller
bash
답변1
많은 쉘은 동일한 프로세스에서 명령을 실행하여 스크립트의 마지막 명령을 최적화합니다.
$ sh -c 'ps
ps'
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 sh
32697 pts/3 00:00:00 ps
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 ps
두 번째 프로세스가 ps
처음 실행된 프로세스 sh
(32696)에서 어떻게 실행되었는지 확인하세요. 그 부모는 sh
의 부모입니다(제 경우에는 zsh
대화형 셸).
다음 줄 을 추가하면 이를 방지할 수 있습니다 exit
.
#! /bin/sh -
foo
exit
sh
완료 foo
후에도 해석할 내용이 더 많기 때문에 동일한 프로세스에서 실행할 수 없습니다 . foo
따라서 대신 foo
다른 프로세스에서 실행되고 기다립니다. 그런 다음 실행합니다 exit
( 와 동일한 종료 상태로 스크립트가 종료됩니다 foo
).
이제 여기에 프로세스를 저장할 수 있으므로 이는 최적이 아닙니다.
foo
경로에 대해 알 수 있는 더 좋은 방법 foocaller
은 다음과 같이 말하는 것입니다.
#! /bin/sh -
CALLER=$0 foo
그런 다음 환경 변수를 foo
쿼리하여 CALLER
호출자의 경로를 얻을 수 있습니다( import os;print(os.environ["CALLER"])
파이썬의 경우).