パイプラインコマンドの個々の実行状態

パイプラインコマンドの個々の実行状態

echo $?コマンドには、出力をさらにリダイレクトするための多くのパイプがあります。コマンド全体の完全な状態ではなく、半分の実行まで、または特定の数のパイプまでのパイプ値を知る方法はありますか?たとえば、次のコマンドを実行して、次のようにエポック時間に変換するファイルのタイムスタンプを取得します。

`ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9|date --date - +%s`

しかし、手動で半分に分けたかどうかを確認したので、欲しいものを手に入れることができませんでした。

var1=`ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9`
var2=`date --date=$var1 +%s`

最初の完全なコマンドはまだエラーなしで出力されます。これは期待したものとは異なりますが、2つのコマンドを使用したくありません。誰でもこれを行う方法を提案できますか?それとも正確にどこで間違っていますか?

修正する: 次回が今日の真夜中の時代を生成する理由(-以前のパイプライン出力を得るために日付が提供された場合はどうなりますか?それはうまくいきませんが)、最初の質問には答えがありません。

-bash-3.2$ ls -lrt --time-style=+"%b %d %Y %H:%M:%S" *.dat|head -1|tr -s " "|cut -d " " -f9|date --date - +%s; date +%s
1429056000      #Midnight's
1429093077      #Current

PS:今はそんな時代ではありません。

答え1

コマンドには、出力をさらにリダイレクトするための多くのパイプがあります。 echo $の値を知る方法はありますか?完全な命令ではなく、実行の途中まで、または一定数のパイプまでの全体的な状態ですか?

PIPESTATUSBashには、最近のパイプラインの各コマンド終了ステータスを含む配列である変数があります。

$ ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /bin/*|head -1|tr -s " "| \
  cut -d " " -f 9|date --date - +%s
1429070400
$ echo ${PIPESTATUS[@]}
141 0 0 141 0
$ kill -l `expr 141 - 128`
PIPE

これは、パイプラインの次のコマンドによって出力が完全に消費されないため、予想されるSIGPIPEでコマンドが終了したことをls示します。cut

最初の完全なコマンドでは、エラーなしで出力が表示されますが、これは予期したものとは異なります。

その理由は、dateコマンドが期待どおりに機能しますが、期待どおりに機能しないためです。

date --date --日付は標準入力から読み取られず、代わりに日付文字列として使用されます。 aloneの意味がどこに記録されているかはわかりませんが、-「昼の真夜中」を意味するorと同じようです。00000

答え2

あなたはこのコマンドを持っています

ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9|date --date - +%s

問題は、dateそのパラメータを渡したくないことです。標準入力したがって、2つの部分に分ける必要があります。質問の2番目の部分ですでにこれを試しました。

var1=$(ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9)
echo "var1='$var1'"    # eg var1='11:37:39'
var2=$(date --date="$var1" +%s)
echo "var2='$var2'"    # eg var2='1429094259'

ただし、dateコマンドを実行すると時間が表示されます(11:37:39 - 1429094259)。今日(これを私の値である11:04:45 - 1429092286と比較するとvar2非常に似ていることがわかります。)

たぶんstat --format '%Y' /tmp/path/*.datもっと簡単でしょうか?


特定の質問に対するいくつかの答え

echo $の値を知る方法はありますか? [パイプ中央を渡る]?直接ではありません。ただし、パイプラインを2つの部分に分割し、一時ファイルを使用して中間結果を保存したり、$?いつでも値を保存したりできます。

cmd1 | ( cmd2; SS=$?; echo $SS >/tmp/cmd2.ss; exit $SS ) | cmd3
cmd2_status=$(</tmp/cmd2.ss)

単一のパイプラインで必要なものをどのように達成できますか?時間を評価し、次のように日付として渡すことができます。

date --date=$( cmd1 | cmd2 | cmd2 ) +%s

date --date=-深夜はなぜ作られたのですか?このdateコマンドは、無効な日付 "-"を使用して意味のある操作を実行しようとします。結局のところ、これは最終的に「今日の真夜中」と解釈されます。しかし、私はそれを信じていません。本当に真夜中が欲しいなら、私は明示的なものを選びますdate --date='00:00'

関連情報