0

I'm a newbie in Bash, I tried without success an if statement where I have two variable numbers a and b.

I want to output $check only if $b is greater than 1 so I tried this:

#!/bin/bash

a=$(shuf -i 1-59 -n 1);

b=$(shuf -i 1-10 -n 1);

if [ $b -gt 1 ];
then
  check="*/$a * * * * /usr/bin/php /var/www/html/requests/check.php > /dev/null"
fi

{
  echo $check
} | crontab -u ubuntu -

It doesn't work, why I get this error message? "-":0: bad day-of-month

  • Did you look at what happens when you echo $check without piping it to crontab? Compare with echo "$check" – steeldriver Feb 8 '17 at 19:29
2

There's couple problems with your script.

1. Unquoted $check variable

In this part,

{
  echo $check
} | crontab -u ubuntu -

echo $check will expand to echo */$2 * * * * <other text here> , but bash * will perform filename expansion to the contents of the current working directory of the script on each of the glob star symbols. Thus, effectively, your crontab receives completely incorrect final string.

2. Potential null variable

Your $check variable set if and only if $b is greater than 1. Well, what happens when $b is 1 ? your variable won't be set.

if [ $b -gt 1 ];
then
     check="*/$a * * * * /usr/bin/php /var/www/html/requests/check.php > /dev/null"
fi

That also means when you echo the variable, your crontab command will receive a null string. Thus, you might want to implement another if statement there to check whether $check variable is null, like

if [ "x$check" != "x"  ];
then
    echo "$check" | crontab -u ubuntu -
fi

And of course, please please please, for the love of shell scripting , quote your string variables.


As requested in the comments, multiple entries could be output to crontab in a similar fashion:

$ check1="*/2 * * * * bash -c 'wall <<< \"check1\"'"                                                               

$ check2="*/2 * * * * bash -c 'wall <<< \"check1\"'"                                                               

$ printf "%s\n" "$check1" "$check2" | crontab -u $USER -

The idea here is that printf keeps processing arguments until all are exhausted so it's basically same as a for loop. Alternatively, one could append each desired crontab string into array, and iterate using for loop via that same array.

  • 2
    I'd assumed the OP was going for a string of the form */2 * * * * in which case the format is OK I think (every two minutes) - it's the fact that $check is unquoted in the echo to crontab that's the issue (* gets expanded to a list of files...?) – steeldriver Feb 8 '17 at 21:06
  • @steeldriver exactly what I was writing, indeed the shuffle number is between 1 and 59 – NineCattoRules Feb 8 '17 at 21:09
  • 1
    @NineCattoRules oh, not at all, I can give an example of that. I just need to know if you have a specific command that you want , or specific timing – Sergiy Kolodyazhnyy Feb 8 '17 at 23:44
  • 1
    @NineCattoRules I added a small example. I might edit it a little later with a better one. For now I have to leave. Let me know if this helps – Sergiy Kolodyazhnyy Feb 9 '17 at 0:02
  • 1
    @NineCattoRules i will it a bit later. I'm short on time right now – Sergiy Kolodyazhnyy Feb 9 '17 at 0:24
2

Make sure you full understand command substitution in BASH. I removed the pipe to crontab for testing and understanding. you can put it in place again with:

echo "$check"|crontab -u ubuntu -

but please have a look to this example here first:

#!/bin/bash

set -x

a=$(shuf -i 1-59 -n 1)
b=$(shuf -i 1-10 -n 1)

if [ $b -gt 1 ]
then
  check='*/'${a}' * * * * /usr/bin/php /var/www/html/requests/check.php > /dev/null'
fi

echo "$check"

You need to read manuals to understand how BASH works as an interpreter. There is too much to explain here. One more hint: you can do syntax check with

bash -n script-name

Teach yourself with the following examples and try to understand them and you will understand your problem above :-)

echo *
echo "*"
echo '*'
X='*';echo $X
X='*';echo "$X"
X="*";echo "$X"

That's important to understand how and why to quote.

  • thanks for bash -n script-name – NineCattoRules Feb 8 '17 at 21:08

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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