0

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 [email protected].:/data1/scp ~/data/scp/files 
success >> ~/data/scp/files/log.txt 2>&1 
if success 
then 
| mail -s "Download 
Successfull" [email protected] <<< "Files Successfully Downloaded" 
else 
 | mail -s "Error: Download Failed" [email protected] <<< "Error File download 
 Failed!"
 fi

Here is the working script without If else block

#!/module/for/bash
 scp -i id_rsa -r [email protected]:/data1/scp ~/data/scp/files 
 echo success! >> ~/data/scp/files/log.txt 2>&1 | mail -s "Download 
 Successfull" [email protected] <<< "Files Successfully 
 Downloaded" | mail -s "Error: Download Failed" [email protected] <<< 
 "Error:file download Failed!"
7
  • I googled if else bash and got tons of relevant results. What is your question exactly? Commented Jul 3, 2017 at 17:11
  • @HFBrowning please see updated question I am getting format error Commented Jul 3, 2017 at 17:16
  • 1
    Your then and else branches start with pipes; you aren’t allowed to do that. If you want to pipe into a conditional, the pipe needs to go before the if; I don’t remember if you also need to enclose the entire conditional ifelsefi block in a subshell. Commented Jul 3, 2017 at 17:20
  • You seem to have some additional line breaks, such as the one in the middle of one of your string literals. Please copy and paste your exact code, even if some of the lines are long. Is success a command? Commented Jul 3, 2017 at 17:40
  • @KeithThompson I have added all code. Basically I want that if success is true then if should run and other wise else. Working Example of script without if is updated in question please see that to get idea what I want Commented Jul 3, 2017 at 17:52

3 Answers 3

2

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 [email protected].:/data1/scp ~/data/scp/files
then
    mail -s "Download Successful" [email protected] <<<"Files Downloaded"
else
    mail -s "Download Error" [email protected] <<<"Download error"
fi

or

scp -i id_rsa -r [email protected].:/data1/scp ~/data/scp/files
if [[ $? -eq 0 ]]
then
    mail -s "Download Successful" [email protected] <<<"Files Downloaded"
else
    mail -s "Download Error" [email protected] <<<"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 [email protected].:/data1/scp ~/data/scp/files 2>&1)
if [[ $? -eq 0 ]]
then
    mail -s "Download Successful" [email protected] <<<"$MYOUT"
else
    mail -s "Download Error" [email protected] <<<"$MYOUT"
fi
Sign up to request clarification or add additional context in comments.

Comments

0

This link should clear the air. Hope it helped!

Comments

0

@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" [email protected] <<< "Files Successfully Downloaded" |
mail -s "Error: Download Failed" [email protected] <<< "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" [email protected] <<< "Files Successfully Downloaded"
mail -s "Error: Download Failed" [email protected] <<< "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" [email protected] <<< "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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.