私はコマンドのリストを取得し、1つずつ実行して出力を表示できるスクリプトが必要です。問題は、特定のコマンドが新しいシェルを起動して後続のコマンドに影響を与えることです。というファイルにはいくつかのサンプル入力がありますcommands
。
echo "current shell: $0"
ksh
echo "current shell: $0"
exit
echo "current shell: $0"
test3.sh
名前付きパイプを使用してコマンドを送信するスクリプトがあります。
#! /usr/bin/env bash
# Create a pipe for processing commands
rm -f shell-pipe
mkfifo shell-pipe
# Set up a bash shell to process the commands sent to the pipe
(tail -f shell-pipe | bash) &
while IFS='' read -r command; do
echo ">>> sending command: $command"
echo $command > shell-pipe
sleep 1
done
# Close the pipe and delete it
fuser -TERM -k shell-pipe > /dev/null
rm shell-pipe
効果がある
$ ./test3.sh < commands
>>> sending command: echo "current shell: $0"
current shell: bash
>>> sending command: ksh
>>> sending command: echo "current shell: $0"
current shell: ksh
>>> sending command: exit
>>> sending command: echo "current shell: $0"
current shell: bash
しかし、コマンドが完了するのにどれくらいの時間がかかるのかは事前にわかりません。コマンドが完了したことを確認する方法が必要です。。だから、応答のために別々の名前付きパイプを設定しました。
$ cat test4.sh
#! /usr/bin/env bash
# Create a pipe for processing commands
rm -f shell-pipe response-pipe
mkfifo shell-pipe response-pipe
# Set up a bash shell to process the commands sent to the pipe
(tail -f shell-pipe | bash > response-pipe) &
while IFS='' read -r command; do
echo ">>> sending command: $command"
echo $command > shell-pipe
echo "...waiting for response..."
echo "<<< reponse: " $(cat response-pipe)
done
# Close the pipe and delete it
fuser -TERM -k shell-pipe > /dev/null
rm shell-pipe response-pipe
残念ながら、これは中断され、最終的にCtrl-cを使用する必要があります。
$ ./test4.sh < commands
>>> sending command: echo "current shell: $0"
...waiting for response...
^C
コマンドを試しましたが、exec
役に立ちませんでした。この例ではPythonを使用していbash
ますが、他のシェルであるPythonまたはHaskellを使用することもできます。
答え1
これを(または一度に1行ずつ入力を処理するシェル)として実行すると、bash < file
次のように動作します。read
$ cat file
echo "current shell: $0"
ksh
echo "current shell: $0"
exit
echo "current shell: $0"
$ bash < file
current shell: bash
current shell: ksh
current shell: bash
$ zsh < file
current shell: zsh
current shell: ksh
current shell: zsh
dash
(読み取り内容を解釈する前にファイル全体(最小8KiBチャンク)を読み取る操作は機能しないため、(bashまたはksh検索を実行せずに)kshは開始時に読み取ることができません。
呼び出されたコマンド(シェルだけでなく)が標準入力を読み取ると、スクリプトも読み込みます。
export VAR=before
echo "$0 $VAR"
ksh
echo "$0 $VAR"
read VAR
after
echo "$0 $VAR"
exit
echo "$0 $VAR"
あなたは得るでしょう:
bash before
ksh before
ksh after
bash before