Having a bash with bash

Let’s say we want to write a command that allows you to take the output of the previous command and stick it in your editor so you can page through it, save it, email it, etc.

One way to do it is with bash’s “process substitution” feature. Try this:

$ ls -l
$ cat <($(tail -1 $HISTFILE)) | vim -

One problem with this is it won’t work if you change “vim” to “emacs”, because Emacs doesn’t like to read stdin. I tried all kinds of stuff including “emacs -nw -t /dev/tty /dev/stdin” and such.

Well, here’s an even more general solution:

with-temp-file ()
{
    local _prefix=$1; shift
    local _tmpfile_var=$1 ; shift
    local ${_tmpfile_var}=$(mktemp -t ${_prefix})
    eval local _tmpfile_value=\${$_tmpfile_var}
    eval "$@"
    rm ${_tmpfile_value}
}

edlo ()
{
    with-temp-file "edlo" tmpfile \
        '$(tail -1 $HISTFILE) > $tmpfile && $EDITOR $tmpfile'
}

Actually for bash versions 2 and up, it turns out we can clean this up a tad using the new syntax for indirect references to variables:

--- edlo.sh.2006-04-29-152010   Sat Apr 29 15:19:53 2006
+++ edlo.sh     Sat Apr 29 15:25:11 2006
@@ -3,7 +3,7 @@
     local _prefix=$1; shift
     local _tmpfile_var=$1 ; shift
     local ${_tmpfile_var}=$(mktemp -t ${_prefix})
-    eval local _tmpfile_value=\${$_tmpfile_var}
+    local _tmpfile_value=${!_tmpfile_var}
     eval "$@"
     rm ${_tmpfile_value}
 }

This should work in any editor, including X11 editors since we’re not using stdin. And the with-temp-file function is a general utility function that could be used for other stuff. Here’s another function that uses it:

eoo () 
{ 
    local _cmd="$@";
    with-temp-file "eoo" tmpfile '$_cmd > $tmpfile && $EDITOR $tmpfile'
}

This one is when you already know that you want to capture the output of a particular command – e.g.:

$ eoo ls -l
$ eoo finger

Enjoy.

Unix Power Tools, Third Edition

3 thoughts on “Having a bash with bash

  1. I’m still trying to decide whether I like using shell mode or not. The key bindings are kind of funky and I miss my color ls output and such.

    Old habits die hard.

Leave a Reply

Your email address will not be published.