[英]Date command as a variable in a bash script. Needs to be invoked each time instead of during variable declaration
I have a bash script and at certain points I am using echo to put some messages in a log file.我有一个 bash 脚本,在某些时候我使用 echo 将一些消息放入日志文件中。 The problem that I have is related to the DATE variable which will be static throughout the entire execution of the script.我遇到的问题与 DATE 变量有关,该变量在整个脚本执行过程中为 static。
I have this basic script below to illustrate the problem:我在下面有这个基本脚本来说明问题:
#!/bin/bash
DATE=`date +"%Y-%m-%dT%H:%M:%S%:z"`
echo "script started at $DATE"
echo "doing something"
sleep 2
echo "script finished at $DATE"
If I execute this script, the output of the $DATE variable is the same in both lines.如果我执行此脚本,两行中 $DATE 变量的 output 是相同的。 Is there some bash magic that could nicely resolve this without having to replace $DATE with the command itself on each line?是否有一些 bash 魔术可以很好地解决这个问题,而不必在每一行上用命令本身替换 $DATE?
Thanks in advance提前致谢
With bash version 4.3+, you can use the builtin printf
to format datetimes.使用 bash 版本 4.3+,您可以使用内置的printf
来格式化日期时间。 -1
below is a magic value that means "now".下面的-1
是一个神奇的值,意思是“现在”。
#!/bin/bash
datefmt='%Y-%m-%dT%H:%M:%S%z'
printf "script started at %($datefmt)T\n" -1
echo "doing something"
sleep 2
printf "script finished at %($datefmt)T\n" -1
bash didn't recognize %:z
for me. bash 没有为我识别%:z
。
Newer versions of the bash/printf
builtin have support for generating datetime stamps without the need to spawn a subprocess to call date
:较新版本的bash/printf
内置支持生成日期时间戳,而无需生成子进程来调用date
:
$ builtin printf --help
...snip...
Options:
-v var assign the output to shell variable VAR rather than
display it on the standard output
...snip...
In addition to the standard format specifications described in printf(1),
printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
... snip ...
Instead of spawning a subprocess to call date
, eg:而不是产生一个子进程来调用date
,例如:
logdt=`date +"%Y-%m-%dT%H:%M:%S:%z"`
The same can be accomplished via printf -v
by wrapping the desired format in %(...)T
, eg:同样可以通过printf -v
通过将所需格式包装在%(...)T
中来完成,例如:
printf -v logdt '%(%Y-%m-%dT%H:%M:%S:%z)T'
NOTE: assuming %:z
should be :%z
注意:假设%:z
应该是:%z
Assuming you'll be tagging a lot of lines with datetime stamps then the savings from eliminating the subproces date
calls could be huge.假设您将用日期时间戳标记很多行,那么消除子过程date
调用所节省的费用可能是巨大的。
Running a test of 1000 datetime stamp generations:运行 1000 代日期时间戳的测试:
$ time for ((i=1;i<=1000;i++)); do { printf -v logdt '%(...)T' | logdate=$(date ...) }; done
Timings for printf -v logdt '%(...)T'
: printf -v logdt '%(...)T'
计时:
real 0m0.182s # ~130 times faster than $(date ...)
user 0m0.171s
sys 0m0.000s
Timings for logdt=$(date...)
: logdt=$(date...)
的时间:
real 0m24.443s # ~130 times slower than printf -v
user 0m5.533s
sys 0m16.724s
This can help you:这可以帮助您:
#!/bin/bash
echo "script started at $(date +'%Y-%m-%dT%H:%M:%S%:z')"
echo "doing something"
sleep 2
echo "script finished at $(date +'%Y-%m-%dT%H:%M:%S%:z')"
You might want to create an alias if calling the full command looks clumsy to you.如果调用完整命令对您来说看起来很笨拙,您可能想要创建一个别名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.