如何重用命令行的最后输出?

met*_*ion 46 command-line shell io-redirection

我想知道如何重用控制台的最后一个输出,即:

pv-3:method Xavier$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/Library/Python/2.6/site-packages
pv-3:method Xavier$ cd **LASTOUTPUT**
Run Code Online (Sandbox Code Playgroud)

jsb*_*ngs 41

假设 bash:

% python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.7/site-packages
% cd $(!!)
cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
% pwd
/usr/lib/python2.7/site-packages
Run Code Online (Sandbox Code Playgroud)

  • 请注意,请记住这是重新运行命令。如果您的命令有副作用,这可能对您不起作用。 (21认同)
  • +1 我一直想知道如何嵌套`\`反引号命令\`!`cd $(dirname $(which python))`我来了! (3认同)
  • 你也可以使用反引号(我不知道如何使这个界面不是 wikify)而不是 $(),但我发现按反引号-shift-1-shift-1-backtick 对我来说很不舒服,并且为了可读性,我试图养成尽可能使用 $() 的习惯。 (2认同)

gle*_*man 12

还没有提到,使用一个变量:

dir=$( python -c ... )
cd "$dir"
Run Code Online (Sandbox Code Playgroud)

  • 确切地。因为它是一个 shell,人们常常忘记 Bash 提供的语言特性,例如循环和赋值。 (3认同)
  • @Aerovistae,如果您不知道值的来源,则需要引号: (3认同)
  • 规范解释是 https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells (2认同)

Mik*_*kel 9

所有其他解决方案都涉及修改您的工作流程或两次运行命令,如果运行时间过长或不可重复(例如,它会删除文件 - 重新运行会产生不同的结果),则这可能不适合。

因此,如果您需要,这里有一个更复杂的想法:

.bashrc

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

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

trap 'rm ~/$$.out' EXIT
Run Code Online (Sandbox Code Playgroud)

bash 提示

$ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.6/dist-packages
$ cd $LASTLINE
$ pwd
/usr/lib/python2.6/dist-packages
Run Code Online (Sandbox Code Playgroud)

这有一些问题,所以它只是作为一个起点。例如,输出文件 ( ~/<pid>.out) 可能会变得非常大并填满您的磁盘。此外,如果tee死机,您的整个外壳可能会停止工作。

可以修改它以仅捕获使用zsh 中的preexecprecmd钩子的前一个命令的输出,或在 bash 中对它们的模拟,但这在此处描述更复杂。

  • 基本的想法是好的,但实施起来却不是。shell 会话中的标准输出不是终端而是管道,这会导致某些程序的行为不同。写入 stdout 和写入 stderr 或直接写入 tty 之间不会有任何同步,因此例如您可能会看到在下一个提示后显示的命令输出。您也没有保护 `tee` 免受信号影响(尝试按 `Ctrl+C` 并运行更多命令)。使用没有这些问题的 [`script`](http://www.freebsd.org/cgi/man.cgi?query=script) 实用程序。 (6认同)

use*_*own 8

传统 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
Run Code Online (Sandbox Code Playgroud)

现在我们可以将屏幕转换为文件。需要 sudo。

id=${ttyid//\/dev\/tty}
sudo cat /dev/vcs$id > screen.dump
Run Code Online (Sandbox Code Playgroud)

Apropos screendump:如此命名的程序不再适合我。也许仅适用于较旧的内核。/dev/pts/N 对我也不起作用。也许您必须在 /dev 中使用一些可选的 MKDEV - 我对 some 记忆犹新/dev/cuaN,但我可能错了。

我们希望通过管道输出而不是使用 screen.dump。但不知何故它不起作用 - 有时它会等待 ENTER。

捕获不是带有换行符的普通文本文件,而是带有 - 例如 - 一个序列中的 80x50 个字符。

要选择最后两行,其中 1 行用于命令输出,另一行用于提示行,我将其还原,选择 160 个字符,再次还原并选择 80。

rev vcs4.dat | sed 's/\(.\{160\}\).*/\1/g' | rev | sed 's/\(.\{80\}\).*/\1/g'
Run Code Online (Sandbox Code Playgroud)

以防万一你想知道为什么会有一个rev程序。

批判:

  • 输入了第一个命令,从而移动了行。好吧 - 只是一个数字练习来选择倒数第三行或其他东西。我主要在不同的窗口工作。
  • 不是每个人都有 80x50 的屏幕。嗯,是的,我们知道。有 $COLUMNS 和 $ROWS 供您使用。
  • 输出并不总是在底部。一个新鲜的和年轻的贝壳可能在上面的行中。嗯 - 就这么简单:评估正在运行的 shell。使用哪个提示。做一些提示检测并找到带有shell提示的最后一行。前(或 2. 前)行应包含目录。

第一张图是用explain.py制作的


bah*_*mat 7

尝试这个:

$ cd $(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
$ pwd
/Library/Python/2.6/site-packages
Run Code Online (Sandbox Code Playgroud)


mat*_*tdm 6

所以,呃,这是一个答案:

如果您在 X 下运行,请用鼠标选择您想要的输出进行复制,然后单击鼠标中键进行粘贴。

如果你在文本控制台上运行,你可以用gpm做类似的事情。