쉘 스크립트가 어떤 프로그램을 실행했는지 알 수 있는 방법이 있습니까?

쉘 스크립트가 어떤 프로그램을 실행했는지 알 수 있는 방법이 있습니까?

*nix 세계에서 쉘 스크립트가 어떤 프로그램을 실행했는지에 대한 정보를 얻을 수 있는 방법이 있습니까?


예:

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

이 가상 시나리오에서는 경로 정보( ) script_xyz가 있습니다 ./path/to/script1

또는

프로세스 PID

이를 실행하는 엔터티입니다.

참고: 다양한 솔루션과 접근 방식이 궁금합니다. 실제로는 가능하지 않을 것 같습니다.

답변1

프로세스 분기와 실행 사이에 혼란이 자주 발생합니다.

쉘 프롬프트에서 이 작업을 수행할 때 bash.

$ sh -c 'exec env ps'

프로세스P1$코드가 현재 실행 중인 동안 이 프롬프트를 발행하십시오 bash. 이 bash코드는 새로운 프로세스를 포크합니다P2하고 /bin/sh또 하고 /usr/bin/env또 하세요 /bin/ps.

그래서P2bash, sh, 의 코드 env가 순서대로 실행됩니다 ps.

psenv(또는 여기서 사용하는 스크립트와 같은 다른 명령) 은 명령이 실행되었는지 여부를 알 수 없습니다 .

할 수 있는 일은 상위 프로세스 ID가 무엇인지 알아내는 것뿐입니다. 이 경우에는P1아니면 1만약에P1이 간격 내에 사망했거나 Linux에서는 다음과 같이 지정된 다른 하나가 사망했습니다.대리 사신바꾸다 1.

그런 다음 프로세스가 어떤 명령인지 시스템에 쿼리할 수 있습니다.지금실행 중이거나( readlink /proc/<pid>/exeLinux에서와 같이) 실행한 마지막 명령에 전달된 인수(Linux에서와 같이 ps -o args= -p <pid>).

스크립트가 무엇을 호출했는지 알기를 원하는 경우 호출자에게 이를 알려주는 것이 신뢰할 수 있는 방법입니다. 예를 들어 환경 변수를 통해 이 작업을 수행할 수 있습니다. 예를 들어 다음 script1과 같이 작성할 수 있습니다.

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

그리고 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할 것이다(일반적으로 말하면)에는 에 대한 경로가 포함되어 있습니다 script1. 어떤 경우에는 상대 경로일 수 있으며 경로는 시작 시 현재 작업 디렉터리에 상대적입니다 script1. 따라서 script1호출하기 전에 현재 작업 디렉토리를 변경 하면 해당 디렉토리 script2script2호출된 위치에 대한 잘못된 정보를 얻게 됩니다. 따라서 $INVOKER다음과 같이 절대 경로(기본 이름을 유지하는 것이 좋음)를 포함하는 것이 가장 좋습니다 script1.

#! /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 쉘에는 $PPID쉘이 초기화될 때 쉘을 실행한 상위 프로세스의 pid가 포함됩니다. 나중에 위와 같이 ID가 있는 프로세스가 $PPID종료되면 상위 프로세스가 변경될 수 있습니다.

zshzsh/system모듈 에서 쿼리할 수 있습니다.현재의현재(하위) 쉘의 상위 pid로, 접미사가 붙습니다 $sysparams[ppid]. POSIX 쉘에서는 다음을 얻을 수 있습니다.현재의인터프리터를 실행하는 프로세스의 ppid(아직 실행 중이라고 가정) ps -o ppid= -p "$$". 를 사용하여 bash현재 (하위)쉘의 ppid를 얻을 수 있습니다 ps -o ppid= -p "$BASHPID".

답변2

예, 프로그램은 상위 프로그램이 누구인지 알 수 있습니다.

이를 설명하기 위해 두 개의 bash 스크립트를 만듭니다. 첫 번째 스크립트는 PID를 보고하고 두 번째 스크립트를 시작합니다.

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

두 번째 스크립트는 프로세스 ID, 상위 프로세스의 PID 및 상위 프로세스를 실행하는 데 사용되는 명령줄을 보고합니다.

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

이제 실행해 보겠습니다.

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

보시다시피 두 번째 스크립트는 실제로 상위 스크립트의 PID를 알고 있습니다. 사용된 ps이 PID는 상위를 호출하는 데 사용되는 명령줄을 표시합니다.

PPID에 대한 더 자세한 내용은 Stéphane Chazelas의 글을 참조하세요.답변.

관련 정보