我想写这样的代码:
command="some command"
safeRunCommand $command
safeRunCommand() {
cmnd=$1
$($cmnd)
if [ $? != 0 ]; then
printf "Error when executing command: '$command'"
exit $ERROR_CODE
fi
}
但是这段代码没有按照我想要的方式运行。 哪里弄错了?
答案 0 :(得分:65)
以下是固定代码:
#!/bin/ksh
safeRunCommand() {
typeset cmnd="$*"
typeset ret_code
echo cmnd=$cmnd
eval $cmnd
ret_code=$?
if [ $ret_code != 0 ]; then
printf "Error : [%d] when executing command: '$cmnd'" $ret_code
exit $ret_code
fi
}
command="ls -l | grep p"
safeRunCommand "$command"
现在,如果你查看这段代码,我改变的一些事情就是:
typeset
不是必要的,而是一种很好的做法。它使cmnd
和ret_code
属于safeRunCommand
ret_code
不是必需的,但是将返回代码存储在某个变量中(并尽快存储)是一种很好的做法,以便您可以像我在printf "Error : [%d] when executing command: '$command'" $ret_code
safeRunCommand "$command"
。如果您不这样做,cmnd
将只获得值ls
而不是ls -l
。如果您的命令包含管道,则更为重要。typeset cmnd="$*"
代替typeset cmnd="$1"
。您可以尝试使用两者,具体取决于命令参数的复杂程度。注意:请记住一些命令将1作为返回码,即使没有像grep
这样的错误。如果grep
发现某些内容,则会返回0,否则为1.
我用KSH / BASH测试过。它工作得很好。如果你遇到问题,请告诉我。
答案 1 :(得分:5)
尝试
safeRunCommand() {
"$@"
if [ $? != 0 ]; then
printf "Error when executing command: '$1'"
exit $ERROR_CODE
fi
}
答案 2 :(得分:2)
应该是$cmd
而不是$($cmd)
。在我的盒子上工作正常。
编辑:您的脚本仅适用于单字命令,例如ls。它不适用于“ls cpp”。要实现此目的,请将cmd="$1"; $cmd
替换为"$@"
。并且,不要将您的脚本作为command="some cmd"; safeRun command
运行,请将其作为safeRun some cmd
运行。
此外,当您必须调试bash脚本时,请使用'-x'标志执行。 [bash -x s.sh]。
答案 3 :(得分:1)
你的剧本有几个问题。
在尝试调用函数(子例程)之前,应该声明它们。您可能希望从子例程返回()而不是exit(),以允许调用块测试特定命令的成功或失败。除此之外,您不会捕获'ERROR_CODE',因此始终为零(未定义)。
使用花括号包围变量引用也是一种很好的做法。您的代码可能如下所示:
#!/bin/sh
command="/bin/date -u" #...Example Only
safeRunCommand() {
cmnd="$@" #...insure whitespace passed and preserved
$cmnd
ERROR_CODE=$? #...so we have it for the command we want
if [ ${ERROR_CODE} != 0 ]; then
printf "Error when executing command: '${command}'\n"
exit ${ERROR_CODE} #...consider 'return()' here
fi
}
safeRunCommand $command
command="cp"
safeRunCommand $command
答案 4 :(得分:0)
通常的想法是运行命令然后使用$?
来获取退出代码。但是,有时您有多种情况需要获取退出代码。例如,您可能需要隐藏它的输出但仍返回退出代码,或者同时打印退出代码和输出。
ec() { [[ "$1" == "-h" ]] && { shift && eval $* > /dev/null 2>&1; ec=$?; echo $ec; } || eval $*; ec=$?; }
这将为您提供禁止输出您想要退出代码的命令的选项。当命令的输出被抑制时,函数将直接返回退出代码。
我个人喜欢将此功能放在我的.bashrc
文件
下面我将演示一些可以使用它的方法:
# In this example, the output for the command will be
# normally displayed, and the exit code will be stored
# in the variable $ec.
$ ec echo test
test
$ echo $ec
0
# In this example, the exit code is output
# and the output of the command passed
# to the `ec` function is suppressed.
$ echo "Exit Code: $(ec -h echo test)"
Exit Code: 0
# In this example, the output of the command
# passed to the `ec` function is suppressed
# and the exit code is stored in `$ec`
$ ec -h echo test
$ echo $ec
0
使用此功能解决您的代码
#!/bin/bash
if [[ "$(ec -h 'ls -l | grep p')" != "0" ]]; then
echo "Error when executing command: 'grep p' [$ec]"
exit $ec;
fi
您还应该注意,您将看到的退出代码将用于正在运行的
grep
命令,因为它是正在执行的最后一个命令。不是ls
。