왜`tail -f / proc / $ pid / fd / 1`을 할 수 없습니까? 스크립트를 작성했습니다 . #/bin/bash while true; do

echoPID 를 나타내는 간단한 스크립트를 작성했습니다 .

#/bin/bash

while true; do
    echo $$;
    sleep 0.5;
done

3844한 터미널에서 스크립트를 반복 실행 하고 다른 터미널 tail에서 파일 설명자를 시도 하고 있습니다.

$ tail -f /proc/3844/fd/1

화면에 아무것도 인쇄하지 않고까지 멈 춥니 다 ^c. 왜?

또한 모든 STD 파일 설명자 (IN / OUT / ERR)는 동일한 pt에 연결됩니다.

$ 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에 속한다고 생각되면 알려주십시오.



답변

메이크업 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 핸들러를 통해 파일이 변경되었다고 (일반적으로 추가되었다고) tail1) 탐색하면 2) 변경 사항을 읽습니다. 3) 변경 사항을 화면에 씁니다.

/proc/3844/fd/1시스템에서에 대한 기호 링크 /dev/pts/14는 문자 장치입니다. 그것에 의해 접근 될 수있는 “메모리 맵”과 같은 것은 없다. 따라서 액세스 할 수있는 디스크 나 메모리 영역이 없기 때문에 변경 사항이 inotify에 서명 될 수있는 것은 없습니다.

이 문자 장치는 가상 터미널로 마치 마치 네트워크 소켓처럼 작동합니다. 이 가상 터미널에서 실행중인 프로그램은이 장치에 연결하고 (TCP 포트에 텔넷으로 연결 한 것처럼) 작성하려는 내용을 작성합니다. 화면 잠금, 터미널 제어 시퀀스 등과 같은 복잡한 작업도 있으며 일반적으로 ioctl()통화로 처리됩니다 .

나는 당신이 어떻게 든 가상 단말기를보고 싶다고 생각합니다. 리눅스에서 할 수는 있지만 그렇게 간단하지는 않으며 네트워크 프록시와 같은 기능이 필요하며 이러한 ioctl()호출 의 약간 까다로운 사용법이 필요 합니다. 그러나 그렇게 할 수있는 도구가 있습니다.

현재 어떤 데비안 패키지 가이 목표를위한 도구를 가지고 있는지 기억이 나지 않지만 약간의 인터넷 검색으로 쉽게 찾을 수 있습니다.

확장 : @Jajesh가 여기에서 언급했듯이 (당신이 나에게 준 경우 +1을주십시오), 도구의 이름은 watch입니다.

확장 # 2 : @kelnos가 언급했듯이 단순함 cat /dev/pts/14도 충분했습니다. 나는 그것을 시도했지만 그렇습니다. 그러나 제대로 작동하지 않았습니다. 나는 그와 많은 실험을하지 않았다, 그러나 출력이 사라 가상 터미널로가는 경우 같은 날 것으로 보인다 하거나 받는 cat명령 또는 원래 위치로, 결코 모두. 그러나 확실하지 않습니다.


답변

파일 /dev/pts은 일반 파일이 아니며 가상 터미널에 대한 핸들입니다. pts몇 가지 일반적인 것들입니다 : 읽기 및 쓰기 동작 (즉,이 나중에 일반 파일 또는 FIFO / 파이프처럼, 그것에서 읽을 수로 작성 무슨)하지만 가상 터미널을 생성하는 과정에 의해 매개 대칭되지 않습니다 xterm 또는 ssh 또는 agetty 또는 화면. 제어 프로세스는 일반적으로 pts파일 을 읽는 프로세스에 키 누름을 전달하고 파일에 작성된 내용을 화면에 렌더링합니다 pts.

따라서, tail -f /dev/pts/14당신은 당신의 스크립트를 시작되는 터미널에 탭 키를 인쇄 할 것이고, 당신이 경우에 메시지가 단말기에 표시됩니다.echo meh > /dev/pts/14meh


답변

내가 찾은 몇 년 전에 것을 해결 때로는 가정, STDOUT에 출력되고 있는지 확인하는 필요성에 응답 당신은이 pid과정의 당신은 눈에게 비우호적 인 결과를 맨 손으로 할 수 있습니다

sudo strace -p $pid 2>&1 | grep write\(


답변

나는 꼬리가 아닌 이것을 위해 당신이해야 할 일은 출력을 보는 것이라고 생각합니다.

$ watch -n2 ls -l /proc/3844/fd/

이것이 당신이 원하는 희망입니다.


답변