2

I am trying to check if the day is Sunday or Friday, and if the time is later than hour 20.
If so, then I want to do something; if not, I want to do something else.
I am using /bin/sh.

This gives me below error:

Too many arguments.

Why ?

   day_of_week=$(date -d $given_date +%u )
   hour_of_day=${ST_job:0:2}
   if [ [ $day_of_week -eq 7 ] || [ [ $day_of_week -eq 5 ] && [ $hour_of_day -gt 20 ] ] ] ; then
       something
   else
       something else
   fi

Thanks

2

3 Answers 3

3

You might think "[" is just a grouping, and that you could have different arbitrary nestings.

It isn't.

"[" is an alias for the shell "test" command ... and you need to match them correctly:

https://www.shellscript.sh/test.html

Test is used by virtually every shell script written. It may not seem that way, because test is not often called directly. test is more frequently called as [. [ is a symbolic link to test, just to make shell programs more readable. It is also normally a shell builtin (which means that the shell itself will interpret [ as meaning test, even if your Unix environment is set up differently):

$ type [
[ is a shell builtin
$ which [
/usr/bin/[
$ ls -l /usr/bin/[
lrwxrwxrwx 1 root root 4 Mar 27 2000 /usr/bin/[ -> test
$ ls -l /usr/bin/test
-rwxr-xr-x 1 root root 35368 Mar 27  2000 /usr/bin/test

Look here for more details (and some helpful examples):

Advanced Bash-Scripting Guide: 7.4. Nested if/then Condition Tests

Sign up to request clarification or add additional context in comments.

1 Comment

I believe shellscript.sh is suffering a bit from "all the world's a Linux system". Whether [ is a symlink is not so clear. Some (many? most?) Unixen chose to make it a hard link to test. At least FreeBSD does.
2

The test command (aka [) does not nest. Anything after the first [ is treated as an expression and the one you used is syntactically invalid.

Personally, I find complex tests with [ so ugly, they make me want to find other, more readable and flexible solutions. The case/in syntax can be used here:

case $day_of_week/$hour_of_day in
  (7/* | 5/2[123]) echo "something";;
  (*)              echo "something else";;
esac

5 Comments

It doesn't answer the question as to why the OP's getting the error ... but it's an excellent solution :) PS: were you born on the 12th of January, 1992,or 1997?
@FoggyDay See my profile :-) Thanks for picking up a fault in my answer. I shall address it shortly.
@Jens How does it work if i have to use multiple or ( || ) condition and a and ( && ) condition ? How do i know my && will get clubbed with which || ? One to the left of it or with right of it or all ?
@Invictus As you can see, you can "or" multiple conditions for the strings using |. The "and" condition for day and hour is made by concatenating with a delimiter character (here /) and the appropriate pattern to match: 5/21 only matches when the day is 5 AND the hour is 21. You get the idea?
@Invictus If you ask about the shell list operators || and &&, they both have equal precedence and the evaluation is stopped as soon as the result is determined. This is called short-circuiting. true || false does not evaluate the false part. false && true does not evaluate the true part. If you insist on using [ then it is probably more readable to use -o for or and -a for and, along with ( for grouping.
-1

Try adjusting your code as following..

day_of_week=$(date -d $given_date +%u )
hour_of_day=${ST_job:0:2}
if [[ $day_of_week -eq 7  ||  $day_of_week -eq 5  &&  $hour_of_day -gt 20 ]] ; 
then
  echo  "something"
else
  echo "something else"
fi

When putting the arguments in the if condition you don't need to have square brackets again to separate the arguments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.