I am unsure what is causing this error. Script continues to run and enters the "if" statement without issues.
"./test.sh: line 79: [: too many arguments"
if [ grep -Fq "variable=00000000000" /home/me/test.txt ] ; then #line 79
........
........
else
echo "hi"
fi
[ ... ] is not part of the syntax of an if statement. [ is a command name, that requires a final argument of ] to simulate the look of syntax.
Drop them if you want to run a different command whose exit status if should check.
if grep -Fq "..." /honme/me/test.txt; then
Simply use :
if grep -Fq "variable=00000000000" /home/me/test.txt; then
[...]
or
grep -Fq "variable=00000000000" /home/me/test.txt && echo 'true'
Explanations
Every command have a return code that you can display with :
true
echo $? # return 0, true in bash
false
echo $? # return 1: false in bash
It's named boolean logic
Related
I'm trying to implement a bash script who supposed to search for a word in a Python script terminal output.
The Python script doesn't stop so "&" in the end of the command is needed but the "if [ $? == 0 ] ; then" condition doesn't work.
How it can be solved?
Thanks, Gal.
#!/bin/bash
#Check if Pixhawk is connected
PORT=/dev/ttyPixhawk
end=$((SECONDS+3))
not_exists=f
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> /dev/null &
while [ $SECONDS -lt $end ] ; do
if [ $? == 0 ] ; then
not_exists=t
fi
sleep 1
done
if [ $not_exists=t ] ; then
echo "Not Exists"
else
echo "Exists"
fi
kill $(pgrep -f '/usr/local/bin/mavproxy.py')
Bash doesn't know anything about the output of background commands. Check for yourself with [ 5444 -lt 3 ] & echo $?.
your if statement wouldn't work in any case because $? checks for the return value of the most recent previous command, which in this case is your while loop.
You have a few different options. If you're waiting for some output, and you know how long it is in the output until whatever target you're looking for occurs, you can have the python write to a file and keep checking on the file size with a timeout for failure.
You can also continue with a simple timed approach as you have where you just check the output after a few seconds and decide success or failure based on that.
You can make your python script actually end, or provide more error messages, or write only the relevant parts to file that way.
Furthermore, you really should run your script through shellcheck.net to notice more problems.
You'll need to define your goal and use case more clearly to get real help; all we can really say is "your approach will not work, but there are definitely approaches which will work"
You are checking the status of grep command output inside while loop using $?. This can be done if $? is the next command to be fired after grep and if grep is not a back-group process . But in your script, $? will return the status of while [$SECONDS -lt $end ]. You can try to re-direct the output to a temp file and check it's status
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> tmp.txt &
sleep 3
# If file exists and it's size is greater than 0, [ -s File] will return true
if [ -s tmp.txt ]; then
echo 'pattern exists'
else
echo 'pattern not exists'
fi
I have the following unix shell script, in which i have two integer
variables namely a and b.
If a is greater then or equal to b then shell script should exit with returning 0.
Else it should exit with returning 1.
My try:
Script: ConditionTest.sh
#!/bin/sh
a=10
b=20
if [ $a -ge $b ]
then
exit 0
else
exit 1
fi
....
....
....
Running Script:
$ ./ConditionTest.sh
$
Note: I am not getting any return value after executing the file.
The shell puts the exit status of the last command in the variable ?.
You could simply inspect it:
mycommand
echo $?
... or you could use it to do something else depending on its value:
mycommand && echo "ok" || echo "failed"
or alternatively, and slightly more readable:
if mycommand; then
# exit with 0
echo "ok"
else
# exit with non-zero
echo "failed"
if
Your script looks fine; you did everything right.
#!/bin/sh
a=10
b=20
if [ $a -ge $b ]
then
exit 0
else
exit 1
fi
So here's where we run it and check the return value:
$ sh test.sh
$ echo $?
1
$
10 is not greater than or equal to 20.
Another way to test it would be like this:
$ sh test.sh && echo "succeeded" || echo "failed"
failed
As noted in the comments, you should also quote your variables, always:
if [ $a -ge $b ]
Should be:
if [ "$a" -ge "$b" ]
To add to the previous answers, the key idea you should understand is that every program provides a number when exiting. That number is used as a way to report if the command has completed its operation successfully, and if not, what type of error has occurred.
Like mentioned, the exit code of the last command executed can be accessed with $?.
The reason nothing was printed by your script, is that your script returned 1, but the exit code of a command is not printed. (This is analogous to calling a function, you get a return value from the function but it's not printed)
I have the following script
var1=$(pwd)
echo $var1
if [ -e $var1 ]
then
echo present directory exists
if [ grep ^d\* | $(ls -al) ]
then
echo these are the directories in $var1
fi
else
echo failed
fi
Running this script gives the following output with errors
/home/user1/Desktop/workspace
present directory exists
ifelse.sh: 6: [: missing ]
ifelse.sh: 6: ifelse.sh: total: not found
Please explain the errors.
If possible give a resource where I can learn about about Bash script errors completely. Thanq
You have a syntax error in your grep.
You must interpolate (execute) the grep and pipe then evaluate the exit code of that command overall:
if [ $(grep ^d\* | $(ls -al)) ]
I keep getting a run time error. I'm running this in a terminal on OSX. The error is,
test.sh: line 15: while[!false]: command not found
test.sh: line 16: syntax error near unexpected token `do'
test.sh: line 16: `do'
I just can't figure where I've got wrong syntactically as I'm new to writing bash scripts.
ipa build &
TASK_PID=$!
sleep 5
kill $TASK_PID
finished=false
declare -a schemes
echo "*****************************************************************************************"
echo "| View the list of available build configs above."
echo "| Enter the name of the build you want,one at a time."
echo "| Type \"done\" to finish entering scheme names"
echo "*****************************************************************************************"
while[!${finished}]
do
read input
if[$input == "done"]
then
finished=true
else
schemes=("${schemes[#]}" $input)
echo ${schemes[0]}
fi
done
echo "Do you want a verbose build? (y/n)"
read verbose
echo "Building your selected schemes....."
ipa build -s ${schemes[0]}
true and false are not boolean keywords in bash; they are simply strings (and the names of commands; more on that in a moment). Even if you fix your syntax by supplying whitespace where necessary:
while ! [ "${finished}" ]; do
...
done
this loop will never run. Why? Whether finished has the value true or false, it is simply a non-empty string. This code will run the [ command (yes, it's a command, not syntax) and succeed because its argument is a non-empty string. The ! negates it, so that the condition for the while loop then always fails.
The most direct fix is to explicitly compare $finished to the string "true".
while [ "$finished" != "true" ]; do
...
done
I mentioned that true and false are also commands: true always succeeds, and false always fails. Usually, you do not want to do what I am about to suggest, but here it's OK because true and false are about as simple a pair of commands as you can imagine.
finished=false
while ! $finished; do
...
# At some point
finished=true
done
Here, we are letting $finished expand to the name of a command, which then executes and has its exit status negated by the !. As long as finished=false, the negated exit status is always 0 and the while loop will continue to run. Once you change the value of finished, the negated exit status will be 1 and the loop will exit.
Give space around brackets in test conditions
while [ ! ${finished} ]
&
if [ $input = "done" ]
Why not try something like this:
#!/bin/bash
list='Foo Bar Baz Quux Xyzzy QUIT'
select item in $list; do
case $item in
QUIT)
break
;;
*)
echo "You picked '$item'!"
;;
esac
done
In bash script
if [ 1 ]
then
echo "Yes"
else
echo "No"
fi
Output: Yes
It represents that '1' is treated as true value.
But in code:
word = Linux
letter = nuxi
if echo "$word" | grep -q "$letter"
then
echo "Yes"
else
echo "No"
fi
Output: No
But echo "$word" | grep -q "$letter" will return 1, so why is the result is No.
How does the keyword if test the value returned by the command after if?
The return value of a command is checked. [ 1 ] has a return value of 0 (true). Any other return value (like 1) indicates an error.
You can display the return value of the last executed command using the $? variable:
true
echo $?
# returned 0
false
echo $?
# returned 1
echo $?
# returned 0 as the last executed command is 'echo', and not 'false'
In unix land, 0 is true and 1 is false.
For your first example:
if [ 1 ]
then
echo "Yes"
else
echo "No"
fi
"If" checks the exit code of the given command for true/false (i.e. zero/non-zero).
The square brackets actually invoke the "test" command (see "man test" for more information) and give the exit code to if.
"test 1" (or indeed "test any_string") returns true (0) so "Yes" is output.
For your second example, this outputs "No" because "nuxi" isn't found in "Linux", if you change "nuxi" to "nux" (perhaps this was a typo?) and remove the spaces around the = then you will get the behaviour you expect. e.g.
word=Linux
letter=nux
if echo "$word" | grep -q "$letter"
then
echo "Yes"
else
echo "No"
fi
This is because the grep failed to find the $letter in $word, hence the exit code is 1. Whenever a process in linux return a code other than 0 then it means it failed. 0 means exited successfully. You can verify this by echo "Linux" | grep -d "nuxi"; echo $?
On the other hand in scripting world 0 means false and 1 mean true. So the grep failed to find the word and send 1 as an exit code to if, which took it as a true value.