web-dev-qa-db-ja.com

コマンドがユーザー入力を要求するときに、コマンドの出力をファイルにリダイレクトするにはどうすればよいですか?

ユーザーにいくつかの入力を求め、その結果を端末に出力するコマンドがあります。以下のようなコマンドを入力して、出力をファイルにリダイレクトしました。

$the_command > abc.txt

しかし、それは機能しません。問題は、プロンプトがないことです。これらのプロンプトの質問のテキストは、希望する結果ではなくabc.txtに出力されます。

7
Aaron Shen

コマンドは機能し、出力をファイルabc.txtに適切にリダイレクトします。
問題は、スクリプトが入力データをどのように要求するか、およびスクリプトをどのように実行するかです。
2つの例を見てみましょう。

# Script_1.sh                                     # 1
echo Please, enter your firstname and lastname    # 2
read FN LN                                        # 3
echo "Hi! $LN, $FN !"                             # 4

そして

# Script_2.sh                                     # 5
read -p "Enter a comment " CM                     # 6
echo  "You said $CM"                              # 7

/bin/bash Script1.sh > abc.txtを実行すると、ttyに「入力してください...」という質問は表示されません。キーボードから期待される入力を与えると、abc.txtファイルに2行目と4行目の出力があります。

/bin/bash Script2.sh > abc.txtを実行すると、「コメントを入力してください」という質問が表示されますが、abc.txtファイルには7行目の出力のみが表示されます。

注:サブシェルでScript2、shを実行する場合

(bash Script2.sh 2>&1)> abc.txt

ttyには出力が表示されず、すべてがabc.txtファイルにあります。
で実行した場合

bash Script2.sh 2>ccc.txt 1>ddd.txt`

標準出力(行#7)はddd.txtにあり、標準エラー(行#6)はccc.txtにあります。


コマンド出力の一部のみをリダイレクトする場合は、スクリプトを変更する必要があります。
これを行う方法の1つは、興味深い出力を生成するスクリプトの部分を移動する関数を作成することです(以下を参照)。次に、スクリプトのメイン部分からこの関数を呼び出すことができます(元々は関数に移動したコードでした)。その出力のみをログファイルにリダイレクトします。

 Part_To_Redirect(){
     : # all that you want
 }

 # ... Main part of the script
 # point where it was the part that generates the output
 Part_to_Redirect "$@" > abc.txt   # this to store only that part in the file
 # Part_to_Redirect "$@" >> abc.txt  # this to append that part in the file
 # ...

あなたも役に立つと思うはずです tee それ

出力を複数のファイルにリダイレクトし、標準入力を標準出力にコピーし、引数として指定されたファイルにもコピーします。

 the_command  | tee abc.txt       # To redirect Standard output
 or 
 the_command 2>&1 | tee abc.txt   # To redirect err in out and both in the file

この場合、コマンドの通常の出力はttyにありますが、同時にログファイルabc.txtにコピーを保存します。 script2の呼び出しread -pのようにthe_command | tee abc.txtを使用する場合は、快適なはずです。

注と参照:

スクリプトの"$@"を追加すると すべての引数を渡す 関数に追加できます。

インターネット上の多くのソースからbashredirectionについてもっと読むのは面白いかもしれません。

3
Hastur

デフォルトでは、STDOUTのみがリダイレクトおよび/またはパイプされます。必要なのは、STDOUTをそのままにして、STDINを介して渡されたものをリダイレクトすることです。

編集する場合the_commandはオプションです。代わりに、質問がSTDERRに出力されることを確認し(リダイレクトに関係なく画面にダンプする必要があります)、ユーザーが入力した内容をSTDOUT経由で画面にエコーします。

3
Jarmund

通常、2つの重要な出力パイプがあります。STDOUT(通常の出力用)とSTDERR(エラーメッセージ用)です。

ここでの問題は、コマンドの「通常の」出力とプロンプトのテキストが両方ともSTDOUTに書き込まれるため、常に同じ場所に配置されることです。リダイレクトを使用する場合、プロンプトを含むSTDOUT全体が必要です。

コマンドの書き換え(Jarmundによる別の回答で提案されている)が不可能な場合、コマンドに追加のオプション/フラグ(--outputなど)があり、リダイレクトを使用する代わりに出力ファイルを指定できますか?

1
Slizzered