bash——自动捕获最后执行的命令的输出到一个变量中

时间:2021-03-16 13:56:27

I'd like to be able to use the result of the last executed command in a subsequent command. For example,

我希望能够在后续命令中使用最后执行的命令的结果。例如,

$ find . -name foo.txt
./home/user/some/directory/foo.txt

Now let's say I want to be able to open the file in an editor, or delete it, or do something else with it, e.g.

现在假设我想要在编辑器中打开文件,或者删除它,或者用它做其他的事情,例如。

mv <some-variable-that-contains-the-result> /some/new/location

How can I do it? Maybe using some bash variable?

我怎么做呢?也许用了bash变量?

Update:

更新:

To clarify, I don't want to assign things manually. What I'm after is something like built-in bash variables, e.g.

为了澄清,我不想手工分配。我想要的是类似于内置bash变量的东西,例如。

ls /tmp
cd $_

$_ holds the last argument of the previous command. I want something similar, but with the output of the last command.

$_保存前一个命令的最后一个参数。我想要类似的东西,但是需要最后一个命令的输出。

Final update:

最后更新:

Seth's answer has worked quite well. Couple of things to bear in mind:

赛斯的回答非常有效。要记住以下几点:

  • don't forget to touch /tmp/x when trying the solution for the very first time
  • 第一次尝试解决方案时,不要忘记触摸/tmp/x
  • the result will only be stored if last command's exit code was successful
  • 只有在最后一个命令的退出代码成功时,才会存储结果

20 个解决方案

#1


65  

This is a really hacky solution, but it seems to mostly work some of the time. During testing, I noted it sometimes didn't work very well when getting a ^C on the command line, though I did tweak it a bit to behave a bit better.

这是一种非常陈腐的解决方案,但在某些时候,它似乎主要起作用。在测试过程中,我注意到它有时效果不是很好当^ C在命令行上,虽然我也调整一下表现得好一点。

This hack is an interactive mode hack only, and I am pretty confident that I would not recommend it to anyone. Background commands are likely to cause even less defined behavior than normal. The other answers are a better way of programmatically getting at results.

这是一个只有交互模式的黑客,我很有信心我不会向任何人推荐它。后台命令可能会导致更少的定义行为。其他的答案是通过编程获得结果的更好的方法。


That being said, here is the "solution":

也就是说,这里有一个“解决方案”:

PROMPT_COMMAND='LAST="`cat /tmp/x`"; exec >/dev/tty; exec > >(tee /tmp/x)'

Set this bash environmental variable and issues commands as desired. $LAST will usually have the output you are looking for:

设置此bash环境变量并按需要发出命令。$LAST通常会有您想要的输出:

startide seth> fortune
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve
startide seth> echo "$LAST"
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve

#2


84  

I don't know of any variable that does this automatically. To do something aside from just copy-pasting the result, you can re-run whatever you just did, eg

我不知道有哪个变量可以自动完成。为了做一些事情,除了复制粘贴结果,你可以重新运行你刚才做的任何事情。

vim $(!!)

Where !! is history expansion meaning 'the previous command'.

在哪里! !是“历史扩展”的意思。

If you expect there to be a single filename with spaces or other characters in it that might prevent proper argument parsing, quote the result (vim "$(!!)"). Leaving it unquoted will allow multiple files to be opened at once as long as they don't include spaces or other shell parsing tokens.

如果您期望有一个文件名中包含空格或其他字符,可能会阻止正确的参数解析,请引用结果(vim“$(!)”)。不使用引号将允许同时打开多个文件,只要它们不包含空格或其他shell解析令牌。

#3


20  

Bash is kind of an ugly language. Yes, you can assign the output to variable

Bash是一种丑陋的语言。是的,您可以将输出分配给变量

MY_VAR="$(find -name foo.txt)"
echo "$MY_VAR"

But better hope your hardest that find only returned one result and that that result didn't have any "odd" characters in it, like carriage returns or line feeds, as they will be silently modified when assigned to a Bash variable.

但是最好希望您的最困难的结果只返回一个结果,并且结果没有任何“奇数”字符,如回车或换行,因为它们将在分配给Bash变量时被静默地修改。

But better be careful to quote your variable correctly when using it!

但是最好在使用变量时正确引用它!

It's better to act on the file directly, e.g. with find's -execdir (consult the manual).

最好直接对文件进行操作,例如使用find的-execdir(请参阅手册)。

find -name foo.txt -execdir vim '{}' ';'

or

find -name foo.txt -execdir rename 's/\.txt$/.xml/' '{}' ';'

#4


12  

There are more than one ways to do this. One way is to use v=$(command) which will assign the output of command to v. For example:

有不止一种方法可以做到这一点。一种方法是使用v=$(命令)将命令的输出分配给v,例如:

v=$(date)
echo $v

And you can use backquotes too.

你也可以用回引号。

v=`date`
echo $v

From Bash Beginners Guide,

从Bash初学者指南,

When the old-style backquoted form of substitution is used, backslash retains its literal meaning except when followed by "$", "`", or "\". The first backticks not preceded by a backslash terminates the command substitution. When using the "$(COMMAND)" form, all characters between the parentheses make up the command; none are treated specially.

当使用老式的后引号形式的替换时,反斜杠保留了它的字面意思,除了后面跟着“$”、“'”或“\”。前面没有反斜杠的第一个反斜杠将终止命令替换。当使用“$(命令)”形式时,括号中的所有字符组成命令;没有特别的对待。

EDIT: After the edit in the question, it seems that this is not the thing that the OP is looking for. As far as I know, there is no special variable like $_ for the output of last command.

编辑:在这个问题的编辑之后,看起来这不是OP想要的东西。据我所知,最后一个命令的输出没有$_的特殊变量。

#5


9  

It's quite easy. Use back-quotes:

这很容易。使用单引号:

var=`find . -name foo.txt`

And then you can use that any time in the future

以后任何时候都可以用

echo $var
mv $var /somewhere

#6


9  

I think you might be able to hack out a solution that involves setting your shell to a script containing:

我认为你可以想出一个解决方案,把你的shell设置成一个包含以下内容的脚本:

#!/bin/sh
bash | tee /var/log/bash.out.log

Then if you set $PROMPT_COMMAND to output a delimiter, you can write a helper function (maybe called _) that gets you the last chunk of that log, so you can use it like:

然后,如果您设置$PROMPT_COMMAND来输出一个分隔符,您可以编写一个助手函数(可能称为_),它将获取该日志的最后一段,因此您可以使用它,比如:

% find lots*of*files
...
% echo "$(_)"
... # same output, but doesn't run the command again

#7


8  

Disclamers:

Disclamers:

  • This answer is late half a year :D
  • 答案是半年后:D。
  • I'm a heavy tmux user
  • 我是tmux的忠实用户
  • You have to run your shell in tmux for this to work
  • 你必须在tmux中运行shell才能让它工作

When running an interactive shell in tmux, you can easily access the data currently displayed on a terminal. Let's take a look at some interesting commands:

在tmux中运行交互式shell时,您可以轻松地访问当前在终端上显示的数据。让我们来看看一些有趣的命令:

  • tmux capture-pane: this one copies the displayed data to one of the tmux's internal buffers. It can copy the history that's currently not visible, but we're not interested in that now
  • tmux capturepane:将显示的数据复制到tmux的一个内部缓冲区。它可以复制当前不可见的历史,但我们现在对它不感兴趣。
  • tmux list-buffers: this displays the info about the captured buffers. The newest one will have the number 0.
  • tmux list-buffers:显示捕获的缓冲区的信息。最新的那个号码是0。
  • tmux show-buffer -b (buffer num): this prints the contents of the given buffer on a terminal
  • tmux显示-缓冲区-b(缓冲区num):这将在终端上打印给定缓冲区的内容
  • tmux paste-buffer -b (buffer num): this pastes the contents of the given buffer as input
  • tmux - paste-buffer -b (buffer num):将给定缓冲区的内容粘贴为输入

Yeah, this gives us a lot of possibilities now :) As for me, I set up a simple alias: alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1" and now every time I need to access the last line i simply use $(L) to get it.

是的,这给我们提供了很多可能性:)对于我来说,我设置了一个简单的别名:alias L="tmux捕获窗格;tmux showb - b0 | tail - n3 | head - n1 "现在每当我需要访问最后一行时,我就使用$(L)来获取它。

This is independent of the output stream the program uses (be it stdin or stderr), the printing method (ncurses, etc.) and the program's exit code - the data just needs to be displayed.

这与程序使用的输出流(无论是stdin还是stderr)、打印方法(ncurses,等等)和程序的退出代码无关——只需要显示数据。

#8


6  

You could set up the following alias in your bash profile:

您可以在bash配置文件中设置以下别名:

alias s='it=$($(history | tail -2 | head -1 | cut -d" " -f4-))'

Then, by typing 's' after an arbitrary command you can save the result to a shell variable 'it'.

然后,通过在任意命令后输入's',您可以将结果保存到shell变量'it'中。

So example usage would be:

例如用法是:

$ which python
/usr/bin/python
$ s
$ file $it
/usr/bin/python: symbolic link to `python2.6'

#9


6  

I just distilled this bash function from the suggestions here:

我刚刚从这里的建议中提炼出bash函数:

grab() {     
  grab=$("$@")
  echo $grab
}

Then, you just do:

然后,你做的事:

> grab date
Do 16. Feb 13:05:04 CET 2012
> echo $grab
Do 16. Feb 13:05:04 CET 2012

Update: an anonymous user suggested to replace echo by printf '%s\n' which has the advantage that it doesn't process options like -e in the grabbed text. So, if you expect or experience such peculiarities, consider this suggestion. Another option is to use cat <<<$grab instead.

更新:一个匿名用户建议用printf ' s\n替换echo,它的优点是不会处理抓取文本中的-e之类的选项。所以,如果你期望或体验到这样的特性,考虑一下这个建议。另一个选项是使用cat <<$grab。

#10


5  

Capture the output with backticks:

用回勾捕获输出:

output=`program arguments`
echo $output
emacs $output

#11


4  

I usually do what the others here have suggested ... without the assignment:

我通常按照这里其他人的建议去做……没有任务:

$find . -iname '*.cpp' -print
./foo.cpp
./bar.cpp
$vi `!!`
2 files to edit

You can get fancier if you like:

如果你喜欢,你可以变得更漂亮:

$grep -R "some variable" * | grep -v tags
./foo/bar/xxx
./bar/foo/yyy
$vi `!!`

#12


4  

By saying "I'd like to be able to use the result of the last executed command in a subsequent command", I assume - you mean the result of any command, not just find.

通过说“我希望能够在后续命令中使用最后执行的命令的结果”,我假设——您指的是任何命令的结果,而不仅仅是find。

If thats the case - xargs is what you are looking for.

如果是这样的话,xargs就是你要找的。

find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}

找到。- name foo。txt -print0 | xargs -0 -I{} {} {} /some/new/location/{}

OR if you are interested to see the output first:

或者如果你有兴趣先看看输出:

find . -name foo.txt -print0

找到。- name foo。txt -print0

!! | xargs -0 -I{} mv {} /some/new/location/{}

! !| xargs -0 -I{} {} {} /some/new/location/{}

This command deals with multiple files and works like a charm even if the path and/or filename contains space(s).

此命令处理多个文件,即使路径和/或文件名包含空格,也可以像魔咒一样工作。

Notice the mv {} /some/new/location/{} part of the command. This command is build and executed for each line printed by earlier command. Here the line printed by earlier command is replaced in place of {}.

注意命令的mv {} /some/new/location/{}部分。此命令将为前面命令打印的每一行构建并执行。在这里,用前面的命令打印的行被替换为{}。

Excerpt from man page of xargs:

摘自《xargs》手册:

xargs - build and execute command lines from standard input

xargs -从标准输入构建并执行命令行

For more detail see man page: man xargs

有关更多细节,请参见man页面:man xargs

#13


2  

If all you want is to rerun your last command and get the output, a simple bash variable would work:

如果您只想重新运行上一个命令并获得输出,那么一个简单的bash变量就可以工作:

LAST=`!!`

So then you can run your command on the output with:

因此,您可以在输出上运行命令:

yourCommand $LAST

This will spawn a new process and rerun your command, then give you the output. It sounds like what you would really like would be a bash history file for command output. This means you will need to capture the output that bash sends to your terminal. You could write something to watch the /dev or /proc necessary, but that's messy. You could also just create a "special pipe" between your term and bash with a tee command in the middle which redirects to your output file.

这将生成一个新进程并重新运行命令,然后给出输出。这听起来像是您真正想要的命令输出的bash历史文件。这意味着您需要捕获bash发送到终端的输出。你可以写一些东西来观察/dev或/proc的必要性,但这很麻烦。您还可以在您的术语和bash之间创建一个“特殊管道”,中间使用tee命令重定向到输出文件。

But both of those are kind of hacky solutions. I think the best thing would be terminator which is a more modern terminal with output logging. Just check your log file for the results of the last command. A bash variable similar to the above would make this even simpler.

但这两个都是一些陈腐的解决方案。我认为最好的是终结者,它是一个更现代的终端,输出日志。检查您的日志文件,查看最后一个命令的结果。类似于上面的bash变量将使这更简单。

#14


1  

Here's one way to do it after you've executed your command and decided that you want to store the result in a variable:

在执行命令并决定要将结果存储在一个变量之后,有一种方法:

$ find . -name foo.txt
./home/user/some/directory/foo.txt
$ OUTPUT=`!!`
$ echo $OUTPUT
./home/user/some/directory/foo.txt
$ mv $OUTPUT somewhere/else/

Or if you know ahead of time that you'll want the result in a variable, you can use backticks:

或者,如果你事先知道你想要一个变量的结果,你可以使用backtick:

$ OUTPUT=`find . -name foo.txt`
$ echo $OUTPUT
./home/user/some/directory/foo.txt

#15


1  

As an alternative to the existing answers: Use while if your file names can contain blank spaces like this:

作为对现有答案的替代选择:如果您的文件名可以包含如下空格,请使用:

find . -name foo.txt | while IFS= read -r var; do
  echo "$var"
done

As I wrote, the difference is only relevant if you have to expect blanks in the file names.

正如我所写的,只有在文件名中必须有空格的情况下,差异才有意义。

NB: the only built-in stuff is not about the output but about the status of the last command.

NB:唯一内置的东西不是关于输出,而是关于最后一个命令的状态。

#16


1  

you can use !!:1. Example:

您可以使用! !:1。例子:

~]$ ls *.~
class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 

~]$ rm !!:1
rm class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 


~]$ ls file_to_remove1 file_to_remove2
file_to_remove1 file_to_remove2

~]$ rm !!:1
rm file_to_remove1

~]$ rm !!:2
rm file_to_remove2

#17


1  

I had a similar need, in which I wanted to use the output of last command into the next one. Much like a | (pipe). eg

我有一个类似的需要,我想要在下一个命令中使用上一个命令的输出。很像|(管道)。如

$ which gradle 
/usr/bin/gradle
$ ls -alrt /usr/bin/gradle

to something like -

类似的,

$ which gradle |: ls -altr {}

Solution : Created this custom pipe. Really simple, using xargs -

解决方案:创建这个自定义管道。非常简单,使用xargs -

$ alias :='xargs -I{}'

Basically nothing by creating a short hand for xargs, it works like charm, and is really handy. I just add the alias in .bash_profile file.

基本上不需要为xargs创建一个简短的手,它像魅力一样工作,而且真的很方便。我只是在.bash_profile文件中添加了别名。

#18


0  

This is not strictly a bash solution but you can use piping with sed to get the last row of previous commands output.

严格来说,这并不是一个bash解决方案,但是您可以使用管道与sed来获取前面命令输出的最后一行。

First lets see what i have in folder "a"

首先让我们看看文件夹a里有什么

rasjani@helruo-dhcp022206::~$ find a
a
a/foo
a/bar
a/bat
a/baz
rasjani@helruo-dhcp022206::~$ 

Then, your example with ls and cd would turn to sed & piping into something like this:

然后,你关于ls和cd的例子就变成了sed & pipe这样的东西:

rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
rasjani@helruo-dhcp022206::~/a/baz$ pwd
/home/rasjani/a/baz
rasjani@helruo-dhcp022206::~/a/baz$

So, the actual magic happens with sed, you pipe what ever output of what ever command into sed and sed prints the last row which you can use as parameter with back ticks. Or you can combine that to xargs also. ("man xargs" in shell is your friend)

所以,对于sed来说,真正的神奇之处在于,您将曾经的命令输出导入到sed,然后sed打印出最后一行,您可以使用它作为参数,并使用回签。或者你也可以把它和xargs合并。(《壳牌》里的“男人xargs”是你的朋友)

#19


0  

The shell doesn't have perl-like special symbols that store the echo result of the last command.

shell没有类似perl的特殊符号来存储最后一个命令的回显结果。

Learn to use the pipe symbol with awk.

学习使用awk的管道符号。

find . | awk '{ print "FILE:" $0 }'

In the example above you could do:

在上面的示例中,您可以这样做:

find . -name "foo.txt" | awk '{ print "mv "$0" ~/bar/" | "sh" }'

#20


0  

find . -name foo.txt 1> tmpfile && mv `cat tmpfile` /path/to/some/dir/

is yet another way, albeit dirty.

这是另一种方式,尽管很脏。

#1


65  

This is a really hacky solution, but it seems to mostly work some of the time. During testing, I noted it sometimes didn't work very well when getting a ^C on the command line, though I did tweak it a bit to behave a bit better.

这是一种非常陈腐的解决方案,但在某些时候,它似乎主要起作用。在测试过程中,我注意到它有时效果不是很好当^ C在命令行上,虽然我也调整一下表现得好一点。

This hack is an interactive mode hack only, and I am pretty confident that I would not recommend it to anyone. Background commands are likely to cause even less defined behavior than normal. The other answers are a better way of programmatically getting at results.

这是一个只有交互模式的黑客,我很有信心我不会向任何人推荐它。后台命令可能会导致更少的定义行为。其他的答案是通过编程获得结果的更好的方法。


That being said, here is the "solution":

也就是说,这里有一个“解决方案”:

PROMPT_COMMAND='LAST="`cat /tmp/x`"; exec >/dev/tty; exec > >(tee /tmp/x)'

Set this bash environmental variable and issues commands as desired. $LAST will usually have the output you are looking for:

设置此bash环境变量并按需要发出命令。$LAST通常会有您想要的输出:

startide seth> fortune
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve
startide seth> echo "$LAST"
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve

#2


84  

I don't know of any variable that does this automatically. To do something aside from just copy-pasting the result, you can re-run whatever you just did, eg

我不知道有哪个变量可以自动完成。为了做一些事情,除了复制粘贴结果,你可以重新运行你刚才做的任何事情。

vim $(!!)

Where !! is history expansion meaning 'the previous command'.

在哪里! !是“历史扩展”的意思。

If you expect there to be a single filename with spaces or other characters in it that might prevent proper argument parsing, quote the result (vim "$(!!)"). Leaving it unquoted will allow multiple files to be opened at once as long as they don't include spaces or other shell parsing tokens.

如果您期望有一个文件名中包含空格或其他字符,可能会阻止正确的参数解析,请引用结果(vim“$(!)”)。不使用引号将允许同时打开多个文件,只要它们不包含空格或其他shell解析令牌。

#3


20  

Bash is kind of an ugly language. Yes, you can assign the output to variable

Bash是一种丑陋的语言。是的,您可以将输出分配给变量

MY_VAR="$(find -name foo.txt)"
echo "$MY_VAR"

But better hope your hardest that find only returned one result and that that result didn't have any "odd" characters in it, like carriage returns or line feeds, as they will be silently modified when assigned to a Bash variable.

但是最好希望您的最困难的结果只返回一个结果,并且结果没有任何“奇数”字符,如回车或换行,因为它们将在分配给Bash变量时被静默地修改。

But better be careful to quote your variable correctly when using it!

但是最好在使用变量时正确引用它!

It's better to act on the file directly, e.g. with find's -execdir (consult the manual).

最好直接对文件进行操作,例如使用find的-execdir(请参阅手册)。

find -name foo.txt -execdir vim '{}' ';'

or

find -name foo.txt -execdir rename 's/\.txt$/.xml/' '{}' ';'

#4


12  

There are more than one ways to do this. One way is to use v=$(command) which will assign the output of command to v. For example:

有不止一种方法可以做到这一点。一种方法是使用v=$(命令)将命令的输出分配给v,例如:

v=$(date)
echo $v

And you can use backquotes too.

你也可以用回引号。

v=`date`
echo $v

From Bash Beginners Guide,

从Bash初学者指南,

When the old-style backquoted form of substitution is used, backslash retains its literal meaning except when followed by "$", "`", or "\". The first backticks not preceded by a backslash terminates the command substitution. When using the "$(COMMAND)" form, all characters between the parentheses make up the command; none are treated specially.

当使用老式的后引号形式的替换时,反斜杠保留了它的字面意思,除了后面跟着“$”、“'”或“\”。前面没有反斜杠的第一个反斜杠将终止命令替换。当使用“$(命令)”形式时,括号中的所有字符组成命令;没有特别的对待。

EDIT: After the edit in the question, it seems that this is not the thing that the OP is looking for. As far as I know, there is no special variable like $_ for the output of last command.

编辑:在这个问题的编辑之后,看起来这不是OP想要的东西。据我所知,最后一个命令的输出没有$_的特殊变量。

#5


9  

It's quite easy. Use back-quotes:

这很容易。使用单引号:

var=`find . -name foo.txt`

And then you can use that any time in the future

以后任何时候都可以用

echo $var
mv $var /somewhere

#6


9  

I think you might be able to hack out a solution that involves setting your shell to a script containing:

我认为你可以想出一个解决方案,把你的shell设置成一个包含以下内容的脚本:

#!/bin/sh
bash | tee /var/log/bash.out.log

Then if you set $PROMPT_COMMAND to output a delimiter, you can write a helper function (maybe called _) that gets you the last chunk of that log, so you can use it like:

然后,如果您设置$PROMPT_COMMAND来输出一个分隔符,您可以编写一个助手函数(可能称为_),它将获取该日志的最后一段,因此您可以使用它,比如:

% find lots*of*files
...
% echo "$(_)"
... # same output, but doesn't run the command again

#7


8  

Disclamers:

Disclamers:

  • This answer is late half a year :D
  • 答案是半年后:D。
  • I'm a heavy tmux user
  • 我是tmux的忠实用户
  • You have to run your shell in tmux for this to work
  • 你必须在tmux中运行shell才能让它工作

When running an interactive shell in tmux, you can easily access the data currently displayed on a terminal. Let's take a look at some interesting commands:

在tmux中运行交互式shell时,您可以轻松地访问当前在终端上显示的数据。让我们来看看一些有趣的命令:

  • tmux capture-pane: this one copies the displayed data to one of the tmux's internal buffers. It can copy the history that's currently not visible, but we're not interested in that now
  • tmux capturepane:将显示的数据复制到tmux的一个内部缓冲区。它可以复制当前不可见的历史,但我们现在对它不感兴趣。
  • tmux list-buffers: this displays the info about the captured buffers. The newest one will have the number 0.
  • tmux list-buffers:显示捕获的缓冲区的信息。最新的那个号码是0。
  • tmux show-buffer -b (buffer num): this prints the contents of the given buffer on a terminal
  • tmux显示-缓冲区-b(缓冲区num):这将在终端上打印给定缓冲区的内容
  • tmux paste-buffer -b (buffer num): this pastes the contents of the given buffer as input
  • tmux - paste-buffer -b (buffer num):将给定缓冲区的内容粘贴为输入

Yeah, this gives us a lot of possibilities now :) As for me, I set up a simple alias: alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1" and now every time I need to access the last line i simply use $(L) to get it.

是的,这给我们提供了很多可能性:)对于我来说,我设置了一个简单的别名:alias L="tmux捕获窗格;tmux showb - b0 | tail - n3 | head - n1 "现在每当我需要访问最后一行时,我就使用$(L)来获取它。

This is independent of the output stream the program uses (be it stdin or stderr), the printing method (ncurses, etc.) and the program's exit code - the data just needs to be displayed.

这与程序使用的输出流(无论是stdin还是stderr)、打印方法(ncurses,等等)和程序的退出代码无关——只需要显示数据。

#8


6  

You could set up the following alias in your bash profile:

您可以在bash配置文件中设置以下别名:

alias s='it=$($(history | tail -2 | head -1 | cut -d" " -f4-))'

Then, by typing 's' after an arbitrary command you can save the result to a shell variable 'it'.

然后,通过在任意命令后输入's',您可以将结果保存到shell变量'it'中。

So example usage would be:

例如用法是:

$ which python
/usr/bin/python
$ s
$ file $it
/usr/bin/python: symbolic link to `python2.6'

#9


6  

I just distilled this bash function from the suggestions here:

我刚刚从这里的建议中提炼出bash函数:

grab() {     
  grab=$("$@")
  echo $grab
}

Then, you just do:

然后,你做的事:

> grab date
Do 16. Feb 13:05:04 CET 2012
> echo $grab
Do 16. Feb 13:05:04 CET 2012

Update: an anonymous user suggested to replace echo by printf '%s\n' which has the advantage that it doesn't process options like -e in the grabbed text. So, if you expect or experience such peculiarities, consider this suggestion. Another option is to use cat <<<$grab instead.

更新:一个匿名用户建议用printf ' s\n替换echo,它的优点是不会处理抓取文本中的-e之类的选项。所以,如果你期望或体验到这样的特性,考虑一下这个建议。另一个选项是使用cat <<$grab。

#10


5  

Capture the output with backticks:

用回勾捕获输出:

output=`program arguments`
echo $output
emacs $output

#11


4  

I usually do what the others here have suggested ... without the assignment:

我通常按照这里其他人的建议去做……没有任务:

$find . -iname '*.cpp' -print
./foo.cpp
./bar.cpp
$vi `!!`
2 files to edit

You can get fancier if you like:

如果你喜欢,你可以变得更漂亮:

$grep -R "some variable" * | grep -v tags
./foo/bar/xxx
./bar/foo/yyy
$vi `!!`

#12


4  

By saying "I'd like to be able to use the result of the last executed command in a subsequent command", I assume - you mean the result of any command, not just find.

通过说“我希望能够在后续命令中使用最后执行的命令的结果”,我假设——您指的是任何命令的结果,而不仅仅是find。

If thats the case - xargs is what you are looking for.

如果是这样的话,xargs就是你要找的。

find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}

找到。- name foo。txt -print0 | xargs -0 -I{} {} {} /some/new/location/{}

OR if you are interested to see the output first:

或者如果你有兴趣先看看输出:

find . -name foo.txt -print0

找到。- name foo。txt -print0

!! | xargs -0 -I{} mv {} /some/new/location/{}

! !| xargs -0 -I{} {} {} /some/new/location/{}

This command deals with multiple files and works like a charm even if the path and/or filename contains space(s).

此命令处理多个文件,即使路径和/或文件名包含空格,也可以像魔咒一样工作。

Notice the mv {} /some/new/location/{} part of the command. This command is build and executed for each line printed by earlier command. Here the line printed by earlier command is replaced in place of {}.

注意命令的mv {} /some/new/location/{}部分。此命令将为前面命令打印的每一行构建并执行。在这里,用前面的命令打印的行被替换为{}。

Excerpt from man page of xargs:

摘自《xargs》手册:

xargs - build and execute command lines from standard input

xargs -从标准输入构建并执行命令行

For more detail see man page: man xargs

有关更多细节,请参见man页面:man xargs

#13


2  

If all you want is to rerun your last command and get the output, a simple bash variable would work:

如果您只想重新运行上一个命令并获得输出,那么一个简单的bash变量就可以工作:

LAST=`!!`

So then you can run your command on the output with:

因此,您可以在输出上运行命令:

yourCommand $LAST

This will spawn a new process and rerun your command, then give you the output. It sounds like what you would really like would be a bash history file for command output. This means you will need to capture the output that bash sends to your terminal. You could write something to watch the /dev or /proc necessary, but that's messy. You could also just create a "special pipe" between your term and bash with a tee command in the middle which redirects to your output file.

这将生成一个新进程并重新运行命令,然后给出输出。这听起来像是您真正想要的命令输出的bash历史文件。这意味着您需要捕获bash发送到终端的输出。你可以写一些东西来观察/dev或/proc的必要性,但这很麻烦。您还可以在您的术语和bash之间创建一个“特殊管道”,中间使用tee命令重定向到输出文件。

But both of those are kind of hacky solutions. I think the best thing would be terminator which is a more modern terminal with output logging. Just check your log file for the results of the last command. A bash variable similar to the above would make this even simpler.

但这两个都是一些陈腐的解决方案。我认为最好的是终结者,它是一个更现代的终端,输出日志。检查您的日志文件,查看最后一个命令的结果。类似于上面的bash变量将使这更简单。

#14


1  

Here's one way to do it after you've executed your command and decided that you want to store the result in a variable:

在执行命令并决定要将结果存储在一个变量之后,有一种方法:

$ find . -name foo.txt
./home/user/some/directory/foo.txt
$ OUTPUT=`!!`
$ echo $OUTPUT
./home/user/some/directory/foo.txt
$ mv $OUTPUT somewhere/else/

Or if you know ahead of time that you'll want the result in a variable, you can use backticks:

或者,如果你事先知道你想要一个变量的结果,你可以使用backtick:

$ OUTPUT=`find . -name foo.txt`
$ echo $OUTPUT
./home/user/some/directory/foo.txt

#15


1  

As an alternative to the existing answers: Use while if your file names can contain blank spaces like this:

作为对现有答案的替代选择:如果您的文件名可以包含如下空格,请使用:

find . -name foo.txt | while IFS= read -r var; do
  echo "$var"
done

As I wrote, the difference is only relevant if you have to expect blanks in the file names.

正如我所写的,只有在文件名中必须有空格的情况下,差异才有意义。

NB: the only built-in stuff is not about the output but about the status of the last command.

NB:唯一内置的东西不是关于输出,而是关于最后一个命令的状态。

#16


1  

you can use !!:1. Example:

您可以使用! !:1。例子:

~]$ ls *.~
class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 

~]$ rm !!:1
rm class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 


~]$ ls file_to_remove1 file_to_remove2
file_to_remove1 file_to_remove2

~]$ rm !!:1
rm file_to_remove1

~]$ rm !!:2
rm file_to_remove2

#17


1  

I had a similar need, in which I wanted to use the output of last command into the next one. Much like a | (pipe). eg

我有一个类似的需要,我想要在下一个命令中使用上一个命令的输出。很像|(管道)。如

$ which gradle 
/usr/bin/gradle
$ ls -alrt /usr/bin/gradle

to something like -

类似的,

$ which gradle |: ls -altr {}

Solution : Created this custom pipe. Really simple, using xargs -

解决方案:创建这个自定义管道。非常简单,使用xargs -

$ alias :='xargs -I{}'

Basically nothing by creating a short hand for xargs, it works like charm, and is really handy. I just add the alias in .bash_profile file.

基本上不需要为xargs创建一个简短的手,它像魅力一样工作,而且真的很方便。我只是在.bash_profile文件中添加了别名。

#18


0  

This is not strictly a bash solution but you can use piping with sed to get the last row of previous commands output.

严格来说,这并不是一个bash解决方案,但是您可以使用管道与sed来获取前面命令输出的最后一行。

First lets see what i have in folder "a"

首先让我们看看文件夹a里有什么

rasjani@helruo-dhcp022206::~$ find a
a
a/foo
a/bar
a/bat
a/baz
rasjani@helruo-dhcp022206::~$ 

Then, your example with ls and cd would turn to sed & piping into something like this:

然后,你关于ls和cd的例子就变成了sed & pipe这样的东西:

rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
rasjani@helruo-dhcp022206::~/a/baz$ pwd
/home/rasjani/a/baz
rasjani@helruo-dhcp022206::~/a/baz$

So, the actual magic happens with sed, you pipe what ever output of what ever command into sed and sed prints the last row which you can use as parameter with back ticks. Or you can combine that to xargs also. ("man xargs" in shell is your friend)

所以,对于sed来说,真正的神奇之处在于,您将曾经的命令输出导入到sed,然后sed打印出最后一行,您可以使用它作为参数,并使用回签。或者你也可以把它和xargs合并。(《壳牌》里的“男人xargs”是你的朋友)

#19


0  

The shell doesn't have perl-like special symbols that store the echo result of the last command.

shell没有类似perl的特殊符号来存储最后一个命令的回显结果。

Learn to use the pipe symbol with awk.

学习使用awk的管道符号。

find . | awk '{ print "FILE:" $0 }'

In the example above you could do:

在上面的示例中,您可以这样做:

find . -name "foo.txt" | awk '{ print "mv "$0" ~/bar/" | "sh" }'

#20


0  

find . -name foo.txt 1> tmpfile && mv `cat tmpfile` /path/to/some/dir/

is yet another way, albeit dirty.

这是另一种方式,尽管很脏。