在 Bash 中重用上一个命令的输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24283097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reusing output from last command in Bash
提问by memecs
Is the output of a Bash command stored in any register? E.g. something similar to $?
capturing the output instead of the exit status.
Bash 命令的输出是否存储在任何寄存器中?例如类似于$?
捕获输出而不是退出状态的东西。
I could assign the output to a variable with:
我可以将输出分配给一个变量:
output=$(command)
but that's more typing...
但这更多的是打字...
回答by ling
You can use $(!!)
to recompute(not re-use) the output of the last command.
您可以使用$(!!)
来重新计算(不可重复使用)的最后一个命令的输出。
The !!
on its own executes the last command.
在!!
自身执行的最后一个命令。
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
回答by konsolebox
The answer is no. Bash doesn't allocate any output to any parameter or any block on its memory. Also, you are only allowed to access Bash by its allowed interface operations. Bash's private data is not accessible unless you hack it.
答案是不。Bash 不会将任何输出分配给其内存中的任何参数或任何块。此外,您只能通过其允许的接口操作来访问 Bash。除非你破解它,否则无法访问 Bash 的私人数据。
回答by anubhava
One way of doing that is by using trap DEBUG
:
一种方法是使用trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Now most recently executed command's stdout and stderr will be available in /tmp/out.log
现在最近执行的命令的 stdout 和 stderr 将在 /tmp/out.log
Only downside is that it will execute a command twice: once to redirect output and error to /tmp/out.log
and once normally. Probably there is some way to prevent this behavior as well.
唯一的缺点是它会执行一个命令两次:一次重定向输出和错误/tmp/out.log
,一次正常。可能还有一些方法可以防止这种行为。
回答by Raghu Dodda
If you are on mac, and don't mind storing your output in the clipboard instead of writing to a variable, you can use pbcopy and pbpaste as a workaround.
如果您使用的是 mac,并且不介意将输出存储在剪贴板而不是写入变量,则可以使用 pbcopy 和 pbpaste 作为解决方法。
For example, instead of doing this to find a file and diff its contents with another file:
例如,不是这样做来查找文件并将其内容与另一个文件进行比较:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
You could do this:
你可以这样做:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
The string /var/bar/app/one.php
is in the clipboard when you run the first command.
/var/bar/app/one.php
当您运行第一个命令时,该字符串位于剪贴板中。
By the way, pbin pbcopy
and pbpaste
stand for pasteboard, a synonym for clipboard.
顺便说一句,PB在pbcopy
与pbpaste
立场纸板,剪贴板的代名词。
回答by olivecoder
Inspired by anubhava's answer, which I think is not actually acceptable as it runs each command twice.
受到 anubhava 的回答的启发,我认为这实际上是不可接受的,因为它每个命令运行两次。
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
This way the output of last command is in /tmp/last and the command is not called twice.
这样,最后一个命令的输出在 /tmp/last 中,并且该命令不会被调用两次。
回答by phil294
Like konsolebox said, you'd have to hack into bash itself. Hereis a quite good example on how one might achieve this. The stderred repository (actually meant for coloring stdout) gives instructions on how to build it.
就像 konsolebox 所说的那样,您必须侵入 bash 本身。这是一个很好的例子,说明如何实现这一目标。stderred 存储库(实际上用于为标准输出着色)给出了如何构建它的说明。
I gave it a try: Defining some new file descriptor inside .bashrc
like
我试了一下:Defining some new file descriptor inside .bashrc
like
exec 41>/tmp/my_console_log
(number is arbitrary) and modify stderred.c
accordingly so that content also gets written to fd 41. It kind ofworked, but contains loads of NUL bytes, weird formattings and is basically binary data, not readable. Maybe someone with good understandings of C could try that out.
(数字是任意的)并相应地修改stderred.c
以便内容也被写入 fd 41。它有点工作,但包含大量的 NUL 字节,奇怪的格式,基本上是二进制数据,不可读。也许对 C 有很好理解的人可以尝试一下。
If so, everything needed to get the last printed line is tail -n 1 [logfile]
.
如果是这样,获得最后一行打印所需的一切都是tail -n 1 [logfile]
.
回答by William Navarre
I have an idea that I don't have time to try to implement immediately.
我有一个想法,我没有时间尝试立即实施。
But what if you do something like the following:
但是,如果您执行以下操作,该怎么办:
$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!
There might be issues with IO buffering. Also the file might get too huge. One would have to come up with a solution to these problems.
IO 缓冲可能存在问题。此外,文件可能会变得太大。人们必须想出解决这些问题的办法。
回答by the sudhakar
I think using script command might help. Something like,
我认为使用脚本命令可能会有所帮助。就像是,
script -c bash -qf fifo_pid
Using bash features to set after parsing.
脚本 -c bash -qf fifo_pid
使用 bash 功能在解析后进行设置。
回答by Connor
Simple enough:
足够简单:
Script (add to .bashrc or .bash_profile)
脚本(添加到 .bashrc 或 .bash_profile)
# capture the output of a command so it can be retrieved with ret
cap () { tee /tmp/capture.out}
# return the output of the most recent command that was captured by cap
ret () { cat /tmp/capture.out }
Usage
用法
$ find . -name 'filename' | cap
/path/to/filename
$ ret
/path/to/filename
I tend to add | cap
to the end of all of my commands. This way when I find I want to do text processing on the output of a slow running command I can always retrieve it with res
.
我倾向于添加| cap
到我所有命令的末尾。这样,当我发现我想对运行缓慢的命令的输出进行文本处理时,我总是可以使用res
.
回答by Giuliano
If you don't want to recompute the previous command you can create a macro that scans the current terminal buffer, tries to guess the -supposed- output of the last command, copies it to the clipboard and finally types it to the terminal.
如果您不想重新计算前一个命令,您可以创建一个宏来扫描当前终端缓冲区,尝试猜测最后一个命令的 -supposed- 输出,将其复制到剪贴板,最后将其输入到终端。
It can be used for simple commands that return a single line of output (tested on Ubuntu 18.04 with gnome-terminal
).
它可用于返回单行输出的简单命令(在 Ubuntu 18.04 上使用 测试gnome-terminal
)。
Install the following tools: xdootool
, xclip
, ruby
安装以下工具:xdootool
, xclip
,ruby
In gnome-terminal
go to Preferences -> Shortcuts -> Select all
and set it to Ctrl+shift+a
.
在gnome-terminal
转到Preferences -> Shortcuts -> Select all
并将其设置为Ctrl+shift+a
.
Create the following ruby script:
创建以下 ruby 脚本:
cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while { |item| item == "" }
g = f.drop_while { |item| item.start_with? "${USER}@" }
h = g[0]
print h
EOF
In the keyboard settings add the following keyboard shortcut:
在键盘设置中添加以下键盘快捷键:
bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '
bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '
The above shortcut:
上面的快捷方式:
- copies the current terminal buffer to the clipboard
- extracts the output of the last command (only one line)
- types it into the current terminal
- 将当前终端缓冲区复制到剪贴板
- 提取最后一个命令的输出(只有一行)
- 将其输入到当前终端