如果是shell命令的bash脚本中的else

时间:2017-07-03 17:05:07

标签: bash shell

我编写了一个没有显示任何错误的bash脚本。但是我想添加条件阻止列表如果成功然后显示电子邮件成功,则在电子邮件中显示错误消息,如下面的代码所示。

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

这是没有If else阻止的工作脚本

#!/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!"

3 个答案:

答案 0 :(得分:2)

scp手册页指出:The scp utility exits 0 on success, and >0 if an error occurs.

所以你可以这样做:

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

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

最后你可能还想看看存储scp输出之类的东西。使用-q让scp不打印进度表而不是:

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

答案 1 :(得分:0)

link应该清除空气。希望它有所帮助!

答案 2 :(得分:0)

@Korthrun已经发布了几种方法来实现我认为你想要做的事情;我将查看当前脚本中出现的问题。您似乎对shell脚本的几个基本元素感到困惑:管道(|)和测试命令成功/失败。

管道用于将一个命令的输出传递给另一个命令的输入(然后可能将第二个命令的输出链接到第三个命令的输入等)。但是当你使用这样的管道字符串时:

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!"
管道实际上并没有做任何事情。第一个管道尝试获取echo的输出并将其提供给mail的输入,但>>命令中的echo将其输出发送到文件,所以没有实际数据发送到mail命令。这可能是好的,因为<<<命令上的mail告诉它忽略常规输入(来自管道)并输入字符串作为输入!类似地,第二个管道尝试将第一个mail命令(没有任何内容)的输出提供给最后一个mail命令,但由于另一个命令,它再次被忽略{ {1}}输入字符串。正确的方法是删除管道,并分别运行每个命令:

<<<

这也会导致脚本的其他版本出现问题:

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!"

这里,在管道之前没有命令,所以它根本没有任何意义(并且你得到一个shell语法错误)。只需取下管道即可。

现在,关于成功/失败测试:您似乎使用if success then | mail -s "Download Successfull" abc@test.com <<< "Files Successfully Downloaded" 作为命令,但它不是一个。您可以使用您想要检查成功的命令直接作为success条件:

if

或使用shell变量if scp ...; then echo "It worked!" else echo "It failed!" fi ,它返回最后一个命令的退出状态(success = 0,failure = nothing):

$?

这里有一个很容易错过的微妙之处:scp ... if [ $? -eq 0 ]; then ... 之后的事情是一个命令,但在第二种形式中,它似乎是一个逻辑表达式(测试是否{{1} }等于if)。秘诀是$?实际上是一个命令,用于评估逻辑表达式,然后根据表达式是真还是假而成功或失败退出。不要将0误认为某种括号或其他分组操作符,这不是这里发生的事情!

BTW,Korthrun使用的[形式与[ ]非常相似,但不受更多基本shell的支持。尽管如此,它确实可以避免使用[[ ]]的一些令人讨厌的语法怪异,所以如果您使用[ ],这是一个很好的方法。

另外,请注意[ ]给出了最后执行的命令的状态,因此它会被执行的每个命令重置。例如,这不会起作用:

bash

...因为$?正在查看scp ... echo "scp's exit status was $?" if [ $? -eq 0 ]; then # Don't do this!!!! 命令的退出状态,而不是if!如果您需要执行此类操作,请将状态存储在变量中:

echo