Error trapping scp exit code not working - linux

I have
# Transfer today's CMS backup to a remote backup server
scp -P 55 -r $localdumpdirectory/dirdump-cms-`date +%Y%m%d`.tar.gz root#someserver:/$remotedumpdirectory/ >/dev/null 2>&1
status=${$}
if [[ ${status} != 0 ]]
then
echo "Failed to secure copy directory, with code: ${status}"
exit 1
fi;
Everything is working except that even though the SCP succeeds, I get:
Failed to secure copy directory, with code: 27348
Ideas?

Exit code is $?, not $$. $$ is process ID.
status=${$}
should be
status=$? # or ${?} if you really insist.
If this is bash, see the section "Special Parameters" in the documentation.

Do you want
status=$?
That will give you the status of the last command.
status=$$
This is giving you the last PID
http://tldp.org/LDP/abs/html/internalvariables.html#PROCCID

BTW, you can shorten what you have to:
if scp -P 55 -r $localdumpdirectory/dirdump-cms-`date +%Y%m%d`.tar.gz root#someserver:/$remotedumpdirectory/ >/dev/null 2>&1
then
echo "Failed to secure copy directory, with code: ${status}"
exit 1
fi

Related

Exiting bash script without terminating ssh connection

I'm pretty new to bash scripting and I'm attempting to write a script that does some basic operations.
I want to check certain conditions and if they are met, terminate the script. So for example, I want to check whether the zip of files was successful:
echo "Zipping file..."
for file in $fileList;
do
echo $file | zip -v $archive -#
if [[ $? != 0 ]];
then
echo "Error creating zip"
exit 1
fi
done
What happens though is that the exit 1 signal causes the ssh connection to terminate as well:
Zipping file...
Command 'zip' not found, but can be installed with:
sudo apt install zip
Error creating zip
Connection to 3.137.7.52 closed.
What's the correct way to terminate a script without also disconnecting from the server?
If you wrap it all in a script with shebang #!/bin/bash than exit 1 will be fine
but if you run this as a oneliner directly in console then this exit 1 means exit from console, and that would break ssh connection obvy
cat > ziper.sh << \EOF
#!/bin/bash
echo "Zipping file..."
for file in $fileList;
do
echo $file | zip -v $archive -#
if [[ $? != 0 ]];
then
echo "Error creating zip"
exit 1
fi
done
EOF
./ziper.sh
In oneliner use break

How to run bash script while it returns code 0?

I have bash script with many lines of code and I need run it while it returns $? == 0, but in case if it has error I need stop it and exit with code 1?
The question is how to do it?
I tried to use set -e command, but Jenkins does not marks build as failed, for him it looks like Success
I also need to get the Error message to show it in my Jenkins log
I managed to get error code(in my case it will be 126), but how to get error message?
main file
fileWithError.sh
rc=$?; if [[ $rc != 0 ]]; then
echo "exit {$rc} ";
fi
fileWithError.sh
#!/bin/sh
set -e
echo "Test"
agjfsjgfshgd
echo "Test2"
echo "Test3"
Just add the command set -e to the beginning of the file
This should look something similar to this
#!/bin/sh
set -e
#...Your code...
I think you just want:
#!/bin/sh
while fileWithError.sh; do
sleep 1;
done
echo fileWithError.sh failed!! >&2
Note that if the script is written well, then the echo is
redundant as fileWithError.sh should have written a decent
error message already. Also, the sleep may not be needed, but is useful to prevent a fast loop if the script succeeds quickly.
You can get the explicit return value, but it requires a bit of refactoring.
#!/bin/sh
true
while test $? = 0; do fileWithError.sh; done
echo fileWithError.sh failed with status $?!! >&2
since the return value of the while script will be the
return value of sleep in the first construction.
Its not quite easy to get an error code only.
How about this ...
#!/bin/bash
Msg=$(fileWithError.sh 2>&1) # redirect all error messages to stdout
if [ "$?" -ne 0 ] # Not Equal
then
echo "$Msg"
exit 1
fi
exit 0
You catch all messages created by fileWithError.sh and if the programm returned an error code then you have the error message already saved in a variable.
But this will make a disadvantage, because you will temporary store all messages created by fileWithError.sh till the error appears.
You can filter the error message with echo "$Msg" |tail -n 1, but its not 100% save.
You should also do some changes in fileWithError.sh...
Switch set -e with trap "exit 1" ERR. this will close the script on errors.
Hope this will help.

How to tell in the script that if the scp failed, try wget

I have this script :
cd /tmp/
scp user#8.8.4.1:/onboot/OTA.sh /tmp -i /usr/script/id 2> /dev/null
if
chmod 775 /tmp/OTA.sh
/tmp/OTA.sh &
sleep 30
rm -rf /tmp/OTA.sh
fi
I want to tell in the script that if the scp failed, try wget
man scp
EXIT STATUS
The scp utility exits 0 on success, and >0 if an error occurs.
The exit status can be accessed using the variable $? in bash.
$? contains exit code of last called command. You can simply check if its non-zero:
scp user#8.8.4.1:/onboot/OTA.sh /tmp -i /usr/script/id 2> /dev/null
if [[ $? -ne 0 ]]
then
#wget here
fi

shell bash script - upload a big tar file, retry?

I use the following shell script code to upload a big .tar file. Sometimes it happens that the server can´t resolve the domain to the ip or the other server isn´t available. So I wan´t it to retry some times if it didn´t work. How can I do this? I couldn´t find something for this on the internet.
ftp -inv << EOF
open $FTP_SERVER
user $FTP_USER $FTP_PASS
cd $FTP_VERZEICHNIS
mkdir ultimate_$DATE
cd ultimate_$DATE
mput *.tar
quit
EOF
Edit:
Sorry I have no real experience with shell, how would this look like ?
FTP_SUCCESS_MSG="226 Transfer complete"
while [fgrep "$FTP_SUCCESS_MSG" $FTPLOG]
do
FTPLOG=/temp/ftplogfile
ftp -inv <<! > $FTPLOG
open $FTP_SERVER
user $FTP_USER $FTP_PASS
cd $FTP_VERZEICHNIS
mkdir ultimate_$DATE
cd ultimate_$DATE
mput *.tar
close
quit
!
fi
exit 0
sleep 10s
else
echo "Upload completed"
done
Adapting from your code and the one in Getting exit status code from 'ftp' command in linux shell I made this:
#!/bin/bash
FTP_SUCCESS_MSG="226 Transfer complete"
FTPLOG=/temp/ftplogfile
i=0
while [ $i -le 5 ]; do
ftp -inv <<! > $FTPLOG
open $FTP_SERVER
user $FTP_USER $FTP_PASS
cd $FTP_VERZEICHNIS
mkdir ultimate_$DATE
cd ultimate_$DATE
mput *.tar
close
quit
!
if fgrep "$FTP_SUCCESS_MSG" $FTPLOG ;then
i=10 #stupid way of saying: exit the "while"
else
sleep 5
i=expr $i + 1 # ((i++)) not working
fi
done

wget with errorlevel bash output

I want to create a bash file (.sh) which does the following:
I call the script like ./download.sh www.blabla.com/bla.jpg
the script has to echo then if the file has downloaded or not...
How can I do this? I know I can use errorlevel but I'm new to linux so...
Thanks in advance!
Typically applications in Linux will set the value of the environment variable $? on failure. You can examine this return code and see if it gets you any error for wget.
#!/bin/bash
wget $1 2>/dev/null
export RC=$?
if [ "$RC" = "0" ]; then
echo $1 OK
else
echo $1 FAILED
fi
You could name this script download.sh. Change the permissions to 755 with chmod 755. Call it with the name of the file you wish to download. ./download.sh www.google.com
You could try something like:
#!/bin/sh
[ -n $1 ] || {
echo "Usage: $0 [url to file to get]" >&2
exit 1
}
wget $1
[ $? ] && {
echo "Could not download $1" | mail -s "Uh Oh" you#yourdomain.com
echo "Aww snap ..." >&2
exit 1
}
# If we're here, it downloaded successfully, and will exit with a normal status
When making a script that will (likely) be called by other scripts, it is important to do the following:
Ensure argument sanity
Send e-mail, write to a log, or do something else so someone knows what went wrong
The >&2 simply redirects the output of error messages to stderror, which allows a calling script to do something like this:
foo-downloader >/dev/null 2>/some/log/file.txt
Since it is a short wrapper, no reason to forsake a bit of sanity :)
This also allows you to selectively direct the output of wget to /dev/null, you might actually want to see it when testing, especially if you get an e-mail saying it failed :)
wget executes in non-interactive way. This means that wget work in the background and you can't catch de 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.

Resources