我想要一个 shell 脚本来根据tar
成功还是失败写一条消息,但是这个脚本不能正常工作:
TAR=$(tar -cf Archiv.tar myfolder/ myotherfolder/)
if [ ! "$TAR" = "/dev/null" ]; then
echo "success"
else
echo "error - no such Directory or file"
fi
问题是什么?
答案1
我不知道在什么情况下tar
会输出/dev/null
错误信号,而这正是代码尝试检测错误的方式。这是检查错误的正确方法:
if tar -cf Archiv.tar myfolder/ myotherfolder/
then
echo "success"
else
echo "error - no such Directory or file"
fi
您可能不需要该else
案例,因为tar
该案例本身会抱怨。如果您使用的目的/dev/null
是抑制tar
抱怨,以便您可以替换自己的消息,那么第一行应该是:
if tar -cf Archiv.tar myfolder/ myotherfolder/ > /dev/null 2>&1
请注意,我们这里没有使用方括号。这实际上是内置 shell 命令的别名,名为test(1)
它执行逻辑运算并分别返回 0 或非零来表示成功或失败。if
反过来检查这个 0/非零返回,所以为了检查像tar
失败时返回非零的程序的成功,你不需要涉及test
或其别名[
。
如果您接受过某种编程语言的培训,该语言要求在表达式周围使用某种标点符号,if
而标点符号的缺乏会困扰您,那么您可以像这样重写第一行:
tar -cf Archiv.tar myfolder/ myotherfolder/
if [ $? = 0 ]
这两行合在一起完成与上面版本相同的功能,因为 shell 内置变量$?
保存了上次程序运行的状态码。
这也许更清楚,但有点浪费。
答案2
像往常一样,有多种方法可以完成您想要做的事情。
这是一种(可能很紧凑的)方法:
#!/bin/bash
TAR_COMMAND='tar -cf Archiv.tar myfolder/ myotherfolder/ 2>/dev/null'
MSG_OK='### Work well DONE ### ' # A more common way to use a variable
MSG_ERR='### OPS IT FAILS ### '
$TAR_COMMAND && echo $MSG_OK || echo $MSG_ERR
简短说明
如果你有无需存储退出状态(或退出代码)你可以在操作符后立即使用和,
&&
, 和 或者,||
[1]。
逻辑:cmd1 && cmd2
,仅在无错误退出cmd2
时执行(退出代码)。相反,仅在出现错误退出时执行(错误代码不同于)。cmd1
0
cmd1 || cmd3
cmd3
cmd1
0
相反,如果你想要存储退出代码你必须在命令执行后立即执行此操作,因为在下一个命令执行时,此值将被更新。变量赋值就足够了
mycommand # you execute your command ExitCodeToUseLater=$? # So I can use it later in the script # ... other stuffs ... [ $ExitCodeToUseLater = 0 ] && echo "It was gone ok " # ... again other stuffs ... [ $ExitCodeToUseLater = 0 ] || echo "# Never a time that it goes as I want"
在 bash 脚本以及 makefile 中[2a,2b], 你可以找到一个命令有很多选择写在变量中以使代码更具可读性(如上所示
TAR_COMMAND
)。在 shell 中写入变量$MyVar
与在 shell 中写入的内容相同[3]。它在脚本中也有效。您可能需要注意 bash 扩展和替换规则,有关详细信息,请参阅man bash
。/dev/null
是个空设备 [4], “丢弃写入的所有数据但报告写入操作成功的设备文件”。它可用于为命令提供空输入(</dev/null
)或以“绝对静默”的方式传递标准输出或标准错误[5]。