/ proc / self는 구문 설탕입니다. / proc /를 오염시키는 지름길이며 getpid () syscall의 결과입니다 (bash에서 메타 변수 $$로 액세스 가능). 쉘 스크립팅의 경우 많은 명령문이 다른 프로세스를 호출하고 자체 PID로 완료되는 것처럼 혼란 스러울 수 있습니다. PID는 종종 죽은 프로세스를 나타냅니다. 치다:
root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan 1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593
'/ bin / ls'는 디렉토리의 경로를 평가하여 디렉토리의 내용을 읽는 프로세스의 PID (새로 작성된 / bin / ls 프로세스)이므로 / proc / 26563으로 해석합니다. 그러나 파이프 라인의 다음 프로세스, 셸 스크립팅의 경우 또는 프롬프트가 표시 될 때까지 (대화식 셸의 경우) 경로가 더 이상 존재하지 않고 정보 출력이 존재하지 않는 프로세스를 나타냅니다.
그러나 이것은 외부 명령에만 적용됩니다 (쉘 자체에 내장되는 것이 아니라 실제 실행 가능한 프로그램 파일 인 명령). 따라서 경로 이름을 외부 프로세스 / bin / ls에 전달하지 않고 filename globbing을 사용하여 디렉토리의 내용 목록을 얻으면 다른 결과를 얻을 수 있습니다.
root@vps01:~# ls /proc/self/fd
0 1 2 3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
첫 번째 줄에서, 쉘은 exec () syscall을 통해 '/ bin / ls'라는 새로운 프로세스를 생성하고 "/ proc / self / fd"를 argv [1]로 전달했습니다. '/ bin / ls'는 차례로 / proc / self / fd 디렉토리를 열고 그 내용을 반복해서 읽은 다음 인쇄합니다.
그러나 두 번째 줄은 장면 뒤에 glob ()를 사용하여 파일 이름 목록을 확장합니다. 이것들은 반향 할 문자열 배열로 전달됩니다. (일반적으로 내부 명령으로 구현되지만 종종 / bin / echo 바이너리도 있습니다.하지만 에코는 문자열 만 다루기 때문에 해당 부분은 실제로 관련이 없습니다. 경로 이름과 관련된 모든 syscall에는 절대로 공급되지 않습니다.)
이제 다음 사례를 고려하십시오.
root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0 1 2 255
여기서 / bin / ls 의 상위 프로세스 인 쉘 은 / proc / self의 하위 디렉토리를 현재 디렉토리 로 만들었습니다 . 따라서 상대 경로 이름은 관점에서 평가됩니다. 가장 좋은 추측은 POSIX 파일 의미와 관련이 있으며 열려있는 파일 설명자를 포함하여 파일에 대한 여러 하드 링크를 만들 수 있습니다 . 따라서 이번에는 / bin / ls가 / proc / $$ / fd / *와 비슷하게 동작합니다.
/proc/self
물론 평가 하는 과정.