我正在运行一长串 -exec 命令,并且我想从运行开始时提取时间戳以用作后续命令的值。这可能吗?就像是:
find . -exec NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
find . -exec set NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
find . -exec export NOW=$(date +%s) {} \; -exec echo $NOW."$0" {} \;
这些似乎不起作用,但如果我只使用 $(date +%s) 而不是设置值,我会得到不一致的时间戳,因为每个后续 -exec 都会及时发生。
我想要的是为每个文件使用不同的时间戳。例如,修改某人的建议,这可能会更好地表达我的意图:
find . -exec sh -c '
NOW=$(date +%s); for f in "$@"; do echo "$NOW $f First Output"; sleep 3; echo "$NOW $f Second Output"; done
' find-sh {} +
该命令没有执行我想要的操作,但显示对第一个文件执行操作时的延迟不应更改时间戳,应输出时间戳和文件名,sleep 3,并输出该文件的相同时间戳。然后我希望它创建一个新的时间戳以与下一个文件一起使用。
答案1
-exec
仅与 一起使用一个sh -c
:
find . -exec sh -c '
NOW=$(date +%s);
echo "$NOW $1 First Output";
sleep 3;
echo "$NOW $1 Second Output";
' find-sh {} \;
作为替代方案,如果您出于某种原因想要坚持使用链式s,则可以使用临时文件,但是每当您读取该临时文件时都-exec
需要:sh -c
find . \
-exec sh -c 'date +%s > /tmp/now' \; \
-exec sh -c 'echo "$(cat /tmp/now) $1 First Output"' find-sh {} \; \
-exec sleep 3 \; \
-exec sh -c 'echo "$(cat /tmp/now) $1 Second Output"' find-sh {} \;
以下内容-exec
不起作用,因为 shell 会在运行$(..)
之前评估该部分find
:
-exec echo "$(cat /tmp/now) {} First Output" \;
附:
你可能会问,这是find-sh
从哪里来-exec sh -c '...' find-sh {}
的?这是答案。
答案2
NOW
为每个文件重新设置,即里面循环for
:
find . -exec sh -c '
for f do
NOW=$(date +%s)
echo "$NOW $f First Output"
sleep 3
echo "$NOW $f Second Output"
done
' find-sh {} +
答案3
我不太清楚你想要做什么,但如果你想要$NOW
在处理每个文件时将其值更新为当前纪元时间,你可以使用zsh
及其$EPOCHSECONDS
变量(或者$EPOCHREALTIME
如果你也想要纳秒)模块zsh/datetime
(或${(%):-%D{%s}}
不带zsh/datetime
,尽管不太清晰):
find . -exec zsh -c '
zmodload zsh/datetime
typeset -F SECONDS # make it float
for file do
start_time=$EPOCHSECONDS SECONDS=0
print -r $start_time processing $file
processing $file
end_time=$EPOCHSECONDS duration=$SECONDS
print start=$start_time end=$end_time duration=$SECONDS
done' zsh {} +
或者因为zsh
can dofind
的工作是用它的递归 glob:
#! /bin/zsh -
zmodload zsh/datetime
typeset -F SECONDS # make it float.
for file (./**/*(ND)) {
start_time=$EPOCHSECONDS SECONDS=0
print -r $start_time processing $file
processing $file
end_time=$EPOCHSECONDS duration=$SECONDS
print start=$start_time end=$end_time duration=$SECONDS
}
在bash
shell 中,您可以获得start_time=$EPOCHSECONDS
与 with等效的内容printf -v start_time '%(%s)T'
。