나는 PID를 포함하는 간단한 스크립트를 작성했습니다 echo
.
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
나는 3844
한 터미널에서 해당 스크립트를 실행하고 (반복적으로 말함) tail
다른 터미널에서 파일 설명자를 실행하려고합니다.
$ tail -f /proc/3844/fd/1
화면에 아무 것도 인쇄하지 않고 까지 멈춥니다 ^c
. 왜?
또한 모든 STD 파일 설명자(IN/OUT/ERR)는 동일한 지점에 연결됩니다.
$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14
이게 정상인가요?
우분투 그놈 14.04를 실행 중입니다.
이 문제가 UL이 아닌 SO 또는 SU에 속한다고 생각되면 알려주시기 바랍니다.
답변1
strace
하나 를 만들면 tail -f
모든 것이 설명됩니다. 흥미로운 부분:
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 fstatfs(3, {...}) = 0
13791 inotify_init() = 4
13791 inotify_add_watch(4, "/path/to/file", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 read(4, 0xd981c0, 26) = -1 EINTR (Interrupted system call)
그게 뭘 할 수 있지? inotify
파일에 대한 핸들러를 설정한 다음 파일에 어떤 일이 발생할 때까지 기다립니다. 커널이 tail
이 inotify 핸들러를 통해 파일이 변경되었음을 표시하면(보통 추가됨) tail
1) 해당 파일을 찾고 2) 변경 사항을 읽으며 3) 이를 화면에 씁니다.
/proc/3844/fd/1
시스템에 /dev/pts/14
문자 장치인 심볼릭 링크가 있습니다. 이를 통해 접근할 수 있는 "메모리 맵" 같은 것은 없습니다. 따라서 액세스할 수 있는 디스크나 메모리 영역이 없기 때문에 콘텐츠 변경 사항에 대해 inotify에 서명할 수 없습니다.
이 캐릭터 장치는 실제로 네트워크 소켓처럼 작동하는 가상 터미널입니다. 이 가상 터미널에서 실행되는 프로그램은 장치에 연결하고(텔넷을 통해 TCP 포트에 로그인한 것처럼) 쓰고 싶은 내용을 씁니다. 일반적으로 호출을 통해 처리되는 잠금 화면, 터미널 제어 시퀀스 등과 같은 더 복잡한 것들도 있습니다 ioctl()
.
내 생각에는 당신이 어떤 방식으로든 가상 터미널을 보고 싶어하는 것 같습니다. Linux에서 수행할 수 있지만 그렇게 간단하지는 않습니다. 일부 네트워크 프록시와 유사한 기능이 필요하고 이러한 호출에 대한 일부 까다로운 사용법이 필요합니다 ioctl()
. 하지만 이를 가능하게 해주는 도구가 있습니다.
지금은 어떤 데비안 패키지에 이 작업을 수행할 수 있는 도구가 있는지 기억나지 않지만, 조금만 인터넷 검색을 하면 쉽게 찾을 수 있을 것입니다.
확장하다:@Jajesh가 여기에서 언급했듯이(나에게 제공한 경우 +1) 도구 이름은 입니다 watch
.
확장 #2:@kelnos는 간단한 것만으로도 cat /dev/pts/14
충분하다고 언급했습니다. 나는 그것을 시도했고 네, 작동하지만 올바르지 않습니다. 이것저것 많이 실험해보진 않았지만 저 가상터미널로 들어가는 출력이 사라지는 것 같아요누구나명령 또는 원래 위치 로 이동 cat
하되 동시에 둘 다로 이동하지 마십시오. 그러나 이것은 확실하지 않습니다.
답변2
의 파일은 /dev/pts
일반 파일이 아니며 가상 터미널에 대한 핸들입니다. 읽기 및 쓰기 동작은 pts
대칭이 아니지만(즉, 작성된 내용은 일반 파일이나 fifo/파이프처럼 나중에 읽을 수 있음) 가상 터미널을 생성하는 프로세스에 의해 규제됩니다. 몇 가지 일반적인 동작은 xterm 또는 SSH 또는 agetty 또는 화면. 제어 프로세스는 일반적으로 pts
파일을 읽고 이를 화면에 렌더링하는 프로세스 에 키 입력을 전달합니다 pts
.
따라서 tail -f /dev/pts/14
스크립트를 시작한 터미널에서 누른 키가 출력되며, 이렇게 하면 터미널에 echo meh > /dev/pts/14
메시지가 나타납니다.meh
답변3
얼마 전에 나는 하나를 발견했다.약간해결책때때로pid
프로세스가 있고 친숙하지 않은 결과를 볼 수 있다고 가정하고 STDOUT에 출력되는 내용을 확인해야 할 필요성에 응답합니다 .
sudo strace -p $pid 2>&1 | grep write\(
답변4
이를 위해 해야 할 일은 tail이 아니라 출력을 지켜보는 것입니다.
$ watch -n2 ls -l /proc/3844/fd/
이것이 당신에게 필요한 것이기를 바랍니다.