誰かがこのコード行で何が起こっているのかを説明できますか?

誰かがこのコード行で何が起こっているのかを説明できますか?

配列内の最小数を確認するCプログラムがあります。このプログラムを実行し、これにテストケースを提供するスクリプトがありますが、次の行の意味を理解するのが困難です。

if ! diff -u <(echo "1 2 5" | $PROGRAM) <(echo 1); then
    echo "test failed on 1 2 5"
    ((FAILURES++))
fi

diffしたがって、ファイルを比較する方法がわかり、-uタイムスタンプ、どのファイルからどの行が削除されたか、どのファイルにどの行が追加されたかなどが表示されます。しかし、エコの後ろの「<」部分で何が起こっているのか理解できないようです。私は括弧内の(echo "1 2 5" | $ PROGRAM)ここで、PROGRAMはCプログラムを実行するファイルであり、私のプログラムは最小限の正しい出力を取得しますが、まだtest failed on 1 2 5を印刷していることを知っています。 if文の表現を理解していないので、理由を理解していません。

答え1

これら2つの<(cmd1) <(cmd2)パラメータは私にとって新しいものですが、明らかにfifoという名前のパスに置き換えられて作成されcmd1ましたcmd2。 man bash(1)から:

Process Substitution

Process substitution is supported on systems that support named
pipes (FIFOs) or the /dev/fd method of naming open files.  takes
the form of <(list) or >(list).  The process list is run with its
input or output connected to a FIFO or some file /dev/fd.  The
name of this file is passed as an argument to the current command
as the result of the expansion.  If the form is used, writing to
the file will provide input for list.  If the <(list) form is
used, the file passed as an argument be read to obtain the output
of list.

このテストはfifoの名前を示しています。

echo <(date) <(sleep 1; date)
/dev/fd/63 /dev/fd/62

これにより、fifoを読み取った結果が印刷されます。

cat <(date) <(sleep 1; date)
Fri Feb 23 14:23:41 PST 2018 
Fri Feb 23 14:23:42 PST 2018

答え2

誰も質問に答えなかったので(「このコード行に何が起こっていますか?」 - 「このコード行が何を意味するのかを理解しようとしています。」):

このスクリプトはCプログラムをテストしています。それがすることは基本的に次のとおりです。

# Run the program with input “1 2 5” and write its output to a file.  Since the program
# is supposed to check the input for the minimum number, we expect it to output “1”.
echo "1 2 5" | $PROGRAM > file1
# Create a second file that contains the known correct output (minimum)
# for this input (i.e., “1”).
echo 1 > file2
# Compare the files.  diff’s standard output and standard error will go to the stdout
# and stderr of the script, which is the terminal unless the user does I/O redirection.
# The `if` will test diff’s exit status.
if diff -u file1 file2
then
        # Exit status 0 means the files are identical;
        # i.e., the program’s output is correct; i.e., the test passes.  Do nothing.
        :
else
        # Exit status non-zero (probably 1) means that the files are different;
        # i.e., the program’s output is wrong; i.e., the test fails.
        echo "test failed on 1 2 5"
        ((FAILURES++))
fi
rm file1 file2

台本はなぜこう書かれたのですか?

とても良い質問です。おそらくスクリプト作成者に尋ねて、答えを私たちに伝えることができます。

  1. ファイルを使用する必要はありません。そして彼らはファイルを使用しません。彼らはアンディ・ダルトンそしてノーベックすでに説明しました。プロセス置換を使用します。これはパイプであり、POSIXと互換性がありません。はい、プログラムの出力をキャプチャするにはファイルまたはパイプを使用する必要があります。ただし、正しい出力を保存するためにファイルやパイプは必要ありません。スクリプトを書き換えることができます。

    if [ "$(echo "1 2 5" | $PROGRAM)" != 1 ]
    then
            echo "test failed on 1 2 5"
            ((FAILURES++))
    fi
    

    それ注文するプログラムの出力をキャプチャして正しい出力をifコマンドラインに入れるには、置換を使用します。

  2. -uオプションを使用する理由は何ですかdiff
    • このオプションは、「統合コンテキストのNUM(デフォルト値3)行出力」として文書化されています。つまり、長さ100行の2つのファイルがあり、行42を除いて同じ場合は、行diff -u39〜45が表示されます(上3行、下3行は互いに異なります)。しかし、入力の1つの長さが1行であることが知られており、他の入力の長さも1行であると予想される場合、これは意味がありません。
    • -uオプションの文書化されていない機能は、diff 入力修正時間を表示することです。ただし、指定されたスクリプトでは、入力はdiff動的に生成されたパイプであるプロセス置換です。したがって、各コンテンツの修正時間は現在の時間、つまり画面上の混雑した時間になります。
  3. "$PROGRAM"特別な理由がない限り、常にシェル変数(例:)を引用する必要があります。

スクリプトでプログラムが失敗したと報告するのはなぜですか?

プログラムや少なくともその出力を見ないとわかりません。プログラム出力に\r改行文字の代わりに、またはそれに加えて空白またはキャリッジリターン()を含めることはできますか?または、改行(空白行など)を追加できますか?これを行う

エコ「1 2 5」|あなたのプログラムODタクシー
odすべてのオプションが認識されないと報告する場合は、苦情を表示するオプション(-cbまたは)を無視してください-ab。)もちろん、出力はa1と改行(\n)でなければなりません。

答え3

このコード行は次の質問に答えます。 $PROGRAM変数で定義されたプログラムは値1を返し、「1 2 5」入力に応答しますか?これはタスクを実行するための非常に混乱した方法です。次のように書くことができます。

if [ $(echo "1 2 5" | $PROGRAM) -ne 1 ] ; then

2番目の質問を最初の質問にマージしました(ただし、検索は依然として求められない他の人が簡単にできるように、各質問に対して別々の質問ページを作成する必要があります)。成功しなければならないと思うにもかかわらず、失敗の兆候を受け取る理由はおそらく(個人的な経験に照らして暗闇の中で撮影すること)によるもの$PROGRAMです1

関連情報