title: Echoing the last command run in Bash?
body: <p>I am trying to echo the last command run inside a bash script. I found a way to do it with some <code>history,tail,head,sed</code> 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 <code>case</code> statement:</p>
  
  <p>The script:</p>
  
  <pre><code>#!/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
  </code></pre>
  
  <p>The output:</p>
  
  <pre><code>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]"]
  </code></pre>
  
  <p><strong>[Q] Can someone help me find a way to echo the last run command regardless of how/where this command is called within the bash script?</strong></p>
  
  <p><strong>My answer</strong></p>
  
  <p>Despite the much appreciated contributions from my fellow SO'ers, I opted for writing a <code>run</code> 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:<br>
  -I only need to prepend the commands I want to check with <code>run</code> which keeps them on one line and doesn't affect the conciseness of my script<br>
  -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</p>
  
  <p>Example script:</p>
  
  <pre><code>#!/bin/bash
  die() { echo &gt;&amp;2 -e "\nERROR: $@\n"; exit 1; }
  run() { "$@"; code=$?; [ $code -ne 0 ] &amp;&amp; die "command [$*] failed with error code $code"; }
  
  case "1" in
    "1")
    run ls /opt
    run ls /wrong-dir
    ;;
  esac
  </code></pre>
  
  <p>The output:</p>
  
  <pre><code>$ ./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
  </code></pre>
  
  <p>I tested various commands with multiple arguments, bash variables as arguments, quoted arguments... and the <code>run</code> 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.</p>