当前时间/日期作为 BASH 中的变量并使用脚本停止程序

当前时间/日期作为 BASH 中的变量并使用脚本停止程序

我正在尝试创建一个树莓派间谍凸轮错误。我正在努力做到这一点,以便为各个进程创建的新文件出现

NOW=`date '+%F_%H:%M:%S'`;

效果很好。但它需要回显来更新时间 $NOW也在/home/pi/.bashrc文件中同样的问题,不更新wo

. ~/.bashrc 

我发现在这个论坛上它有效:

#! /bin/bash

NOW=`date '+%F_%H:%M:%S'`;

filename="/home/pi/gets/$NOW.jpg"

raspistill -n -v -t 500 -o $NOW.jpg;

echo $filename;

我不明白它是如何工作的,因为它位于 raspistil 的输出之前并用引号引起来。

谢谢大家!!!

答案1

当你这样做时

NOW=`date '+%F_%H:%M:%S'`

或者,使用更现代的语法,

NOW=$( date '+%F_%H:%M:%S' )

该变量将被设置为执行该行时命令NOW的输出。date如果您在 中执行此操作~/.bashrc$NOW则将显示一个时间戳,告诉您何时启动当前交互式 shell 会话。

您还可以使用以下命令设置变量的值

printf -v NOW '%(%F_%H:%M:%S)T' -1

如果您使用的是bash4.2 或更高版本。这会将时间戳直接打印到变量中,而无需调用date.

在您显示的脚本中,变量NOW在脚本运行时被设置(这就是您想要的)。

当赋值时

filename="/home/pi/gets/$NOW.jpg"

执行后,shell 将扩展字符串中的变量。即使它用双引号括起来,它也会这样做。 单引号阻止 shell 扩展嵌入变量(这是不是在这种情况下你想要什么)。

请注意,您似乎并没有filename在调用中实际使用该变量raspistill,所以我不确定为什么要设置它的值,除非您只想在echo最后输出它。

在代码的其余部分中,您应该双引号$NOW变量扩展(和$filename)。如果不这样做,并且稍后更改定义方式NOW以使其包含空格或通配符(文件名通配模式),则使用的命令$NOW可能无法正确解析其命令行。

比较,例如

string="hello * there"

printf 'the string is "%s"\n' $string

string="hello * there"

printf 'the string is "%s"\n' "$string"

相关事情:

答案2

这个答案是一些实用的建议:

  1. 不要使用诸如:命名文件之类的字符!在使用任何非字母数字字符之前,问问自己是否可能会弄乱未来的脚本或命令行单行代码。请改用破折号或下划线,或者只是将元素压缩在一起而不使用分隔符。

  2. 由于您的问题表明您正在使用bash,因此您应该知道该 shell 的最新版本包含带有 shell 自己的printf命令的 date-spec 输出的本机版本。像这样使用它:

    printf "%(%F_%H%M%S)T"
    

    或者

    NOW=$(printf "%(%F_%H%M%S)T")
    

    甚至

    printf -v NOW "%(%F_%H%M%S)T"
    

    (这避免了分叉额外的进程)

  3. bash打印日期规范的版本具有另外的优点,即两个否则不存在的功能:“-1 表示当前时间,-2 表示调用 shell 的时间。如果未指定参数,则转换的行为就像 -1一样已经被给予了。”例如,

    printf -v THEN "%(%F_%H%M%S)T" -2
    

答案3

从 Bash 5 开始:如果自纪元 (1970-01-01 00:00:00) 以来的秒数满足您的需求,您可以从两个预定义变量中获取该时间戳:

# Seconds since epoch
echo ${EPOCHSECONDS}

# Seconds with microsecond precision since epoch
echo ${EPOCHREALTIME}

# Microseconds since epoch
echo ${EPOCHREALTIME/./}

# Miliseconds since epoch
echo $(( ${EPOCHREALTIME/./} / 1000 ))

答案4

我正在寻找一种方法,让脚本在 bash 中运行时实际更新时间,以防止对我多次更新的文件进行踩踏(是的,是的),并且仍然将其简单地“分配”给变量。很确定这在 Perl 中不是问题,但已经有一段时间了。

user1404316 的答案不适用于 RHEL 上的 bash 4.2。

以下是我在 bash 4.2 中解决此问题的方法:

#!/bin/bash
now=$(printf "%(%F_%H%M%S)T")
echo printf: ${now}
sleep 1
echo printf after 1: ${now}

# Tried backticks here too :(    
then="$(date +%s)"

# This is your now date
now() { date +%s; }

# This is how you use it    
filename="something.$(now)"

echo "now ${filename}"
filename="something.${then}"
echo "then ${filename}"
sleep 1
filename2="something.$(now)"
echo "now ${filename2}"
filename2="something.${then}"
echo "then ${filename2}"

和输出:

printf: 1969-12-31_190000
printf after 1: 1969-12-31_190000
now something.1588791459
then something.1588791459
now something.1588791460
then something.1588791459

希望这对某人有帮助:)

  1. 必须给予一些信任用户未知@askubuntu.com,因为我在尝试找到正确的解决方案时确实审查了该代码。

相关内容