Reputation: 23
Is it possible to use a while loop in a background job created by a script? This works perfectly fine when I manually run this in command prompt.
Called Script Content (test.sh)
#!/bin/bash
> switch
echo 'Running' >> switch
check=$(more switch)
echo $check
while [ $check = 'Running' ]
do
sleep 5s
check=$(more switch)
echo $check
done
Calling Script Content (start.sh)
#!/bin/bash
$PWD/test.sh &
I am getting an error:
-bash: [: too many arguments
when the calling script runs. The called script run manually without issue. Is while loop not allow in a script created background job?
Upvotes: 2
Views: 480
Reputation: 107879
echo 'Running' >> swtich check=$(more switch)
You write to a file called swtich
and then read to a file called switch
. That file doesn't exist, so the variable check
ends up empty.
Incidentally, why call more
? That's only useful to view a file page by page. If you're piping the output, cat
is equivalent. If more
doesn't have a controlling terminal, which happens when you call test.sh
in the background, more
prints an extra line containing the file name, so its output
So you really must use cat
and not more
. (In bash, you can also write check=$(<switch)
.)
[ $check = 'Running' ]
Since $check
is empty, the command [
receives three arguments: =
, Running
and ]
. This is not valid syntax for the [
command.
Always put double quotes around variable substitution and command substitution: "$check"
, "$(somecommand)"
. If a $
substitution occurs outside quotes, the result is split into separate words (0 words in your case, since the result was empty) and the words are interpreted as file glob patterns. This is almost never desirable, so always use double quotes unless you really have a list of glob patterns.
check=$(cat switch)
is actually safe, because in an assignment, a single word is expected on the right-hand side, so word splitting doesn't happen. However, you might as well write check="$(cat switch)"
for clarity. Also, the quotes are required if you write export check="$(cat switch)"
.
So we have:
#!/bin/bash
echo 'Running' >> switch
check=$(cat switch)
while [ "$check" = 'Running' ]
do
sleep 5s
check=$(cat switch)
done
In bash (but not in sh), you can write [[ $check = Running ]]
instead of [ $check = Running ]
. That's because [[ … ]]
is special syntax, unlike [
which is a built-in command with no special parsing. However, you would need double quotes if the variable was on the right-hand side of the =
operator, because the right-hand side of =
inside [[ … ]]
is a pattern. Rather than learn such complicated rules, just use double quotes all the time and you'll be fine.
Upvotes: 2
Reputation: 33387
The problem is basically that you haven't quoted the argument in the test command. It should be
while [ "$check" = 'Running' ]
with double quotes around the variable. If you do that, you will notice that you have a typo in the first line. Instead of
echo 'Running' >> swtich
it should be
echo 'Running' >> switch
Then it should work as expected
As a side note, it is better not to use the more command to read the contents of the file, since it is intended for humans, but instead to just do:
check=$(<switch)
Upvotes: 0
Reputation: 11375
Try this:
nohup yourprogram >>/dev/null 2>>/dev/null &
Your program content should not have & or nohup
Upvotes: 0