저는 우분투 리눅스를 사용하고 있습니다. 이라는 프로그램이 있다고 가정해보자 myprogram
. 이 프로그램은 사용자에게 입력을 요청합니다. 특히 사용자는 프롬프트가 표시되면 정수를 입력하고 키를 눌러야 합니다 Enter. bash 스크립트를 사용하여 이 프로세스를 자동화하고 싶습니다. 특히, 예를 들어 100번 실행하고 싶습니다 ( 에서 로 가는 myprogram
카운터를 사용하여 ). 을(를) 실행할 때마다 메시지가 표시되면 현재 값을 입력하고 싶습니다 . i
1
100
myprogram
i
(그런데 myprogram
options/switches 를 사용하는데 -options
, 모두 상수이므로 bash 스크립트 내에서 지정됩니다.)
이 bash 스크립트의 불완전한 골격은 다음과 같습니다.
#!/bin/bash
for i in {1..100}
do
myprogram -options
done
i
이제 프로그램에서 메시지가 표시될 때 현재 값이 입력되도록 위 코드를 수정하고 싶습니다 . 이를 수행하는 가장 좋은 방법은 무엇입니까?
내가 사용하고 있는 소프트웨어의 웹사이트에 따르면<<EOF
줄 끝에서 사용합니다 myprogram -options
. 나는 이것이 bash에게 입력이 사용할 "파일의 끝"을 보도록 지시한다고 생각합니다. 하지만 입력을 다음 위치에 배치하고 싶지 않다면 어떻게 해야 할까요?끝파일의? <<
또는 바로 뒤에 넣으려면 어떻게 해야 합니까 <
?
그 이유는 상황이 더욱 복잡해지기 때문입니다. 예를 들어, j
비선형, 비순차적 방식으로 변경되는 정수 카운터를 도입할 수 있습니다 . 그런 다음 각 반복마다 j
to 의 현재 값을 제공하고 싶지만 에 대한 호출 과 파일 끝 사이에 myprogram
값이 변경될 수 있습니다 . j
myprogram -options
EOF
의견 있으십니까?
답변1
거의 모든 프로그램에 대해 표준 입력을 통해 프로그램을 공급하면 echo $i | myprogram -options
및 둘 다 작동해야 합니다.myprogram -options <<<$i
$i
<foo
stdin이라는 파일의 내용을 사용합니다 foo
.
<<foo
foo
표준 입력으로 만 구성된 줄과 그 사이의 텍스트를 사용합니다 . 이것은여기 문서(heredoc) Gilles가 말했듯이; EOF
실제로 파일의 끝을 의미하는 것은 아니며 단지 일반적인 heredoc 설명자일 뿐입니다(이 예에서는 대신 "foo"를 사용합니다).
<<<foo
표준 입력으로 문자열 "foo"를 사용합니다. $foo
위에서 본 것처럼 변수를 지정할 수도 있으며 , 쉘은 해당 내용을 stdin으로 사용합니다. 이것은여기 문자열, heredoc에서와 같이 전체 블록과 달리 짧은 문자열을 사용하기 때문입니다. Herestring은 bash에서는 작동하지만 /bin/sh
.
답변2
이 웹사이트에서 권장하는 구문을여기 문서. 파일 프로그램에 대한 입력은 을 포함하는 줄 바로 아래에서 시작하고 <<EOF
스크립트의 끝으로 종료되지 않고 정확히 텍스트를 포함하는 줄로 종료됩니다 EOF
(추가 공백이 없도록 주의하세요). 그런데 쉘 특수 문자가 포함되지 않은 끝 표시를 사용할 수 있습니다. 는 EOF
키워드가 아니며 단지 전통적인 문자일 뿐입니다.
#!/bin/bash
for i in {1..100}
do
myprogram -options <<EOF
$i
EOF
for j in {1..42}; do
myprogram2 <<EOF
$i
$j
EOF
done
done
답변3
위의 Kevin과 Gilles가 언급한 문서를 사용하거나 간단한 배관을 사용하면 많은 경우에 작동합니다.
더 복잡한 상황에서는 Expect나 이와 유사한 것을 살펴보는 것이 좋습니다(예: Expect::Simple CPAN 모듈은 사용하기 매우 쉬운 Perl 구현입니다). 개인적으로 저는 perl 모듈을 선호하지만(자체는 tcl이라고 예상합니다) 많은 일반적인 스크립팅 언어에 대한 구현이 있습니다. 심지어 글을 쓰는 것도 가능하다매우while 및 read를 사용하여 sh 또는 bash에서 아이디어를 기본적으로 구현합니다.
Expect 및 유사한 도구의 일반적인 아이디어는 프로그램 출력에서 지정된 문자열이나 패턴을 기다린 다음 원하는 입력을 제공하는 것입니다.
일반적인 사용 예는 문자열 "ogin:"을 "기대"(즉 대기)하여 로그인을 자동화하고 로그인 이름을 보낸 다음 "word:" 문자열을 예상하고 비밀번호를 보내는 것입니다.
myprogram의 소스가 있는 경우 마지막 옵션 중 하나는 명령줄 옵션으로 제공하려는 입력을 가져오도록 수정하는 것입니다. 이것은 사전에 좀 더 많은 작업이 될 수 있지만 Expect를 사용하여 장난을 치거나 그런 식으로 사용하도록 설계되지 않은 프로그램에 데이터를 파이프하는 것보다 훨씬 덜 악화될 것입니다.
... 그리고 패치를 myprogram 백업 업스트림에 제출하는 것을 잊지 마세요 :) 코딩한 방식이 마음에 들지 않더라도 기능 자체를 추가할 정도로 아이디어가 마음에 들 수도 있습니다. 업스트림 개발자는 요구하거나 불평하기보다는 자신의 입장에서 벗어나 기여하는 사람들을 높이 평가하는 경향이 있습니다.