백그라운드에서 실행 중인 프로세스로 인해 터미널이 손상될 수 있음

백그라운드에서 실행 중인 프로세스로 인해 터미널이 손상될 수 있음

나는 이것을 가지고있다 makefile:

all: 
        sudo watch "ls -l" > /dev/null &
        @echo line 1
        @echo line 2
        @echo line 3
        @echo line 4

달리기 watch(또는 어떻게든 터미널을 변경하는 다른 프로세스) 터미널이 파손되었습니다. 이것이 출력입니다. 이렇게 넓은 공간을 볼 수 있습니다. 또한 다음과 같은 글을 쓸 때 문자가 보이지 않습니다.

me@me:/tmp$ make
watch "ls -l" > /dev/null &
line 1
line 2
      line 3
            line 4
                  me@me:/tmp$ 

프로세스가 터미널을 변경하는 것을 방지하는 방법이 있습니까?
밝히다: watch딱 하나만재현 가능한 예. 데몬으로 실행해야 하는 다른 응용 프로그램을 사용하고 있지만 여전히 터미널이 중단됩니다.


편집: 이 애플리케이션을 실행합니다(이 예에서는 애플리케이션은 watch).sudo
해결책없이 시작하는 것입니다. sudo그러면 터미널이 파괴되지 않습니다.
이것의 단점은 chown이 과정이 필요하지 않다는 것입니다 root:root.

답변1

시계는 디자인적으로 터미널을 업데이트했습니다. 개체를 "감시"하고 개체의 현재 버전(또는 -d를 사용하여 개체에 대한 변경 사항)을 표시합니다. watch가 유용한 예는 CPU 온도를 모니터링하려는 경우 새 터미널을 열고 다음 명령을 실행하면 출력이 센서에 의해 기록된 온도로 2초마다 업데이트되는 것입니다.

watch -x cat /sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon0/temp1_input

왜 "ls -l"을 보고 싶은지 잘 모르겠습니다. 출력을 기록하는 쉘 스크립트를 만들 수 있습니까?

#!/bin/bash

while :
do 
   date +"%H:%M:%S" >> /var/log/ls.log
   ls -l >> /var/log/ls.log   
   sleep 2
done

새 파일이나 수정된 ​​파일을 기록하려면 다음을 수행하십시오.

 #!/bin/bash
    
    while :
    do 
       find -newer /var/log/ls.log >> /var/log/ls.log
       date +"%H:%M:%S" >> /var/log/ls.log  
       sleep 2
    done

수면 시간을 늘리고 싶을 수도 있습니다. 시계의 기본 설정이므로 저는 2로 설정했습니다.

출력이 들여쓰기되어 있고 출력 후에 입력한 문자를 볼 수 없는 이유는 Bash가 아니라 터미널 때문입니다.

터미널 프로그램의 설정을 확인하고 용어 유형이 인코딩과 일치하는지 확인하세요(예: utf8, ANSII 등). 터미널은 커서를 줄의 시작 부분(\r)으로 재설정하는 대신 커서를 한 줄 아래(\n)만 이동합니다. 이는 파일이 Windows에서 생성된 다음 Linux로 이동된 경우 또는 파일이 Linux에서 생성되어 Windows로 이동된 경우에도 발생할 수 있습니다.

입력한 문자는 출력의 마지막 줄 뒤에 나타납니다. 그래서 당신은 그것을 볼 수 없습니다.

답변2

프로세스가 터미널을 변경하는 것을 방지하는 방법이 있습니까?

설마. 터미널 상태는 터미널 전체에 적용되며 권한이 있는 모든 프로세스에 의해 변경될 수 있습니다.

$ tty
/dev/ttys007
$ stty -a | grep ' erase'
        eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
$ stty erase '#'
$ stty -a | grep ' erase'
        eol2 = <undef>; erase = #; intr = ^C; kill = ^U; lnext = ^V;

연습을 통해 해당 변경 사항을 취소하는 방법을 알아낼 수 있습니다. 또 다른 연습은 어떤 쉘이나 프로그램이 erase전통적인지 확인하는 것입니다 #("UNIX 프로그래밍 환경"(1984)에 나와 있음).

그렇지 않으면 대화형 프로그램이 백그라운드에서 실행되도록 설계되지 않았으며 터미널 상태를 변경하지 않더라도 해당 출력이 다른 프로그램의 출력과 인터리브되어 읽기 어려울 수 있거나 SIGTTIN 또는 영구적인 영향을 받을 수 있습니다. SIGTTOU 신호. 백그라운드에서 터미널과 상호작용해 보세요. 래더링은 터미널 상태(또는 라인 프린터)가 프로세스에서 예상하는 상태와 동기화되지 않는 일반적인 문제입니다. CR/NL 처리에 영향을 미치는 다양한 플래그 termios( INLCRIGNCR)가 매뉴얼 페이지에 문서화되어 있습니다. 백그라운드 프로세스에서 X를 설정해야 하는데 셸이 X를 다시 Y로 변경하면 충돌이 발생하는 것입니다.

일부 운영 체제에는 프로그램이 터미널 설정을 변경하는 것을 방지할 수 있는 보안 프레임워크가 있을 수 있습니다. 이 경우 대화형 프로그램은 설계된 대로 실행되지 않거나 작동하지 않을 수 있으며 결국 구성을 올바르게 설정하기 위해 보안 프레임워크를 조작하는 데 많은 시간을 소비하게 될 수 있습니다.

tmux또 다른 옵션은 다른 창에서 실행 중인 다른 프로그램을 방해하지 않는 고유한 pty(예: 아래)에서 프로세스를 실행하는 것입니다 .

stty -g(지원되는 경우)를 사용하면 나중에 복원하기 위해 (일부) 터미널 설정을 저장할 수 있지만 백그라운드 프로세스가 터미널 상태를 영원히 조작하거나 백그라운드 프로세스에 복원된 값과 충돌하는 설정이 필요한 경우에는 작동하지 않습니다. 대부분의 프로그램은 시작 시 또는 기타 특정 이벤트(예: control+에 반응 z한 다음 포그라운드로 이동)에서만 터미널 상태를 변경합니다. 프로그램을 사용하여 tcsetattr(3)다음을 수행 할 수 있습니다.단말기 상태 직접 수정.

일부 셸은 프로그램이 종료된 후 터미널 상태를 복원하는 데 다른 셸보다 뛰어납니다. ZSH를 Heirloom Bourne Shell 등과 비교하십시오. 다양한 프로그램은 특정 터미널 설정을 무시합니다. 예를 들어 ZSH는 erase에 대한 설정을 무시 #하지만 다른 프로그램( cat예:) 에서는 #이전 문자를 제거해야 합니다.

연습 팁: lnext"literally next"의 약어는 일반적으로 control+ v또는 stty -a무엇이든입니다. 프로그램이 이를 존중하지 않을 수도 있습니다...

답변3

  • watch데몬 의 경우 stdin을 리디렉션(예: add)하여 < /dev/null애초에 터미널에 액세스하지 않도록 할 수도 있습니다.
  • 당신은 그것이 데몬이라고 말했으므로 또 다른 방법은 시스템 또는 초기화에서 실행하여 다시 tty에 닿지 않도록 방지하는 것입니다.
  • 이것이 단지 테스트이고 복원이 필요한 경우에도 있습니다.stty sane

관련 정보