Linuxシステムで入力を待つスクリプトにコマンドを渡す

Linuxシステムで入力を待つスクリプトにコマンドを渡す

いくつかのコマンドが提供されるのを待つ他のスクリプトを呼び出すシェルスクリプトを実行しようとしています。 echoを使ってコマンドを渡しましたが、うまくいきません。 2番目のスクリプトは入力を待ち続けます。

スクリプト1:

#!/bin/sh
set -x
sh script2.sh
echo ".open Simulation\n"
set +x

しかし、これを行うと結果が出ません。ずっと待っています。

出力:

./script1.sh
+ sh script2
<Nothing appears here>

ベストアンサー1

デフォルトでは、Linuxシステムのすべてのプロセスには1つの入力(stdin)と2つの出力(stdout、stderr)があります。ターミナルはキーボードから入力を受け取り、実行中のシェルのstdinに送信し、プロセスからstdoutとstderrを取得して画面に印刷します。

シェル(ターミナル)でコマンドを実行すると、独自の標準入力がプロセスの標準入力に接続されるため、入力したすべてのキーがコマンドに送信されます。また、stdoutとstderrをそれ自体に接続します(ターミナルはそれを画面に印刷します)。スクリプトでコマンドを実行しても同じことが起こります。 stdin、stdout、stderr は親プロセスのコマンドに接続され、最終的に端末に伝播されます。

また、スクリプトのコマンドはデフォルトでブロックされます。実行中のコマンドが完了したときにのみ、次のコマンドを実行します。

これを考慮してスクリプトを見てみましょう(2つの関心のある行に単純化されています)。

sh script2.sh
echo ".open Simulation\n"

それがするのは、sh(script2.sh実行)を実行し、その標準入力をスクリプトの標準入力に追加して完了するのを待つことです。 2行目は、最初のプロセスが終了するまで実行されません。

これで、シェルに入力した内容はすべてsh.open Simulation\nに送信されますscript2.shscript2.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

これにより、スクリプトを処理する準備が整った3行(EODを除く)がスクリプトに送信されます。より高度な操作が必要な場合は、サブコマンドリダイレクトを使用することもできます。これにより、サブシェルの出力をプログラムにリダイレクトできます。ここでは、各行の間にスリープ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

おすすめ記事