Bash - 可选地在命令替换中设置环境变量

Bash - optionally set env var in command substitution

以下工作没有问题:

timestamp=$(TZ=America/New_York date)
echo $timestamp

这(如果保存在名为 /tmp/foo 的文件中)会导致:

$ /tmp/foo
Thu Dec 23 21:03:41 EST 2021

此代码也有效:

timezone=

timestamp=$(TZ=$timezone date)
echo "$timestamp"

嗯……有点;当 运行 带有参数时,它会做我想要的:

$ date
Thu Dec 23 21:05:03 EST 2021

$ /tmp/foo Asia/Calcutta
Fri Dec 24 07:35:11 IST 2021

但是当 运行 没有参数时,它将恢复为 UTC(因为 TZ 设置为空值,这与 TZ 根本未设置时执行不同的代码):

$ /tmp/foo Asia/Calcutta
Fri Dec 24 07:37:16 IST 2021

$ /tmp/foo
Fri Dec 24 02:07:19 UTC 2021

所以我应该只在提供的子 shell 中设置 TZ 变量,对吗?这不起作用:

timezone=
if [[ -n "$timezone" ]]; then
    tzstring="TZ=$timezone"
fi

timestamp=$($tzstring date)
echo "$timestamp"

不争论也行:

$ /tmp/foo
Thu Dec 23 21:09:07 EST 2021

但是有一个参数,它失败了:

$ /tmp/foo Asia/Calcutta
/tmp/foo: line 12: TZ=Asia/Calcutta: No such file or directory

它正在尝试执行第一个元素。

我可以使用这段代码让它完全按照我的意愿工作:

if [[ -n "$timezone" ]]; then
   timestamp=$(TZ=$timezone date)
else
   timestamp=$(date)
fi

这导致:

$ /tmp/foo
Thu Dec 23 21:13:19 EST 2021

$ /tmp/foo Asia/Calcutta
Fri Dec 24 07:43:21 IST 2021

但肯定有更好的方法可以减少代码重复。我宁愿不使用函数,但如果我没有那个规定,我也许可以制作 TZ local。我能想到的做所有我想做的事情的唯一方法是使用 eval,我不太愿意这样做(而且我不确定我是否知道如何去做)。

只有在有参数的情况下才设置时区。您可以通过在您正在捕获其输出的子 shell 中导出 $TZ 来做到这一点。

timestamp=$(if [ "" ] ; then export TZ= ; fi; date)
echo $timestamp