是否在Bash中运行了最后一个命令? [英] Echoing the last command run in Bash?

查看:80
本文介绍了是否在Bash中运行了最后一个命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图回显在bash脚本中运行的最后一个命令.我找到了一种使用history,tail,head,sed做到这一点的方法,当从解析器的角度来看命令在我的脚本中代表特定行时,该方法很好用.但是在某些情况下,例如在将命令插入case语句内

I am trying to echo the last command run inside a bash script. I found a way to do it with some history,tail,head,sed which works fine when commands represent a specific line in my script from a parser standpoint. However under some circumstances I don't get the expected output, for instance when the command is inserted inside a case statement:

脚本:

#!/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同事对此表示赞赏,但我选择编写run函数-该函数将其所有参数作为单个命令运行,并在失败时显示该命令及其错误代码-具有以下好处:
-我只需要将要检查的命令放在run之前,这样可以将它们保持在一行上,并且不会影响脚本的简洁性
-每当脚本在这些命令之一上失败时,脚本的最后输出行就会显示一条消息,清楚地显示哪个命令及其退出代码失败,从而使调试更加容易

Despite the much appreciated contributions from my fellow SO'ers, I opted for writing a run function - which runs all its parameters as a single command and display the command and its error code when it fails - with the following benefits:
-I only need to prepend the commands I want to check with run which keeps them on one line and doesn't affect the conciseness of my script
-Whenever the script fails on one of these commands, the last output line of my script is a message that clearly displays which command fails along with its exit code, which makes debugging easier

示例脚本:

#!/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变量作为参数,带引号的参数的各种命令,并且run函数没有破坏它们.到目前为止,我发现的唯一问题是运行回波,但该回波中断了,但我仍然不打算检查回波.

I tested various commands with multiple arguments, bash variables as arguments, quoted arguments... and the run function didn't break them. The only issue I found so far is to run an echo which breaks but I do not plan to check my echos anyway.

推荐答案

命令历史记录是一种交互式功能.历史记录中仅输入完整的命令.例如,当外壳完成解析后,整个输入case构造.使用内置的history查找历史记录(也不通过外壳扩展(!:p)打印历史记录)并不能满足您的需要,即打印简单命令的调用.

The command history is an interactive feature. Only complete commands are entered in the history. For example, the case construct is entered as a whole, when the shell has finished parsing it. Neither looking up the history with the history built-in (nor printing it through shell expansion (!:p)) does what you seem to want, which is to print invocations of simple commands.

通过 DEBUG陷阱,您可以执行在执行任何简单命令之前的命令. BASH_COMMAND 变量.

The DEBUG trap lets you execute a command right before any simple command execution. A string version of the command to execute (with words separated by spaces) is available in the BASH_COMMAND variable.

trap 'previous_command=$this_command; this_command=$BASH_COMMAND' DEBUG
…
echo "last command is $previous_command"

请注意,每次运行命令时,previous_command都会更改,因此请将其保存到变量中以便使用.如果您还想知道上一条命令的返回状态,请将两者保存在一个命令中.

Note that previous_command will change every time you run a command, so save it to a variable in order to use it. If you want to know the previous command's return status as well, save both in a single command.

cmd=$previous_command ret=$?
if [ $ret -ne 0 ]; then echo "$cmd failed with error code $ret"; fi

此外,如果您只想中止失败的命令,请使用 EXIT陷阱.

Furthermore, if you only want to abort on a failed commands, use set -e to make your script exit on the first failed command. You can display the last command from the EXIT trap.

set -e
trap 'echo "exit $? due to $previous_command"' EXIT

请注意,如果您试图跟踪脚本以查看其作用,请忘记所有这些,并使用

Note that if you're trying to trace your script to see what it's doing, forget all this and use set -x.

这篇关于是否在Bash中运行了最后一个命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆