EOF를 사용하지 않고 bash 스크립트에서 텍스트 입력 자동화


10

우분투 리눅스를 사용하고 있습니다. 라는 프로그램이 있다고 가정합니다 myprogram. 이 프로그램은 사용자에게 입력을 요구합니다. 특히 사용자는 프롬프트가 표시되면 정수를 입력하고를 누릅니다 Enter. bash 스크립트를 사용 하여이 프로세스를 자동화하고 싶습니다. 특히, 나는 실행하고자하는 myprogram100 번 (카운터 이용, 말 i에서 이동 1로를 100). 를 실행할 때마다 프롬프트가 표시 될 때 myprogram의 현재 값을 입력하고 싶습니다 i.

(그런데 myprogram옵션 / 스위치를 사용 -options하면 모두 bash 스크립트 내에서 일정하게 유지됩니다.)

이 bash 스크립트의 불완전한 골격은 다음과 같습니다.

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

이제 i프로그램이 프롬프트 할 때 현재 값 이 입력 되도록 위의 코드를 수정하고 싶습니다 . 가장 좋은 방법은 무엇입니까?

내가 사용하고있는 소프트웨어의 웹 사이트는 제안 사용 <<EOF의 끝에 myprogram -options선. 이것은 bash가 입력에 사용할 "파일 끝"을 보도록 지시한다고 생각합니다. 그러나 파일 끝에 입력을 배치하지 않으려면 어떻게해야 합니까? <<또는 바로 다음에 넣으려면 <어떻게합니까?

그 이유는 상황이 더 복잡해지기 때문입니다. 예를 들어, j비선형, 비 순차 방식으로 변경 되는 정수 카운터 를 도입 할 수 있습니다 . 그런 다음 각 반복에서에 현재 값을 제공 j하고 myprogram싶지만 j호출 값 myprogram -options과 파일 끝 사이의 값 이 변경 될 수 있습니다 EOF.

의견 있으십니까?


이 블로그를 확인하십시오- 대화 형 프로그램 실행
Suresh

답변:


14

거의 모든 프로그램의 경우, 모두 echo $i | myprogram -optionsmyprogram -options <<<$i프로그램 공급함으로써, 작업을해야 $i표준 입력을 통해입니다.

<foofoostdin 이라는 파일의 내용을 사용합니다 .

<<foofoo표준 입력 으로 만 구성된 줄과 그 사이의 텍스트를 사용합니다 . 이것은이다 여기에 문서의 질이 말했듯이, (히어 닥); EOF실제로 파일의 끝을 의미하는 것은 아니며 일반적인 heredoc 구분자입니다 (이 예에서는 대신 "foo"를 사용합니다).

<<<foo문자열 "foo"를 표준 입력으로 사용합니다. 변수를 지정할 수도 $foo있으며, 위에 표시된 것처럼 쉘은 내용을 stdin으로 사용합니다. 이것은 heredoc 과 같이 전체 블록과 대조적으로 짧은 문자열을 사용하므로 herestring 이라고합니다 . Herestring은 bash에서는 작동하지만에서는 작동하지 않습니다 /bin/sh.


9

이 웹 사이트에서 권장하는 구문을 여기 문서 라고합니다 . 파일 프로그램에 대한 입력은을 포함하는 행 바로 아래에서 시작 <<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

즉,이 컨텍스트에서 EOF 는 스크립트 파일의 실제 끝이 아니라 파일 끝 마커를 의미 합니다. 텍스트 "EOF"는 임의의 텍스트입니다. << 문자 바로 다음에 사용하는 모든 내용은 현재 문서의 끝을 나타냅니다. 나는 일반적으로 EOF를 사용 합니다. 예를 들어, 쉘 스크립트를 프로그래밍 방식으로 생성하는 경우 (내가 자주하는 경우) 눈에 띄지 않으며 현재 문서 안에있을 가능성이 거의 없습니다.
cas

굵게 표시된 EOF는 <underscore> <underscore> EOF <underscore> <underscore> 여야합니다
cas

이와 같은 문서를 사용하여 필자는 종종 종료 표시를보다 의미있는 것으로 변경했습니다 ( "임의로"일치하지 않을 가능성) END_OF_WHATEVER_FUNCTION. 때로는 공간 / 크기를 "저장"하려고하면 실제로 발생하는 일에 대한 모호함이 발생하기 때문에 실제로 노력의 낭비입니다.
킬러 미스트

sleep스크립트에서 읽는 명령 사이에서 어떻게 할 수 있습니까?
boltup_im_coding 1

@ unexpected62 요청하신 내용을 이해하지 못합니다. 이 사이트에서 새로운 질문을해야 할 것입니다. 충분한 맥락을 제공하십시오.
Gilles 'SO- 악의를 멈춰라'

3

위의 Kevin과 Gilles가 언급 한 문서 또는 간단한 배관은 많은 경우에 작동합니다.

더 복잡한 상황에서는 Expect 또는 이와 유사한 것을 살펴볼 수 있습니다 (예 : Expect :: Simple CPAN 모듈은 사용하기 매우 쉬운 펄 구현). 개인적으로, 나는 perl 모듈을 선호하지만 (예상 자체는 tcl 임) 많은 일반적인 스크립팅 언어에 대한 구현이 있습니다. while 및 read를 사용하여 sh 또는 bash로 아이디어 의 매우 원시적 인 구현 을 작성하는 것도 가능합니다 .

Expect 및 이와 유사한 도구의 일반적인 아이디어는 프로그램 출력에서 ​​지정된 문자열 또는 패턴을 기다렸다가 원하는 입력을 제공하는 것입니다.

일반적인 예는 문자열 "ogin :"을 "예상"(즉, 대기)하고 로그인 이름을 보낸 다음 문자열 "word :"를 예상하고 암호를 보내 로그인을 자동화하는 것입니다.

myprogram의 소스가있는 경우 마지막 옵션 중 하나는 명령 줄 옵션으로 제공하려는 입력을 취하도록 수정하는 것입니다. 이것은 조금 더 선행 작업 일지 모르지만 Expect로 엉망이되거나 데이터를 그런 식으로 사용하도록 설계되지 않은 프로그램에 파이프하는 것보다 훨씬 덜 어려울 것입니다.

... 그리고 패치를 myprogram back upstream에 제출하는 것을 잊지 마십시오. 업스트림 개발자는 요구를하거나 불만을 제기하기보다는 엉덩이에서 벗어난 사람들에게 감사하는 경향이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.