Error in checking file downloaded properly through curl - bash

I am trying to run curl command to download a file using sftp and after that checking if that file downloaded or not, but somehow my code is printing "File downloaded successfully" everytime even when the file did not download.
Here is my script:
#!bin/bash
curl -k -u "user:user" -ssl -o file.zip sftp:domain
if [[ $? -ne 0 ]]; then
echo "Failed to download file"
exit -1
fi
echo "File downloaded successfully"

Try using --write-out option as
#!bin/bash
rcode=$(curl --silent --write-out '%{response_code}' -k -u "user:user" -ssl -o file.zip sftp:domain)
if [[ "$rcode" -ne 0 ]]; then
echo "Failed to download file"
exit -1
fi
echo "File downloaded successfully"
For a 404 http response
rcode=$curl --silent --write-out '%{response_code})' http://localhost:8080/tyu
echo "$rcode"
404
sftp response codes, success is 0.

Related

Shell script for monitoring the sever

Can someone please give shell script for this scenario. I need to check below Server/URL is up or not.
If my server is up no need to trigger any alert .. if my server is down .. Alert should be triggered by stating my server is down.
http://18.216.40.147:5555/
#!/bin/bash
addr=18.216.40.147
if ! curl -v -u 'Administrator:******' https://"$addr":5555 | grep HTTP/1.1 200; then
echo "Server is down" | mailx -s "server is down" "******#gmail.com"
echo "Server is down" >&2
fi
curl can return only http response code, then you can compare with right answer:
#!/bin/bash
addr="http://18.216.40.147:5555/"
answer=$(curl -o /dev/null -s -w '%{http_code}\n' $addr)
if [ $answer -eq 200 ]
then
echo "UP"
else
echo "DOWN"
fi
Suggesting #Juarnir Santos is essentially correct but need some improvements:
If server is down or network configuration is blocking access to server, you want to timeout the request for 4 (or more) seconds.
Bash testing for numbers requires [[ numerical expression ]]
Therefore the improved answer is:
#!/bin/bash
addr="http://18.216.40.147:5555/"
answer=$(timeout 4 curl -o /dev/null -s -w '%{http_code}\n' $addr)
if [[ $answer -eq 200 ]]; then
echo "UP"
else
echo "DOWN"
fi

Checking whether specific website is up in the terminal?

Is there an easy way to check Internet connectivity from console? I am trying to play around in a shell script. One idea I seem is to wget --spider http://www.google.com/ and check the HTTP response code to interpret if the Internet connection is working fine.
This is what I am trying:
#!/bin/bash
# Sending the output of the wget in a variable and not what wget fetches
RESULT=`wget --spider http://google.com 2>&1`
FLAG=0
# Traverse the string considering it as an array of words
for x in $RESULT; do
if [ "$x" = '200' ]; then
FLAG=1 # This means all good
fi
done
Is there any way to accomplish this?
You can do it with ping or curl commands. Check man for more.
I am using this for myself and kinda works for me! It checks the connection from a reliable website like google and if it gets 200 status as the response, you probably have internet.
if curl -s --head --request GET www.google.com | grep "200 OK" > /dev/null ; then
echo "Internet is present"
else
echo "Internet isn't present"
fi
On one line, thanks #PS
if ping -c1 8.8.8.8 &>/dev/null ;then echo Working ;else echo Down ;fi
An option that does not use the internet to see if it is available is to check for a default route in your routing tables. The routing daemon will remove your default route when the internet is not available and add it back when it is.
netstat -nrf inet | grep -q ^default && \
echo internet is up || \
echo internet is down
To check if a website is up, you can use netcat to see if it is listening on port 80. This helps with sites that refuse head requests with '405 Method Not Allowed'.
nc -zw2 www.example.com 80 &>/dev/null && \
echo website is up || \
echo website is down
Please try this code.
#!/bin/bash
wget -q --spider http://google.com
if [ $? -eq 0 ]; then
echo "Internet connection is OK"
else
echo "Internet connection is FAILED"
fi
A bit more compact variant of #carlos-abraham answer. You can have curl to output just the http response code and make a decision with it
# 200 if everything is ok
http_code=$(curl -s --head -m 5 -w %{http_code} --output /dev/null www.google.com)
if [ "$http_code" -eq 200 ]; then
echo "success"
else
# write error to stderr
echo "http request failed: $http_code" >&2
exit 1
fi
-m 5: wait 5 seconds for the whole operation
--output /dev/null: suppress html site response
-w %{http_code}: write to stdout the http response code.
A bit more elaborated script to check connectivity and http response
#url="mmm.elgoog.moc"
url="www.google.com"
max_wait=5
(ping -w $max_wait -q -c 1 "$url" > /dev/null 2>&1 )
response_code=$?
if [ "$response_code" -eq 0 ]; then
# 200 if everything is ok
response_code=$(curl -s --head -m $max_wait -w %{http_code} --output /dev/null "$url")
fi
case "$response_code" in
1)
echo "Connectivity failed. Host down?" >&2
exit $response_code
;;
2)
echo "Unknown host or other problem. DNS problem?" >&2
exit $response_code
;;
200)
echo "success"
exit 0
;;
*)
echo "Failed to get a response: $response_code" >&2
exit 1
esac

If else in bash script for shell command

I have written a bash script that does not show any errors. However I would like to add conditional block list if success then show email success else show error message in email as shown in the code below.
scp -i id_rsa -r testuser#1.1.1.:/data1/scp ~/data/scp/files
success >> ~/data/scp/files/log.txt 2>&1
if success
then
| mail -s "Download
Successfull" abc#test.com <<< "Files Successfully Downloaded"
else
| mail -s "Error: Download Failed" abc#test.com <<< "Error File download
Failed!"
fi
Here is the working script without If else block
#!/module/for/bash
scp -i id_rsa -r test#1.1.1.1:/data1/scp ~/data/scp/files
echo success! >> ~/data/scp/files/log.txt 2>&1 | mail -s "Download
Successfull" abc#test.com <<< "Files Successfully
Downloaded" | mail -s "Error: Download Failed" abc#test.com <<<
"Error:file download Failed!"
The scp man page states: The scp utility exits 0 on success, and >0 if an error occurs.
So you can do something like:
if scp -i id_rsa -r testuser#1.1.1.:/data1/scp ~/data/scp/files
then
mail -s "Download Successful" abc#test.com <<<"Files Downloaded"
else
mail -s "Download Error" abc#test.com <<<"Download error"
fi
or
scp -i id_rsa -r testuser#1.1.1.:/data1/scp ~/data/scp/files
if [[ $? -eq 0 ]]
then
mail -s "Download Successful" abc#test.com <<<"Files Downloaded"
else
mail -s "Download Error" abc#test.com <<<"Download error"
fi
finally you may also want to look at something like storing the scp output. Use -q to have scp not print out progress meters and what not:
MYOUT=$(scp -q -i id_rsa -r testuser#1.1.1.:/data1/scp ~/data/scp/files 2>&1)
if [[ $? -eq 0 ]]
then
mail -s "Download Successful" abc#test.com <<<"$MYOUT"
else
mail -s "Download Error" abc#test.com <<<"$MYOUT"
fi
This link should clear the air. Hope it helped!
#Korthrun has already posted several ways to accomplish what I think you're trying to do; I'll take a look at what's going wrong in your current script. You seem to be confused about a couple of basic elements of shell scripting: pipes (|) and testing for command success/failure.
Pipes are used to pass the output of one command into the input of another (and possibly then chain the output of the second command into the input of a third command, etc). But when you use a pipe string like this:
echo success! >> ~/data/scp/files/log.txt 2>&1 |
mail -s "Download Successfull" abc#test.com <<< "Files Successfully Downloaded" |
mail -s "Error: Download Failed" abc#test.com <<< "Error:file download Failed!"
the pipes aren't actually doing anything. The first pipe tries to take the output of echo and feed it to the input of mail, but the >> in the echo command sends its output to a file instead, so no actual data is sent to the mail command. Which is probably good, because the <<< on the mail command tells it to ignore the regular input (from the pipe) and feed a string as input instead! Similarly, the second pipe tries to feed the output from the first mail command (there isn't any) to the last mail command, but again it's ignored due to another <<< input string. The correct way to do this is simply to remove the pipes, and run each command separately:
echo success! >> ~/data/scp/files/log.txt 2>&1
mail -s "Download Successfull" abc#test.com <<< "Files Successfully Downloaded"
mail -s "Error: Download Failed" abc#test.com <<< "Error:file download Failed!"
This is also causing a problem in the other version of your script, where you use:
if success
then
| mail -s "Download Successfull" abc#test.com <<< "Files Successfully Downloaded"
Here, there's no command before the pipe, so it doesn't make any sense at all (and you get a shell syntax error). Just remove the pipe.
Now, about success/failure testing: you seem to be using success as a command, but it isn't one. You can either use the command you want to check the success of directly as the if conditional:
if scp ...; then
echo "It worked!"
else
echo "It failed!"
fi
or use the shell variable $? which returns the exit status of the last command (success=0, failure=anything else):
scp ...
if [ $? -eq 0 ]; then
...
There's a subtlety here that's easy to miss: the thing after if is a command, but in the second form it appears to be a logical expression (testing whether $? is equal to 0). The secret is that [ is actually a command that evaluates logical expressions and then exits with success or failure depending on whether the expression was true or false. Do not mistake [ ] for some sort of parentheses or other grouping operator, that's not what's going on here!
BTW, the [[ ]] form that Korthrun used is very similar to [ ], but isn't supported by more basic shells. It does avoid some nasty syntax oddities with [ ], though, so if you're using bash it's a good way to go.
Also, note that $? gives the status of the last command executed, so it gets reset by every single command that executes. For example, this won't work:
scp ...
echo "scp's exit status was $?"
if [ $? -eq 0 ]; then # Don't do this!!!!
...because the if is then looking at the exit status of the echo command, not scp! If you need to do something like this, store the status in a variable:
scp ...
scpstatus=$?
echo "scp's exit status was $scpstatus"
if [ $scpstatus -eq 0 ]; then

FTP bash script

I would like to create a script that will upload a file until the upload uperation will successfull. The script will monitoring the log file. If "not connected" to the server i want to repeat the upload operation until "connected" and "file successfully transferred" Anyone can help me to build the correct one pls. What should i write after if egrep "not...?
LOGFILE=/home/transfer_logs/$a.log
First=$(egrep "Connected" $LOGFILE)
Second=$(egrep "File successfully transferred" $LOGFILE)
ftp -p -v -i 192.163.3.3 < ../../example.script > ../../$LOGFILE 2>&1
if
egrep "Not connected" $LOGFILE; then
ftp -p -v -i 192.163.3.3 < ../../example.script > ../../$LOGFILE 2>&1
until
[[ -n "$first" ]] && [[ -n "$second" ]];
done
fi
example contains:
binary
mput a.txt
quit
while :; do
ftp ... > $LOGFILE
grep -qF Connected $LOGFILE &&
grep -qF "File successfully transferred" $LOGFILE && break
done

How to check if an URL exists with the shell and probably curl?

I am looking for a simple shell (+curl) check that would evaluate as true or false if an URL exists (returns 200) or not.
Using --fail will make the exit status nonzero on a failed request. Using --head will avoid downloading the file contents, since we don't need it for this check. Using --silent will avoid status or errors from being emitted by the check itself.
if curl --output /dev/null --silent --head --fail "$url"; then
echo "URL exists: $url"
else
echo "URL does not exist: $url"
fi
If your server refuses HEAD requests, an alternative is to request only the first byte of the file:
if curl --output /dev/null --silent --fail -r 0-0 "$url"; then
I find wget to be a better tool for this than CURL; there's fewer options to remember and you can actually check for its truth value in bash to see if it succeeded or not by default.
if wget --spider http://google.com 2>/dev/null; then
echo "File exists"
else
echo "File does not exist"
fi
The --spider option makes wget just check for the file instead of downloading it, and 2> /dev/null silences wget's stderr output.

Resources