管道命令的单独执行状态

管道命令的单独执行状态

在一个命令中,我们有很多管道进一步重定向它们的输出,有什么方法可以知道直到一半执行或直到一定数量的管道的值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`

在第一个完整的命令中,我仍然得到没有任何错误的输出,这不是我所期望的,但我什至也不想使用两个命令。任何人都可以建议这样做或者我到底错在哪里?

更新: 为什么下面会产生今天的午夜纪元(如果给出日期来-获得较早的管道输出会发生什么 - 尽管它不能那样工作)第一个问题也仍然没有答案。

-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 $ 的值?直到执行一半或直到一定数量的管道,而不是整个命令的总体状态?

在 bash 中,有一个PIPESTATUS变量,它是一个数组,其中包含最近管道中每个命令的退出状态。

$ 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

这告诉我们lscut命令以 SIGPIPE 退出,这是预期的,因为它们的输出没有被管道中的下一个命令完全消耗。

在第一个完整的命令中,我仍然得到没有任何错误的输出,这不是我所期望的。

那是因为该date命令按预期工作,但我认为不是按您期望的方式工作。

date --date -不从标准输入读取日期;相反,它用作-日期字符串。我看不出 a lone 的含义在哪里记录,但它似乎与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它的参数不希望通过标准输入,所以你需要将其分成两部分。您已经在问题的第二部分尝试过此操作:

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 $ 的值吗? [穿过管道的中间]?不直接,不。但是,您可以将管道分成两部分,并使用临时文件来保存中间结果,或者$?随时保存该值。

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'

相关内容