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. Mar 10 '11 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
    Mar 10 '11 at 20:26
  • @Gilles -- unless you use @mattdm's answer, of course!
    – simon
    Mar 11 '11 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... Mar 16 '11 at 1:09
  • 1
    possible duplicate of Using text from previous commands' output Mar 21 '11 at 21:34

11 Answers 11


Assuming bash:

% 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. Mar 11 '11 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
    Mar 11 '11 at 13:40
  • @jsbillings see my answer below. I typed \` to display ` in the answer. And to display '\', as usual type '\\'.
    – yasouser
    Mar 11 '11 at 16:27
  • 3
    +1 I've been wondering how to nest `backtick-commands`! cd $(dirname $(which python))here I come!
    – Ed Brannin
    Mar 11 '11 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. Mar 16 '11 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
    Mar 11 '11 at 1:09
  • can just say cd $dir Jan 26 '15 at 0:10
  • 3
    @Aerovistae, the quotes are required if you don't know where the value comes from: Jan 26 '15 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
    Jan 7 '16 at 18:57
  • 2
    The canonical explanation is unix.stackexchange.com/questions/171346/… Jan 7 '16 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. Mar 10 '11 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. Mar 11 '11 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)' Mar 18 '11 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
    Mar 11 '11 at 1:15
  • 1
    It seemed so obvious that I was hesitant to say it. But everyone else is so busy being clever. :)
    – mattdm
    Mar 11 '11 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
    Mar 11 '11 at 15:47
  • @simon: Actually, my answer doesn't. Neither does glenn's.
    – Mikel
    Mar 18 '11 at 1:08
  • @Mikel: True, but they require you doing something beforehand, or correctly the first time.
    – mattdm
    Mar 22 '11 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
    Jan 24 '18 at 15:52
  • 1
    nice catch. Though there is an easier way to prove me wrong: echo $RANDOM; !!
    – Tebe
    Jan 24 '18 at 20:33
  • Sweet -- didn't know about that! Thanks.
    – Caleb
    Jan 25 '18 at 2:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.