0

So, I am new to scripting and I am trying to figure it out what this does. Can you help?

if [ "@$1@" = "@@" ]; then
strDate ='date +%Y%m%d' 
else
strDate=$1
fi
Chris Davies
  • 116,213
  • 16
  • 160
  • 287
Mihaela
  • 1
  • 3
  • 1
    This is an overly elaborate way to test for an empty variable. More concise would be if [ -z "$1" ]; then ...; fi. I suggest reading the manual page for dash or a similar simple shell (purely because Bash manual might be too long and intimidating for newcomers). – Vilinkameni Aug 12 '22 at 08:25
  • it is a best practice to test on -z and the @ are useless here ; might be used as text separator but really useless in the parameter test context – francois P Aug 12 '22 at 08:27
  • @francoisP the @ wrapper approach is a throwback to the early style of configure scripts that couldn't guarantee what version of a bourne shell they were using – Chris Davies Aug 12 '22 at 08:38
  • Very similar, but using a single x in place of two @: bash script [ x$1 = x ] – Kusalananda Aug 12 '22 at 09:20

1 Answers1

6

The overall construct is an if {condition} then {do something} else {do something different}. The shell itself requires a little more syntax to help it parse the construct though, such as fi to denote the end of the end of the construct, and [ ... ] to execute the condition test.)

  • The condition test [ "@$1@" = "@@" ] compares two strings for equality ([ X = Y ]):

    • The first string is @ followed by the first argument to the program or function ($1) followed by another @. So if you had passed red as the first argument then the string would be @red@. On the other hand if you had passed nothing at all then the string would simply be @@
    • The second string is the literal @@

    What's going on here is that the condition test is checking to see if $1 (the first argument the program or function) is empty. This would be better written as [ -z "$1" ].

  • The next line strDate ='date +%Y%m%d' is syntactically wrong and cannot run. Perhaps you meant strDate=`date +%Y%m%d` , which these days would be better written as strDate=$(date +%Y%m%d). (In either case, there must be no space between the variable name, the =, and its assignment value. The single quotes that you show ('...') mean that the assignment would have been of the literal 12 characters in the string date +%Y%m%d, but the intention is clearly to use backticks to assign the output from having run that command.) This line would assign the variable $strDate to today's date in the format YYYYMMDD (for example 12 August 2022 would be 20220812).

  • The final assignment strDate=$1 assigns the variable $strDate the value supplied as the first argument to the program or function. There is no further validation on the value in the code that you present.

I should point out that you can identify many syntax and construct errors by passing your code through shellcheck (also at https://shellcheck.net/).

Here is the corrected code, with indentation to improve readability:

if [ -z "$1" ]
then
    strDate=$(date +'%Y%m%d')
else
    strDate=$1
fi

You'll see the shell's syntax clearly implementing the description I have given in the first paragraph. Some people prefer to have the then on the same line as the if, i.e. if [ -z "$1" ]; then, as you did in your original code; it doesn't really matter either way as long as you're consistent. However, almost all experienced coders use indentation to show code structure, and this would be an approach well worth using in your own code as it helps reduce an entire class of bugs.

Finally, the entire block could be replaced in a more idiomatic way with a single conditional assignment:

strDate=${1:-$(date +'%Y%m%d')}
Chris Davies
  • 116,213
  • 16
  • 160
  • 287