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

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

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

$the_command > abc.txt

しかし、それは機能しません。問題はプロンプトがないことであり、プロンプトの質問のテキストが abc.txt に出力され、必要な結果が得られません。

答え1

コマンドは機能し、出力をファイルに適切にリダイレクトします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.txttty に「入力してください...」という質問は表示されません。キーボードから期待どおりの入力を行うと、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 に表示されますが、同時にログ ファイルにもコピーが保存されます。script2の呼び出しのようにabc.txt使用すれば、快適に使用できるはずです。read -pthe_command | tee abc.txt

注記と参考文献:

追加"$@"するとすべての議論を通過させるスクリプトを関数に追加します。

インターネット上の多くの情報源から bashredirection についてさらに詳しく読むと興味深いかもしれません。

答え2

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

編集がthe_commandオプションである場合は、質問が に出力されるようにしSTDERR(リダイレクトに関係なく画面にダンプするはずです)、ユーザーが入力したものを 経由で画面にエコーバックするようにすることができますSTDOUT

答え3

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

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

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

関連情報