일부 명령이 제공되기를 기다리는 다른 스크립트를 호출하는 쉘 스크립트를 실행하려고 합니다. echo를 사용하여 명령을 전달했지만 작동하지 않습니다. 두 번째 스크립트는 계속해서 입력을 기다립니다.
스크립트 1:
#!/bin/sh
set -x
sh script2.sh
echo ".open Simulation\n"
set +x
하지만 이렇게 하면 결과가 나오지 않습니다. 계속 기다리고 있습니다.
산출:
./script1.sh
+ sh script2
<Nothing appears here>
답변1
기본적으로 Linux 시스템의 모든 프로세스에는 하나의 입력(stdin)과 두 개의 출력(stdout, stderr)이 있습니다. 터미널은 키보드에서 입력을 받아 실행 중인 셸의 stdin으로 보내고, 프로세스에서 stdout 및 stderr을 가져와 화면에 인쇄합니다.
셸(터미널)에서 명령을 실행하면 자체 표준 입력이 프로세스의 표준 입력에 연결되므로 입력하는 모든 키가 명령으로 전송됩니다. 또한 stdout 및 stderr을 자체에 연결합니다(터미널은 이를 화면에 인쇄합니다). 스크립트에서 명령을 실행할 때에도 동일한 일이 발생합니다. stdin, stdout 및 stderr은 상위 프로세스의 명령에 연결되고 결국 터미널로 전파됩니다.
또한 스크립트의 명령은 기본적으로 차단됩니다. 실행 중인 명령이 완료될 때만 다음 명령을 실행합니다.
이를 고려하여 스크립트를 살펴보겠습니다(관심 있는 두 줄로 단순화됨).
sh script2.sh
echo ".open Simulation\n"
그것이 하는 일은 sh(script2.sh 실행)를 실행하고 해당 표준 입력을 스크립트의 표준 입력에 추가하고 완료될 때까지 기다리는 것입니다. 두 번째 줄은 첫 번째 프로세스가 끝날 때까지 실행되지 않습니다.
이제 쉘 에 입력한 모든 내용은 sh .open Simulation\n
로 전송되어 script2.sh
.script2.sh
.open Simulation\n
이제 우리는 무슨 일이 일어났는지 압니다. 어떻게 해결할 수 있나요? 그런 다음 파일이나 기타 프로세스를 포함하여 원하는 위치에 stdin, stdout 및 stderr의 기본 추가를 재정의할 수 있습니다. 이를 위해서는 쉘에 강력한 유틸리티, 입력/출력 리디렉션 및 명령 파이프가 있어야 합니다.
I/O 리디렉션을 사용하면 입력/출력을 원하는 파일 암호 해독으로 리디렉션할 수 있습니다. 예를 들면 다음과 같습니다.
echo "contents of a file" > somefile.txt
이는 echo 명령의 stdout을 리디렉션하여 작성됩니다 contents of a file
. 입력 리디렉션은 동일한 방식으로 작동합니다.somefile.txt
somefile.txt
cat < somefile.txt
cats stdin을 화면으로 리디렉션하여 파일의 내용을 읽습니다. somefile.txt
(이것은 조작된 예입니다. 대부분의 사람들은 cat somefile.txt
쉘이 이를 수행하도록 하는 대신 cat 자체가 somefile.txt를 읽도록 합니다.)
다음은 명령 파이프로, 한 프로그램의 표준 출력을 다른 프로그램의 표준 입력에 연결할 수 있습니다. 이는 원하는 대로 들립니다. echo 출력을 스크립트의 stdin으로 보냅니다.
echo ".open Simulation" | sh script2.sh
이제 이것은 간단한 입력에 적합하지만 몇 줄 이상이면 여기에 문서화된 더 쉬운 방법이 있습니다. 예를 들어 여러 줄을 스크립트로 파이프하려면 다음을 수행합니다.
sh script2.sh <<EOD
.open Simulation
.do something
.end Simulation
EOD
그러면 스크립트가 처리될 준비가 된 세 줄(EOD 제외)이 스크립트로 전송됩니다. 더 고급 작업이 필요한 경우 하위 명령 리디렉션을 사용할 수도 있습니다. 이를 통해 하위 쉘의 출력을 프로그램으로 리디렉션할 수 있습니다. 여기서는 각 줄 사이에 sleep 1이 있습니다.
sh script2.sh <(
echo ".open Simulation"
sleep 1
echo ".do something"
sleep 1
echo ".end Simulation"
)
이 예에서 스크립트는 .open Simulation
이를 즉시 확인하고 1초 후에 .do something
stdin이 닫힐 때까지 1초 더 기다립니다..end Simulation
답변2
노력하다
echo ".open Simulation" | sh script2.sh
스크립트에서 방금 script2.sh를 시작했고 입력을 기다리고 있기 때문입니다. 파이프를 사용하여 echo 출력을 script2.sh의 표준 입력으로 보냅니다.
죄송합니다. 기본적으로 개행 문자를 인쇄하므로 echo에 '\n'을 삽입할 필요가 없습니다. (고마워요, 셋째 형님)