/proc/의 내용/cmdline 파일은 스크립트 shebang에 따라 달라집니다.

/proc/의 내용/cmdline 파일은 스크립트 shebang에 따라 달라집니다.

bash이라는 스크립트 가 있습니다 test.sh. shebang을 사용 startproc하면 파일 은 다음과 같습니다.#!/usr/bin/env bashtest.sh/proc/<PID>/cmdline

SERVER:~ # cat /proc/29481/cmdline
bash/root/user/test.shSERVER:~ # 
SERVER:~ # 

#!/bin/bash이제 Shebang 줄을 : 으로 변경하면 /proc/<PID>/cmdline파일은 다음과 같습니다.

SERVER:~ # cat /proc/29729/cmdline
/bin/bash/root/user/test.shSERVER:~ # 
SERVER:~ # 

이 동작의 원인은 무엇입니까? 파일 내용이 /proc/<PID>/cmdline스크립트 shebang에 따라 달라지나요? 문제는 이전 옵션을 사용하는 경우 checkproc서비스 를 감지할 수 없다는 killproc것 입니다 . 나는 openSUSE 11.4와 .startproctest.shsysvinit-tools-2.88-37.47.1.x86_64

답변1

예, 수행된 시스템 호출 cmdline에 따라 정규화된 경로는 경로 검색에 나타나는 경로와 다를 수 있습니다.exec*env(1)

bash-4.1$ cat aaa
#!/bin/bash
xxd /proc/$$/cmdline
bash-4.1$ cat bbb
#!/usr/bin/env bash
xxd /proc/$$/cmdline
bash-4.1$ ./aaa
0000000: 2f62 696e 2f62 6173 6800 2e2f 6161 6100  /bin/bash../aaa.
bash-4.1$ ./bbb
0000000: 6261 7368 002e 2f62 6262 00              bash../bbb.
bash-4.1$ 

strace세부정보 표시:

bash-4.1$ strace ./aaa 2>&1 | grep exec
execve("./aaa", ["./aaa"], [/* 57 vars */]) = 0
bash-4.1$ strace ./bbb 2>&1 | grep exec
execve("./bbb", ["./bbb"], [/* 57 vars */]) = 0
execve("/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/sbin/bash", ["bash", "./bbb"], [/* 57 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/bash", ["bash", "./bbb"], [/* 57 vars */]) = 0
bash-4.1$ 

Linux 전용 스크립트인 경우 위치는 변경되지 않을 수 있습니다(예외: , bash다른 곳에 를 포함하는 bash일종의 소프트웨어 라이브러리 가 있습니다). 따라서 정규화된 경로를 사용하는 것이 가장 적합할 것입니다. 이렇게 하면 env(1)경로 검색 시 혼란을 피하고 init 도구와의 호환성을 얻을 수 있습니다.

답변2

프로세스의 명령줄은 argv매개변수 요소로 구성됩니다.execve시스템 호출. 이 매개변수는 0부터 시작하는 번호의 배열입니다. 여기서 1부터 n까지의 요소는 명령을 호출할 때 전달되는 매개변수이고, 요소 0은 호출 쉘이나 다른 프로그램에 의해 선택됩니다 execve. 관례적으로 요소 0은 명령을 지정하는 문자열입니다.

Shebang 라인은 커널에 의해 처리됩니다. 커널은 #!매직 접두사 뒤에 지정된 경로 인 매개변수 0을 삽입합니다 . 따라서 /root/user/test.sh0=에서 하나의 인수로 실행하는 경우 1=에서는 두 개의 인수로 호출합니다. 로 시작할 때 커널은 shebang을 보고 인수 목록을 0= , 1= , 2= 로 다시 작성합니다.foostartprocstartprocexecve/root/user/test.shfoo/root/user/test.sh/bin/bash/root/user/test.sh/bin/bash/root/user/test.shfoo

shebang 줄이 이면 #!/bin/env bash커널은 인수 목록에 프로그램과 인수라는 두 항목을 삽입합니다. (Linux는 여기서 단일 인수로 제한됩니다.) 따라서 이 경우 호출은 0= /bin/env, 1= bash, 2= /root/user/test.sh, 3= 으로 변환됩니다 foo. 프로그램 env은 작업을 완료하고 새로운 execve시스템 호출 0= bash(매개변수 0이 명령을 지정하는 데 사용되는 경로라는 규칙을 준수함), 1= /root/user/test.sh, 2= 을 발행합니다 foo.

모든 경우에 /root/user/test.sh이는 프로시저에 대한 첫 번째 인수가 됩니다.

관련 정보