4

In the bash script, I want to check if it is the first day of the month. Now I have:

if [ $DAY -eq 1 ]; then
        rclone copy /tmp/$MONTH-$YEAR.tar.gz.gpg /server2/archive
fi

and I get an error:

[: -eq: unary operator expected

I tried many different syntaxes from the web, but I can't succeed. Any idea what is wrong? Ubuntu Server 18.04

8
  • 5
    If you put echo $DAY before this expression you will see that $DAY is not defined at this point, so your expression comes down to [ -eq 1 ]. Which is invalid because -eq is not a unary operator.
    – Jos
    Nov 12, 2019 at 8:35
  • 1
    not defined or empty.
    – pLumo
    Nov 12, 2019 at 8:35
  • 1
    Possible duplicate of Unary operator expected
    – pLumo
    Nov 12, 2019 at 8:40
  • 1
    if ["$DAY" -eq "1" ]; then will fix the error, but not the problem ;-)
    – Rinzwind
    Nov 12, 2019 at 8:42
  • 3
    @WinEunuuchs2Unix Unlike the bash shell keyword [[, the shell builtin [ doesn't observe the " characters themselves, as quote removal is performed before the builtin is called. So you can be sure that -eq 1 and -eq "1" both work. They also both work with [[, but one must actually consult the details of how [[ works to be sure. On the other hand, the specific example command ["$DAY" -eq "1" ] doesn't work because it introduces a new typo: a missing space after [. Nov 12, 2019 at 17:15

1 Answer 1

7

Bash does not predefine DAY. As Jos says, the error message you're getting is the same as the message obtained when it is omitted altogether:

ek@Kip:~$ [ -eq 1 ]
-bash: [: -eq: unary operator expected

The command date +%d outputs the current day of the month. If you want DAY to hold that value, you can use:

DAY="$(date +%d)"

But you can also just place the command substitution in the [ command:

if [ "$(date +%d)" -eq 1 ]; then
        rclone copy "/tmp/$MONTH-$YEAR.tar.gz.gpg" /server2/archive
fi

date +%d always outputs two digits, so when it is the first day of the month it outputs 01, but that is no problem. Arithmetically, 01 is equal to 1, and you're rightly using -eq, which performs numerical comparison (unlike =, which performs textual comparison).

You will notice that I have enclosed $(date +%d) in double quotes in the [ command. This prevents globbing and word splitting.

It is a good idea always to enclose parameter expansion ("$DAY"), arithmetic expansion ("$((3 + 4))"), and command substitution ("$(date +%d)" or the less preferred form `date +%d`) in double quotes except in the fairly uncommon case that you actually want globbing and word splitting to be performed.

If you had written "$DAY" originally, instead of $DAY, then you would have gotten this error from [:

-bash: [: : integer expression expected

That error makes much more sense.

I've also enclosed your path, /tmp/$MONTH-$YEAR.tar.gz.gpg, which contains the parameter expansions $MONTH and $YEAR, in double quotes.

1
  • 1
    Tnx. When you (and other commentators) mentioned that $DAY doesn't have a value, I noticed that I accidentally delete a block where $DAY, $MONTH and $YEAR were set. Nov 12, 2019 at 17:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .