Check wget's return value - bash

I'm writing a script to download a bunch of files, and I want it to inform when a particular file doesn't exist.
r=`wget -q www.someurl.com`
if [ $r -ne 0 ]
then echo "Not there"
else echo "OK"
fi
But it gives the following error on execution:
./file: line 2: [: -ne: unary operator expected
What's wrong?

Others have correctly posted that you can use $? to get the most recent exit code:
wget_output=$(wget -q "$URL")
if [ $? -ne 0 ]; then
...
This lets you capture both the stdout and the exit code. If you don't actually care what it prints, you can just test it directly:
if wget -q "$URL"; then
...
And if you want to suppress the output:
if wget -q "$URL" > /dev/null; then
...

$r is the text output of wget (which you've captured with backticks). To access the return code, use the $? variable.

$r is empty, and therefore your condition becomes if [ -ne 0 ] and it seems as if -ne is used as a unary operator. Try this instead:
wget -q www.someurl.com
if [ $? -ne 0 ]
...
EDIT As Andrew explained before me, backticks return standard output, while $? returns the exit code of the last operation.

you could just
wget ruffingthewitness.com && echo "WE GOT IT" || echo "Failure"
-(~)----------------------------------------------------------(07:30 Tue Apr 27)
risk#DockMaster [2024] --> wget ruffingthewitness.com && echo "WE GOT IT" || echo "Failure"
--2010-04-27 07:30:56-- http://ruffingthewitness.com/
Resolving ruffingthewitness.com... 69.56.251.239
Connecting to ruffingthewitness.com|69.56.251.239|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `index.html.1'
[ <=> ] 14,252 72.7K/s in 0.2s
2010-04-27 07:30:58 (72.7 KB/s) - `index.html.1' saved [14252]
WE GOT IT
-(~)-----------------------------------------------------------------------------------------------------------(07:30 Tue Apr 27)
risk#DockMaster [2025] --> wget ruffingthewitness.biz && echo "WE GOT IT" || echo "Failure"
--2010-04-27 07:31:05-- http://ruffingthewitness.biz/
Resolving ruffingthewitness.biz... failed: Name or service not known.
wget: unable to resolve host address `ruffingthewitness.biz'
zsh: exit 1 wget ruffingthewitness.biz
Failure
-(~)-----------------------------------------------------------------------------------------------------------(07:31 Tue Apr 27)
risk#DockMaster [2026] -->

Best way to capture the result from wget and also check the call status
wget -O filename URL
if [[ $? -ne 0 ]]; then
echo "wget failed"
exit 1;
fi
This way you can check the status of wget as well as store the output data.
If call is successful use the output stored
Otherwise it will exit with the error wget failed

I been trying all the solutions without lucky.
wget executes in non-interactive way. This means that wget work in the background and you can't catch the return code with $?.
One solution it's to handle the "--server-response" property, searching http 200 status code
Example:
wget --server-response -q -o wgetOut http://www.someurl.com
sleep 5
_wgetHttpCode=`cat wgetOut | gawk '/HTTP/{ print $2 }'`
if [ "$_wgetHttpCode" != "200" ]; then
echo "[Error] `cat wgetOut`"
fi
Note: wget need some time to finish his work, for that reason I put "sleep 5". This is not the best way to do but worked ok for test the solution.

Related

Bash script for searching a specific word in terminal output

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

Shell Script won't fail in Jenkins

I have a simple shell script which I want to set up as a periodic Jenkins job rather than a cronjob for visibility and usability for less experienced users.
Here is the script:
#!/bin/bash
outputfile=/opt/jhc/streaming/check_error_output.txt
if [ "grep -sq 'Unable' $outputfile" == "0" ]; then
echo -e "ERROR MESSAGE FOUND\n"
exit 1
else
echo -e "NO ERROR MESSAGES HAVE BEEN FOUND\n"
exit 0
fi
My script will always return "NO ERROR MESSAGES HAVE BEEN FOUND" regardless of whether or not 'Unable' is in $outputfile, what am I doing wrong?
I also need my Jenkins job to class this as a success if 'Unable' isn't found (e.g. If script returns "0" then pass, everything else is fail)
Execute the grep command and check the exit status instead:
#!/bin/bash
outputfile=/opt/jhc/streaming/check_error_output.txt
grep -sq 'Unable' $outputfile
if [ "$?" == "0" ]; then
echo -e "ERROR MESSAGE FOUND\n"
exit 1
else
echo -e "NO ERROR MESSAGES HAVE BEEN FOUND\n"
exit 0
fi
You are comparing two different strings. The outcome will always be false, i.e. the else part is taken.
Also, no need to explicitly query the status code. Do it like this:
if grep -sq 'Unable' $outputfile
then
....
else
....
fi

Shell if else fi syntax error while actual syntax seems correct

So I have a shell script that contains a big if/fi block, and it was working fine until I decided to place an else case for this big if/fi block. Now I am getting this error:
/root/VVPN/Scripts/scriptPrincipal.sh: line 201: syntax error near unexpected token `else'
/root/VVPN/Scripts/scriptPrincipal.sh: line 201: `else'
I went through 8~10 stackoverflow posts where people had exactly the same error, except that all of them were simple syntax errors like a missing space after the [ of the if statement, or a : instead of a ; before the then keyword, or an else intended for an if that was already closed with a fi, etc... (you get the idea :p).
However I've checked my code for all these errors over and over and everything seems to be correct when it comes to if/else/fi syntax. I even showed the code to some colleagues and they too couldn't find the reason for this error.
Here's the code:
if [ ${CP} != "continue" ]
then
echo 'Downloading the necessary files from the server...'
# If folder F*** doesn't exist in /root/VVPN/Numbers
if [ ! -d ${N} ]
then
# Create folders F***, and F***/Results
mkdir ${N}
mkdir ${N}/Results
cd ${N}
# Get real number to factorize from server (e.g: wget server.com:8000/route/to/F1067/F1067)
ROUTE="VVPN/Numbers/${N}/${N}"
REAL_NUM_FILENAME=${N}
while true
do
wget --retry-connrefused --tries=inf -q ${SERVER}/${ROUTE} -O ${REAL_NUM_FILENAME} --continue
if [ $? -eq 0 ]; then
break
fi
sleep 1
done
# Get ECM-Program tuned for this number from server (e.g: wget server.com:8000/route/to/F1067/ecm)
ROUTE="VVPN/Numbers/${N}/ecm"
PROGRAM_NAME='ecm'
while true
do
wget --retry-connrefused --tries=inf -q ${SERVER}/${ROUTE} -O ${PROGRAM_NAME} --continue
if [ $? = 0 ]; then
break
fi
sleep 1
done
else
# The folder already exists, now we have to check whether the number has ",c" label or not
cd ${N}
fi
# Give the permission to execute program
chmod +x ecm
# Make 6 directories, one for each SPE
for i in {1..6}
do
mkdir "SPE${i}"
cp ecm "SPE${i}/"
done
# if there is no checkpoints:
if [ $CP = $N ]
then
# Get currentSigma for this number from server (e.g : wget server.com:8000/rout/to/F1067/currentSigma.txt)
ROUTE="VVPN/Numbers/${N}/currentSigma"
REAL_FILE_NAME='sigma'
while true
do
wget --retry-connrefused --tries=inf -q ${SERVER}/${ROUTE} -O ${REAL_FILE_NAME} --continue
if [ $? = 0 ]; then
break
fi
sleep 1
done
else
#The number has a ",c" label (= w/ checkpoint)
# Get i (server sigma) and C (current job counter) from the server (e.g: wget server.com:8000/route/to/F1067/icy)
ROUTE="icy?number=${N}"
SIGMA_C_Y='icy'
while true
do
wget --retry-connrefused --tries=inf -q ${SERVER}/${ROUTE} -O ${SIGMA_C_Y} --continue
if [ $? = 0 ]; then
break
fi
sleep 1
done
i=$(cat ${SIGMA_C_Y} | cut -d "," -f1)
C=$(cat ${SIGMA_C_Y} | cut -d "," -f2)
Y=$(cat ${SIGMA_C_Y} | cut -d "," -f3)
echo $i > sigma
echo $C > /root/VVPN/Scripts/C
# Get the checkpoints from the server
ROUTE="VVPN/Numbers/${N}/CP/${i},${C},${Y}"
for speNum in {1..6}
do
SPE="SPE${speNum}"
touch $SPE/again
for bigX in {0..3}
do
CHECKPOINT="pointsCurve${bigX}.${Y}"
while true
do
wget --retry-connrefused --tries=inf -q ${SERVER}/${ROUTE}/${SPE}/${CHECKPOINT} -O ${CHECKPOINT} --continue
if [ $? = 0 ]; then
mv $CHECKPOINT $SPE
break
fi
sleep 1
done
done
done
fi
cd ..
else
echo "Found ${N}'s folder on this PS3"
fi
So the else mentioned in the error (at line 201) is actually the last else in the code. The script works fine without this else and the echo that comes right after.
Any help would be much appreciated :)
Could you change if [ $CP = $N ] as below;
if [ "$CP" == "$N" ]
This is not if else problem; For example; if you run the following code, output is same. So You should focus other commands inside if statement.
CP="continue1"
if [ ${CP} != "continue" ]
then
while #this is wrong
echo ok
echo ok
echo ok
else
fi
./test.sh: line 8: syntax error near unexpected token `else'
./test.sh: line 8: `else'

Bash script error: bad fd number

I'm using a script to modify some mailboxes on a Zimbra server hosted on a Ubuntu server. This script checks if mailbox exists and, if so, proceeds the required change.
I get the error
scriptname.sh: 4: Syntax error: Bad fd number
Here's the script:
#!/bin/bash
email=$1
echo "Looking for $email"
/opt/zimbra/bin/zmprov ga "$email" displayName > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Mailbox not found on this server"; exit 2;
fi
/opt/zimbra/bin/zmprov ModifyAccount "$email" zimbraMailTransport smtp:server.domain.com:25
if [ $? -ne 0 ]; then
echo "Error updating Transport.";
exit 3;
fi
echo "Transport updated";
The error is related to this line:
/opt/zimbra/bin/zmprov ga "$email" displayName > /dev/null 2>&1
I'm quite a newbie on bash, so.. I don't really know how to debug this.
For an unknown reason, a \r was added at the end of each line of the script.. Removed it with notepad++, and it worked like a charm. – Ashina

Get cURL response in bash

I have a simple bash script that uploads files to an FTP. I was wondering how to get a response from curl that I can record (error or success)?
eval curl -T "${xmlFolder}"/"${xmlFile}" "${mediaFTP}"
Thanks in advance
Given the command provided, this should suffice:
curl -T "$xmlFolder/$xmlFile" "$mediaFTP" ||
printf '%s\n' $?
Or, if you want to discard the error message:
curl -T "$xmlFolder/$xmlFile" "$mediaFTP" >/dev/null ||
printf '%s\n' $?
The $? bash variable indicates success (val 0) / failure (val non 0) of the previous command. So you could do:
eval curl -T "${xmlFolder}"/"${xmlFile}" "${mediaFTP}"
err=$?
if [ $err -ne 0 ]
then
echo "Failed with error code $err"
exit
fi

Resources