I'd like to know how to reuse the last output from the console, ie:

pv-3:method Xavier$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
pv-3:method Xavier$ cd **LASTOUTPUT**
  • 7
    You can't; there is some background explanation here. Your best bet is to run the command again, as seen in the two answers posted so far. Commented Mar 10, 2011 at 20:19
  • You can't capture output sent directly to a device such as /dev/tty, but it should be possible to capture anything sent to stdout or stderr, which might be adequate.
    – Mikel
    Commented Mar 10, 2011 at 20:26
  • @Gilles -- unless you use @mattdm's answer, of course!
    – simon
    Commented Mar 11, 2011 at 1:16
  • @Gilles: but there might be a shell created by someone that will capture (and pass through) the outputs of the commands and make the captured outputs available for the user to refer to from his further commands. Perhaps, there are even some existing, not so popular shells that allow this with more or less complications... Commented Mar 16, 2011 at 1:09
  • 1
    possible duplicate of Using text from previous commands' output Commented Mar 21, 2011 at 21:34

11 Answers 11


Assuming history expansion is enabled, that you're running Bash or some other shell that supports it, that the command is idempotent, and that waiting for it to run a second time is not an issue, you could use the !! form of history expansion to get the last command line again, to run the previous command again in a command substitution:

% python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
% cd $(!!)
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
% pwd
  • 1
    Thanks! Not too easy to type but it beats going for the mouse. Commented Mar 11, 2011 at 1:38
  • 2
    You could also use backticks (which I can't figure out how to make this interface not wikify) instead of $(), but I've found that it's uncomfortable for me to hit backtick-shift-1-shift-1-backtick, and I'm trying to get into the habit of using $() when possible for readability's sake.
    – jsbillings
    Commented Mar 11, 2011 at 13:40
  • @jsbillings see my answer below. I typed \` to display ` in the answer. And to display '\', as usual type '\\'.
    – yasouser
    Commented Mar 11, 2011 at 16:27
  • 3
    +1 I've been wondering how to nest `backtick-commands`! cd $(dirname $(which python))here I come!
    – Ed Brannin
    Commented Mar 11, 2011 at 17:52
  • 22
    Just a note, remember that this is rerunning the command. If your command has side effects, this may not work for you. Commented Mar 16, 2011 at 23:08

Not yet mentioned, use a variable:

dir=$( python -c ... )
cd "$dir"
  • 3
    Exactly. Because it's a shell, people often forget about the language features Bash provides, such as loops and assignment.
    – Evan
    Commented Mar 11, 2011 at 1:09
  • can just say cd $dir Commented Jan 26, 2015 at 0:10
  • 3
    @Aerovistae, the quotes are required if you don't know where the value comes from: Commented Jan 26, 2015 at 11:10
  • @glenn, (I know this could be whole other question, but if answer is short:) could you explain more/ provide an example where not using quotes would break things?
    – alexey
    Commented Jan 7, 2016 at 18:57
  • 2
    The canonical explanation is unix.stackexchange.com/questions/171346/… Commented Jan 7, 2016 at 19:13

All the other solutions involve modifying your workflow or running the command twice, which might not be suitable if it takes a long time to run, or is not repeatable (e.g. it deletes a file - rerunning it would produce a different result).

So here's a more complicated idea if you need it:


exec > >(tee -a ~/$$.out)

PROMPT_COMMAND='LASTLINE=$(tail -n 1 ~/$$.out)'

trap 'rm ~/$$.out' EXIT

bash prompt

$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
$ pwd

This has some issues, so it's just meant as a starting point. For example, the output file (~/<pid>.out) might grow very large and fill up your disk. Also, your whole shell could stop working if tee dies.

It could be modified to only capture the output from the previous command using preexec and precmd hooks in zsh, or an emulation of them in bash, but that's more complicated to describe here.

  • 6
    The basic idea is good, but the implementation is not. The standard output in the shell session is not a terminal but a pipe, which will cause some programs to behave differently. There will not be any synchronization between writes to stdout and writes to stderr or direct to the tty, so for example you might see command output displayed after the next prompt. You also haven't protected tee from signals (try pressing Ctrl+C and running a more few commands). Use the script utility which has none of these problems. Commented Mar 10, 2011 at 21:12
  • Good to know! I'm still working on my command line basics so this is possibly an overkill for me, plus I want to be able to use it on any computer, but I'll remember it if I ever reach a good level. Commented Mar 11, 2011 at 1:42

A working draft for a traditional shell:

ttyid=$(readlink /proc/$$/fd/1)
\___/   \______/ \___/ |  |  |
  |         |      |   |  |  \- 0: stdin 
  |         |      |   |  |     1: stdout <- our interest
  |         |      |   |  |     2: stderr
  |         |      |   |  \- fd is, maybe, filedescriptor
  |         |      |   |
  |         |      |   \- $$ is the PID of the current process (shell,
  |         |      |      in our case)
  |         |      |
  |         |      \- you know, much runtime stuff is here
  |         |
  |         \- readlink extracts the symbolic link of /proc/$$/fd/1
  |            lrwx------ 1 stefan stefan 64 2011-03-18 09:11
  |            /proc/22159/fd/1 -> /dev/pts/4
  \- /dev/tty3 for real shell, /dev/pts/3 for xterm

Now we can cat the screen to a file. Needs sudo.

sudo cat /dev/vcs$id > screen.dump

Apropos screendump: so named program doesn't work for me any more. Maybe for older kernels only. /dev/pts/N didn't work for me too. Maybe you have to some optional MKDEV in /dev - I remember darkly about some /dev/cuaN, but I may be wrong.

We would like to pipe the output instead of using screen.dump. But somehow it doesn't work - sometimes it waits for ENTER.

The capturing isn't a normal textfile with linefeeds, but with - for example - 80x50 chars in one sequence.

To pick the last 2 lines, 1 for the output of the command, and one for the prompting line, I revert it, pick 160 chars, revert again and pick 80.

rev vcs4.dat | sed 's/\(.\{160\}\).*/\1/g' | rev | sed 's/\(.\{80\}\).*/\1/g'

Just in case you ever wondered, why there is a rev program.


  • The first commands are entered, thus moving the line ahed. Well - just a numerical excercise to pick the 3rd-last line or something. I worked mainly in a different window.
  • Not everybody has a 80x50 screen. Well, yes, we know. There is $COLUMNS and $ROWS for your pleasure.
  • The output is not allways at the bottom. A fresh and young shell might be in the upper rows. Well - simple as that: Evaluate what shell is running. Which prompt is used. Do some prompt detection and find the last line with a shell-prompt. The line before (or 2. before) should contain the directory.

The first diagram is made with explain.py

  • +1, made me do alias tee2tty='tee $(readlink /proc/$$/fd/1)' Commented Mar 18, 2011 at 9:17

Try this:

$ cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
$ pwd

So, uh, here's an answer:

If you're running under X, select the output you want with the mouse to copy it, and then middle-click to paste it.

If you're running on a text console, you can do a similar thing with gpm.

  • 1
    +1 -- good answer! you could achieve the same thing, even if you're not running X, by using GNU screen (gnu.org/software/screen).
    – simon
    Commented Mar 11, 2011 at 1:15
  • 1
    It seemed so obvious that I was hesitant to say it. But everyone else is so busy being clever. :)
    – mattdm
    Commented Mar 11, 2011 at 15:25
  • it's the only answer here which allows the OP to reuse the last line -- everything else entails running the command again, which could be anywhere between utterly irrelevant and catastrophic :) But the OP did say reuse.
    – simon
    Commented Mar 11, 2011 at 15:47
  • @simon: Actually, my answer doesn't. Neither does glenn's.
    – Mikel
    Commented Mar 18, 2011 at 1:08
  • @Mikel: True, but they require you doing something beforehand, or correctly the first time.
    – mattdm
    Commented Mar 22, 2011 at 11:27

(It's not a working answer, unfortunately, but still something curious. Someone interested could well try to complete the implementation of the feature I'm going to tell you about.)

In eshell inside Emacs, they wanted to have such a feature but it's not implemented in a complete way (which is however reflected in the documentation).

For example:

~ $ pwd
~ $ /bin/echo $$
~ $ /bin/pwd
~ $ /bin/echo $$

~ $ 

You see, only the output of builtins can be captured into the $$ variable.

But well, some elisp programming (cf. eshell-mark-output implementation in "esh-mode.el"), and you could implement a function that "marks" the last output and returns it as the function's result; so that you can use that function in a eshell command you are asking for -- elisp functions can be used in eshell commands with the usual elisp syntax, i.e. in parentheses, like this:

~ $ /bin/echo (buffer-name)
~ $ /bin/echo (car '(a b c))
~ $ 

If you realize you're going to want to reuse the output before you hit Enter, you can save it in a variable: add tmp=$( at the beginning of the line and ) at the end. (This removes any blank line at the end of the command output, and in fact removes any final newline; this rarely matters.)

tmp=$(python -c …)
echo "$tmp"
cd "$tmp"

If your shell is ksh or zsh, here's a useful function you can use to make this more automatic. (It's no help in bash because it requires the last command in a pipeline to be executed in the parent shell, which is only the case in ksh (not pdksh) and zsh.)

keep () {
  local line IFS=$'\n'
  while read -r line; do
    printf '%s\n' "$line"
alias keep=k

Use it this way:

python -c … |k
cd $kept
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" | tee $(readlink /proc/$$/fd/1))

(building up on 4485's answer)

That's lots of typing, so make an alias:

alias tee2tty='tee $(readlink /proc/$$/fd/1)'

Then simply call cd $(python -c ... | tee2tty)

This of course requires you to already know what you want to do with the output but has the advantage of calling the command only once.

$ cd \`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"\`

will do the trick.

Read here for more details: Command substitution.


There is a better solution:

Just print !! after executed command and you will get repeated output.


enter image description here



  • !! doesn't repeat the outcome from the last command, it re-runs the last command. If jot -r 1 0 1000 returns a single random number between 0 and 1000, then after running that command once and getting 539, running !! will most likely give some other number. !! may also be undesirable if the previous command takes significant time to run, or repeats an operation that shouldn't be repeated (like changing a file).
    – Caleb
    Commented Jan 24, 2018 at 15:52
  • 1
    nice catch. Though there is an easier way to prove me wrong: echo $RANDOM; !!
    – Tebe
    Commented Jan 24, 2018 at 20:33
  • Sweet -- didn't know about that! Thanks.
    – Caleb
    Commented Jan 25, 2018 at 2:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .