获取并设置日期及延时
延时可以用来在程序执行过程中等待一段时间(比如1秒),或是每隔几秒钟(或是几个月) 监督某项任务。与时间和日期打交道需要理解如何描述并处理这两者
日期能够以多种格式呈现。在系统内部,日期被存储成一个整数,其取值为自1970年1月1
日0时0分0秒1起所流逝的秒数。这种计时方式称为纪元时或Unix时间。 可以在命令行中设置系统日期。
(1) 读取日期:
$ date
Thu May 20 23:09:04 IST 2010
(2) 打印纪元时:
$ date +%s
1290047248
data命令可以将很多不同格式的日期转换成纪元时。
将日期转换成纪元时:
$ date --date "Wed mar 15 08:09:16 EDT 2017" +%s 1489579718
选项–date指定了作为输入的日期。我们可以使用任意的日期格式化选项来打印输出。 data命令可以根据指定的日期找出这一天是星期几:
$ date --date "Jan 20 2001" +%A
Saturday
(3) 用带有前缀+的格式化字符串作为date命令的参数,可以按照你的选择打印出相应格式
$ date "+%d %B %Y"
20 May 2010
(4) 设置日期和时间:
# date -s "格式化的日期字符串"
例如:
# date -s "21 June 2009 11:01:22"
如果系统已经联网,可以使用ntpdate来设置日期和时间:
/usr/sbin/ntpdate -s time-b.nist.gov
(5) 要优化代码,首先得先进行测量。date命令可以用于计算一组命令所花费的执行时间:
#!/bin/bash
#文件名: time_take.sh
start=$(date +%s)
commands;
statements;
end=$(date +%s)
difference=$(( end - start))
echo Time taken to execute commands is $difference seconds.
date命令的最小精度是秒。对命令计时的另一种更好的方式是使用time命令: time commandOrScriptName.
编写以循环方式运行的监控脚本时,设置时间间隔是必不可少的。
sleep命令可以延迟脚本执行一段时间(以秒为单位)。下面的脚本使用tput和sleep从0开 始计时到40秒:
#!/bin/bash #文件名: sleep.sh echo Count:
tput sc
# 循环40秒
for count in `seq 0 40` do
tput rc
tput ed
echo -n $count
sleep 1
done
在上面的例子中,变量依次使用了由seq命令生成的一系列数字。我们用tput sc存储光标 位置。在每次循环中,通过tput rc恢复之前存储的光标位置,在终端中打印出新的count值, 然后使用tputs ed清除从当前光标位置到行尾之间的所有内容。行被清空之后,脚本就可以显 示出新的值。sleep可以使脚本在每次循环迭代之间延迟1秒钟。
调试
(1)使用选项-x,启用shell脚本的跟踪调试功能:
$ bash -x script.sh
或者使用sh -x script
(2)使用set -x和set +x对脚本进行部分调试。例如:
#!/bin/bash #文件名: debug.sh for i in {1..6}; do
set -x
echo $i
set +x
done
echo "Script executed"
在上面的脚本中,只会打印出echo $i的调试信息,因为使用-x和+x对调试区域进行 了限制。
该脚本并没有使用上例中的seq命令,而是用{start…end}来迭代从start到end之间 的值。这个语言构件(construct)在执行速度上要比seq命令略快。
(3) 前面介绍的调试方法是Bash内建的。它们以固定的格式生成调试信息。但是在很多情况 下,我们需要使用自定义的调试信息。可以通过定义 _DEBUG环境变量来启用或禁止调试 及生成特定形式的信息。
请看下面的代码:
#!/bin/bash
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@ || :
}
for i in {1..10}
do
DEBUG echo "I is $i"
done
可以将调试功能设置为on来运行上面的脚本:
$ _DEBUG=on ./script.sh
在每一条需要打印调试信息的语句前加上DEBUG。如果没有把 _DEBUG=on传递给脚 本,那么调试信息就不会打印出来。在Bash中,命令:告诉shell不要进行任何操作。
可以在脚本中使用set builtin来启用或禁止调试打印。
set -x:在执行时显示参数和命令。
set +x:禁止调试。
set -v:当命令进行读取时显示输入。
set +v:禁止打印输入
把#!/bin/bash
改成 #!/bin/bash -xv
,这样就可以启用调试功能了。
如果每一行前面都加上+,那么就很难在默认输出中跟踪执行流程了。可以将环境变量PS4
设置为'$LINENO:'
,显示出每行的行号:
PS4='$LINENO: '
调试的输出信息可能会很长。如果使用了-x或set -x,调试输出会被发送到stderr。可以
使用下面的命令将其重定向到文件中:
sh -x testScript.sh 2> debugout.txt
Bash 4.0以及后续版本支持对调试输出使用自定义文件描述符:
exec 6> /tmp/debugout.txt
BASH_XTRACEFD=6