我试图回应一个bash脚本中运行的最后一个命令。我发现了一个方法来做一些历史,尾,头,sed,当命令表示我的脚本中的特定行从解析器立场工作正常。然而在某些情况下,我没有得到预期的输出,例如当命令插入case语句:
剧本:
#!/bin/bash set -o history date last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //') echo "last command is [$last]" case "1" in "1") date last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //') echo "last command is [$last]" ;; esac
输出:
Tue May 24 12:36:04 CEST 2011 last command is [date] Tue May 24 12:36:04 CEST 2011 last command is [echo "last command is [$last]"]
[Q]有人可以帮助我找到一种方式来回显最后一个运行命令,无论在bash脚本中如何/在哪里调用这个命令?
我的答案
尽管我的同事SO’ers非常感谢的贡献,我选择了编写一个运行函数 – 它运行所有的参数作为一个单一的命令,并显示命令和其失败时的错误代码 – 具有以下好处:
– 我只需要预先命令我想检查与运行,它们保持在一行,不影响我的脚本的简洁性
– 无论脚本在其中一个命令失败,我的脚本的最后一个输出行是一个消息,清楚地显示哪个命令失败及其退出代码,这使得调试更容易
示例脚本:
#!/bin/bash die() { echo >&2 -e "\nERROR: $@\n"; exit 1; } run() { "$@"; code=$?; [ $code -ne 0 ] && die "command [$*] Failed with error code $code"; } case "1" in "1") run ls /opt run ls /wrong-dir ;; esac
输出:
$ ./test.sh apacheds google iptables ls: cannot access /wrong-dir: No such file or directory ERROR: command [ls /wrong-dir] Failed with error code 2
我测试了各种命令与多个参数,bash变量作为参数,引用的参数…和运行函数没有打破他们。我发现到目前为止唯一的问题是运行一个回声,打破,但我不打算检查我的回波。
命令历史是一个交互功能。在历史记录中只输入完整的命令。例如,当shell完成解析它时,case结构作为一个整体输入。无论是通过内置的历史查找历史记录(也不通过shell扩展(!:p)打印它),你所需要的是打印简单命令的调用。
DEBUG
trap允许您在任何简单命令执行之前执行命令。要执行的命令的字符串版本(用空格分隔)在BASH_COMMAND
变量中可用。
trap 'prevIoUs_command=$this_command; this_command=$BASH_COMMAND' DEBUG … echo "last command is $prevIoUs_command"
注意,prevIoUs_command将在每次运行命令时更改,因此将其保存到变量以便使用它。如果你想知道上一个命令的返回状态,还要保存在一个命令中。
cmd=$prevIoUs_command ret=$? if [ $ret -ne 0 ]; then echo "$cmd Failed with error code $ret"; fi
此外,如果您只想中止失败的命令,请使用set -e
使脚本退出第一个失败的命令。您可以显示来自EXIT
trap的最后一个命令。
set -e trap 'echo "exit $? due to $prevIoUs_command"' EXIT
注意,如果你试图跟踪你的脚本,看看它在做什么,忘记所有这一切,使用set -x
。