Home > Mobile >  Bash - optionally set env var in command substitution
Bash - optionally set env var in command substitution

Time:12-24

The following works without issue:

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

which (if saved in a file called /tmp/foo) results in:

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

This code also works:

timezone=$1

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

well...sort of; when run with an argument, it does what I want:

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

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

but when run without an argument, it reverts to UTC (because TZ becomes set to an empty value, which executes different code than if TZ is just not set at all):

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

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

So I should only set the TZ variable in the subshell if it's provided, right? This does not work:

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

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

Without an argument, it's fine:

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

but with an argument, it fails:

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

It's trying to execute that first element.

I can get it to work exactly as I'd like to with this code:

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

which results in:

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

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

but surely there's a better way to do this that reduces the code duplication. I'd rather not use a function, but if I didn't have that stipulation, I could maybe make TZ local. The only way I can think of to do all of what I want involves using eval, which I'm not really willing to do (and I'm not really sure I know how to do it even then).

CodePudding user response:

Set the timezone only when there's a parameter. You can do that by exporting $TZ inside the subshell whose output you're capturing.

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