Ubuntu Linuxを実行しています。 myprogram
というプログラムがあるとします。このプログラムは、ユーザーに入力を求めます。具体的には、ユーザーはプロンプトが表示されたら整数を入力して、 Enter。 bashスクリプトを使用してこのプロセスを自動化したいと思います。特に、myprogram
を、たとえば100回実行したいと思います(1
から100
へのカウンターi
を使用)。 myprogram
を実行するたびに、プロンプトが表示されたらi
の現在の値を入力します。
(ちなみに、myprogram
はオプション/スイッチ-options
を受け取ります。これらはすべて定数であり、bashスクリプト内で指定されます。)
このbashスクリプトの不完全なスケルトンは次のようになります。
#!/bin/bash
for i in {1..100}
do
myprogram -options
done
次に、上記のコードを変更して、プログラムから要求されたときにi
の現在の値が入力されるようにします。これを行う最良の方法は何ですか?
私が使用しているソフトウェアのWebサイトが示唆しています<<EOF
行の終わりにmyprogram -options
を使用しています。これは、入力が使用するために「ファイルの終わり」を調べるようにbashに指示すると思います。しかし、入力をファイルのendに配置したくない場合はどうなりますか? <<
または<
の直後に配置したい場合はどうなりますか?
その理由は、物事がより複雑になるからです。たとえば、整数カウンタj
を導入すると、非線形で非順次的な方法で変化します。次に、各反復でj
の現在の値をmyprogram
に供給したいと思いますが、j
の値は、myprogram -options
の呼び出しとファイルの終わりEOF
。
何か提案はありますか?
ほとんどすべてのプログラムで、echo $i | myprogram -options
とmyprogram -options <<<$i
の両方が機能するはずです。これには、標準入力を介してプログラム$i
に入力することで機能します。
<foo
は、foo
という名前のファイルの内容をstdinとして使用します。
<<foo
は、それとfoo
のみで構成される行の間のテキストを標準入力として使用します。 Gillesが言ったように、これはhereドキュメント(heredoc)です。 EOF
は実際にはファイルの終わりを意味するのではなく、単なる一般的なヒアドキュメントの区切り文字です(この例では、代わりに「foo」を使用しています)。
<<<foo
は、文字列 "foo"を標準入力として使用します。変数$foo
を指定することもできます。上で示したように、シェルはその内容をstdinとして使用します。ヒアドキュメントのようにブロック全体とは対照的に短い文字列を使用するため、これはherestringと呼ばれます。ヒア文字列はbashでは機能しますが、/bin/sh
では機能しません。
このWebサイトが推奨する構文は hereドキュメント と呼ばれます。ファイルプログラムへの入力は、<<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
上記のKevinとGillesの両方が言及しているドキュメント、または単純な配管が多くの場合機能します。
より複雑な状況では、Expectまたは同様のものを検討することをお勧めします(たとえば、Expect :: Simple CPANモジュールは、Perlの実装を使用するのが非常に簡単です)。個人的には、Perlモジュール(Expect自体はtcl)を好みますが、多くの一般的なスクリプト言語の実装があります。 whileとreadを使用して、アイデアのveryプリミティブ実装をshまたはbashで作成することも可能です。
Expectおよび同様のツールの一般的なアイデアは、プログラムの出力で指定された文字列またはパターンを待ってから、必要な入力を提供することです。
一般的な使用例は、文字列「ogin:」を「期待」する(つまり待機する)ことでログインを自動化し、ログイン名を送信してから、文字列「Word:」を期待してパスワードを送信することです。
Myprogramのソースがある場合、最後のオプションの1つは、変更したいコマンドをコマンドラインオプションとして受け取ることです。これは前もって少し作業量が増えるかもしれませんが、Expectをいじったり、そのように使用するように設計されていないプログラムにデータをパイプしたりするよりも、ずっと悪化しません。
...そして、アップストリームにmyprogramにパッチを送信することを忘れないでください:)彼らがあなたがそれをコーディングした方法が気に入らなくても、機能を自分で追加するのに十分なアイデアを好むかもしれません。上流の開発者は、要求や不満を言うよりも、お尻を降りて貢献する人々を高く評価する傾向があります。