쉘 스크립트는 다른 화면에서 실행되는 명령을 기다립니까?

쉘 스크립트는 다른 화면에서 실행되는 명령을 기다립니까?

나는 예정된 쉘 스크립트를 작성하는 첫 단계에 있습니다. 목표는 Minecraft 서버를 위한 간단한 백업 스크립트를 작성하는 것입니다. 서버가 자체 이름으로 실행 중입니다.화면.

내 스크립트에 다음과 같은 내용이 포함되어 있다고 가정합니다.

screen -S $(screen_name) -p 0 -X stuff "save-all^M"

서버 명령에는 시간이 좀 걸립니다. 내 질문은 스크립트가 즉시 계속됩니까, 아니면 액세스된 화면 내의 명령이 완료될 때까지 기다리는 것입니까? 즉시 반환된다면 어떻게 기다릴 수 있습니까? (이 경우 명령은 save-all현재 세계를 저장합니다. 다음 단계는 파일을 백업 폴더에 복사하는 것이므로 분명히 세계가 올바르게 저장될 때까지 기다리고 싶습니다.) ?

답변1

아니요. screen -X stuff명령은 즉시 반환됩니다.알지 못함처음에 명령을 실행하라는 요청을 받고 있으며 해당 명령이 완료되면 더욱 그렇습니다. 수행하는 작업은 키 누르기 주입뿐입니다(이것이 ^M수동으로 추가해야 하는 이유입니다). 가짜 tty 입력이 전송되자마자 명령이 반환되고 스크립트가 계속됩니다.

일반적으로 터미널 에뮬레이터로서 화면은 특정 터미널 창에서 정확히 무슨 일이 일어나고 있는지 알지 못합니다. 즉, 일반 출력에서 ​​셸 프롬프트(또는 다른 대화형 콘솔 프롬프트)를 구분하는 것이 없습니다.

(이것은 근본적으로 불가능하지 않습니다. 일부 터미널 에뮬레이터에서는 쉘이 "출력 시작/종료" 및 "프롬프트 시작/종료" 마커를 출력하도록 허용합니다. 예:VSCode이를 정확하게 달성하기 위해 Bash에 특수 구성을 삽입합니다. 하지만 이를 위해서는 터미널 에뮬레이터의 지원이 필요합니다.그리고입력 프롬프트를 표시하는 모든 프로그램의 협력이 필요하며 Screen이나 Minecraft는 현재 그렇게 하지 않습니다.)

반면에 스크립트는 단일 프로그램만 다루기 때문에 작업 시간이 더 쉬울 수 있습니다. 즉,특정한일반적인 프롬프트가 아닌 프롬프트가 나타납니다. 를 사용하여 Screen에서 현재 버퍼 "내용"을 쿼리하는 루프를 사용하여 이를 구현할 수 있으며 -X hardcopy, 해당 버퍼의 마지막 줄이~ 아니다아직 Minecraft 프롬프트가 표시되지 않으면 1초 동안 잠을 자고 반복하세요.

이는 프로그램 작동 방식과 유사합니다 . 다양한 종류의 대화형 입력을 자동화하기 위해 Expect 스크립트를 작성할 수 있지만 이러한 스크립트의 핵심은 항상 및 expect세트입니다. 즉, 일부 특정 텍스트가 "프롬프트"임을 미리 아는 것입니다. "라고 문자를 기다리고 있어요.expect "this"expect "that"

[...]
expect "Password:" { send "$password\r" }
expect ">" { send "enable\r" }
expect "Password:" { send "$enablepwd\r" }
expect "#" { send "show run\r" }

다른 Minecraft 관리 스크립트의 기능(예:이 프로젝트최근 Screen에서 tmux로 전환된 )은 1) "save-all"과 "stop"을 동시에 맹목적으로 제출하고, 2) 서버가 스스로 종료될 때까지 서버가 봇 명령을 처리할 때까지 기다리는 것으로 보입니다. 즉, 기다리기보다는명령완료하기 위해 그들은 기다립니다결과그 명령의.

마찬가지로, 다음을 기다리고 싶다면구하다완료하기 위해 "save-all" 명령을 기다릴 필요가 없습니다. 대신 inotifywait서버가 특정 파일 쓰기를 완료할 때까지 기다릴 수 있습니다. 이것은 올바르게 수행하기가 다소 까다로울 수 있습니다(일반적으로 inotifywait를 시작하려면 "coproc"을 사용해야 합니다).~ 전에이벤트를 놓치지 않도록 명령을 내립니다.) 하지만 저장하는 데 시간이 오래 걸릴 수 있으므로아마그냥 나중에 하셔도 좋아요.

echo "waiting..."
inotifywait -q -e close_write /path/to/game
echo "probably done!"

일부 프로그램은 의도적으로 특정 파일을 마지막에 생성하여 다른 도구가 해당 파일이 나타날 때까지 기다릴 수 있도록 합니다.

echo "waiting..."
until [ -e /path/to/marker_file ]; do sleep 1; done
echo "marker file showed up"

관련 정보