Linux 시스템에서 입력을 기다리는 스크립트에 명령 전달

Linux 시스템에서 입력을 기다리는 스크립트에 명령 전달

일부 명령이 제공되기를 기다리는 다른 스크립트를 호출하는 쉘 스크립트를 실행하려고 합니다. 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.txtsomefile.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 somethingstdin이 닫힐 때까지 1초 더 기다립니다..end Simulation

답변2

노력하다

echo ".open Simulation" | sh script2.sh

스크립트에서 방금 script2.sh를 시작했고 입력을 기다리고 있기 때문입니다. 파이프를 사용하여 echo 출력을 script2.sh의 표준 입력으로 보냅니다.

죄송합니다. 기본적으로 개행 문자를 인쇄하므로 echo에 '\n'을 삽입할 필요가 없습니다. (고마워요, 셋째 형님)

관련 정보