16

I am using the below script to move two days back when script runs at starting two days of the year and also check first and second days of every month and move two days back.

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

But my bad am getting the below error message

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found
  • 1
    The given answers are correct; you need whitespace after [. Additionally, look into the elif statement; it will help you clean things up. Also, the semicolons after the if statements are not necessary, but are also not incorrect, just strange. – Shawn J. Goff Jun 4 '14 at 14:14
  • @ShawnJ.Goff They are necessary if you concatenate the next line (if [ ... ]; then), so not that unusual. – goldilocks Jun 4 '14 at 14:18
  • @goldilocks, yes, that is my preferred style. The reason it's unusual is because he is not doing that. – Shawn J. Goff Jun 4 '14 at 14:56
27

[ is neither a metacharacter nor a control operator (not even a reserved word; same for ]) thus it needs whitespace around it. Otherwise the shell "sees" the command [01=01] instead of the command [ with the separate parameters 01, =, 01, and ]. Each operator and operand needs to be a separate argument to the [ command, so whitespace is necessary around the operators as well.

if [ "$month" = "01" ]

[$month="01"] is a wildcard pattern matching any of the characters in $month or "01. If it doesn't match anything, it's left alone.

If there is a semicolon after the closing bracket, you don't need a space before it, because the semicolon is always part of a separate token.

if [ "$month" = "01" ]; then

The same goes for bash's (and ksh's and zsh's) double bracket syntax.

More than one condition

There are two ways to combine conditions:

  1. within [

  2. with separate [ commands combined with && or ||

Grouping with brackets is probably easier within [.

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

The first one should be avoided as it's unreliable (try for instance with month='!'). Problems with strange variable content can be avoided by using the safe string (if there is one) first; or by using [[/]] instead of [/]:

if [ "01" = "$month" -a "01" = "$day" ]
  • How we can match the two condition in if , like month value == day value if [$month="01"] && [$day="01"]; am expecting 01 && 01 true then print below conditions or move to else statement – Kumar1 Jun 4 '14 at 14:14
  • @AshokSanganahalli I have extended my answer. – Hauke Laging Jun 4 '14 at 14:21
  • 1
    [ when -a/-o are not used is always reliable with POSIX compliant shells. There's no advantage whatsoever in using -a/-o over &&/||. I would definitely discourage its use. Note that [[ is not POSIX. – Stéphane Chazelas Jun 4 '14 at 15:09
4

Another way to write it:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac
  • 1
    +1 for case statement. If you have more than one elif, you should probably be using case. – HalosGhost Jun 5 '14 at 2:27
-1

So, this is your answer:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

So you must put "space" between square bracket and variable/value.

  • no i GUESS, because as i asked script to move two days back when script runs at starting two days of the year and also check first and second days of every month and move two days back means here if [$month="01"] && [$day="01"] we suppose to match month "01" and first day "01" true , move to then or move to else condition – Kumar1 Jun 4 '14 at 14:07
  • 1
    @AshokSanganahalli: I don't know how is this related, but your IF condition is not working because you don't have "blank space" between square brackets and value – Neven Jun 4 '14 at 14:12
  • @AshokSanganahalli It is usually not a good idea for people at your skill level to dispute corrections from people with obviously better understanding without at least giving the hint a try. If your guesses were right then you would not have to ask here, would you? – Hauke Laging Jun 4 '14 at 14:24
  • 4
    -1 for non-quoted variables and usage of == instead of standard =. – Stéphane Chazelas Jun 4 '14 at 14:52
  • 2
    The question is not tagged bash. The equality comparison operator in the standard [ aka test command is =. [ if for tests, it doesn't do any assignment so there's no need to disambiguate. Some [ implementations support == as an extension over the standard, but not all. The Bourne shell's, ash's, posh's [s or the /bin/[ of some systems for instance don't. == was added by ksh, I suppose for consistency with the same operator in its new (( ... )) construct (which has both = and ==, but it no standard) – Stéphane Chazelas Jun 7 '14 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.