Linux 使用Bash将最后一个命令的输出自动捕获到变量中?

Linux 使用Bash将最后一个命令的输出自动捕获到变量中?,linux,bash,command-line,Linux,Bash,Command Line,我希望能够在后续命令中使用最后执行的命令的结果。比如说, $ find . -name foo.txt ./home/user/some/directory/foo.txt 现在让我们假设我希望能够在编辑器中打开该文件,或者删除它,或者使用它执行其他操作,例如 mv <some-variable-that-contains-the-result> /some/new/location $保存上一个命令的最后一个参数。我想要一些类似的东西,但是有最后一个命令的输出 最终更新: 赛斯

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

$ find . -name foo.txt
./home/user/some/directory/foo.txt
现在让我们假设我希望能够在编辑器中打开该文件,或者删除它,或者使用它执行其他操作,例如

mv <some-variable-that-contains-the-result> /some/new/location
$保存上一个命令的最后一个参数。我想要一些类似的东西,但是有最后一个命令的输出

最终更新:

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

  • 第一次尝试解决方案时,不要忘记触摸/tmp/x
  • 仅当最后一个命令的退出代码成功时,才会存储结果

  • 这很容易。使用反引号:

    var=`find . -name foo.txt`
    
    然后你可以在将来的任何时候使用它

    echo $var
    mv $var /somewhere
    

    使用反勾号捕获输出:

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

    我不知道有哪个变量能自动做到这一点。除了复制粘贴结果外,您还可以重新运行刚才所做的任何操作,例如

    vim $(!!)
    
    其中
    是历史扩展,表示“上一个命令”


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

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

    v=$(date)
    echo $v
    
    你也可以使用反引号

    v=`date`
    echo $v
    

    当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后跟“$”、“`”或“\”。第一个反斜杠前面没有反斜杠的反斜杠终止命令替换。使用“$(命令)”表单时,括号之间的所有字符构成命令;没有人受到特殊对待


    编辑:在问题中编辑之后,似乎这不是OP想要的东西。据我所知,对于最后一个命令的输出,没有像
    $\ucode>这样的特殊变量。

    在执行命令并决定将结果存储在变量中后,这里有一种方法:

    $ find . -name foo.txt
    ./home/user/some/directory/foo.txt
    $ OUTPUT=`!!`
    $ echo $OUTPUT
    ./home/user/some/directory/foo.txt
    $ mv $OUTPUT somewhere/else/
    
    或者,如果您提前知道希望在变量中得到结果,则可以使用反勾号:

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

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

    MY_VAR="$(find -name foo.txt)"
    echo "$MY_VAR"
    
    但最好希望
    find
    只返回一个结果,并且该结果中没有任何“奇数”字符,如回车符或换行符,因为当将它们分配给Bash变量时,它们将被静默修改

    但在使用变量时,最好小心正确地引用它

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


    我通常按照这里其他人的建议做。。。未经转让:

    $find . -iname '*.cpp' -print
    ./foo.cpp
    ./bar.cpp
    $vi `!!`
    2 files to edit
    
    如果你喜欢,你可以变得更时尚:

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

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

    find . -name foo.txt | while IFS= read -r var; do
      echo "$var"
    done
    
    rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
    rasjani@helruo-dhcp022206::~/a/baz$ pwd
    /home/rasjani/a/baz
    rasjani@helruo-dhcp022206::~/a/baz$
    
    正如我所写的,只有在文件名中出现空格时,这种差异才有意义


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

    这是一个非常有技巧的解决方案,但似乎大部分时间都可以使用。在测试过程中,我注意到当在命令行上获得^C时,它有时不能很好地工作,尽管我确实对它进行了一些调整,使其表现得更好

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


    话虽如此,以下是“解决方案”:

    PROMPT_COMMAND='LAST=“`cat/tmp/x`”;exec>/dev/tty;exec>>(T/tmp/x)'
    
    设置此bash环境变量并根据需要发出命令
    $LAST
    通常会有您想要的输出:

    startide seth>fortune
    《婚姻的求爱》,作为一部非常乏味的戏剧的一个非常诙谐的开场白。
    --威廉·康格里夫
    星潮赛斯>回声“$LAST”
    《婚姻的求爱》,作为一部非常乏味的戏剧的一个非常诙谐的开场白。
    --威廉·康格里夫
    
    通过说“我希望能够在后续命令中使用最后执行的命令的结果”,我假定-您指的是任何命令的结果,而不仅仅是查找。

    如果是这样-xargs就是您要寻找的

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

    或者,如果您有兴趣首先查看输出:

    find-名称foo.txt-print0

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

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

    注意命令的mv{}/some/new/location/{}部分。此命令是为先前命令打印的每一行生成和执行的。在这里,先前命令打印的行被替换为{}

    摘自xargs手册页:

    xargs-从标准输入生成和执行命令行

    有关更多详细信息,请参见手册页:
    manxargs

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

    首先让我们看看文件夹“a”中有什么内容

    然后,使用ls和cd的示例将转换为sed&piping,如下所示:

    find . -name foo.txt | while IFS= read -r var; do
      echo "$var"
    done
    
    rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
    rasjani@helruo-dhcp022206::~/a/baz$ pwd
    /home/rasjani/a/baz
    rasjani@helruo-dhcp022206::~/a/baz$
    
    因此,sed的真正神奇之处在于,您将what-ever命令的what-ever输出导入sed和sed-prin
    find . -name foo.txt 1> tmpfile && mv `cat tmpfile` /path/to/some/dir/
    
    LAST=`!!`
    
    yourCommand $LAST
    
    find . | awk '{ print "FILE:" $0 }'
    
    find . -name "foo.txt" | awk '{ print "mv "$0" ~/bar/" | "sh" }'
    
    #!/bin/sh
    bash | tee /var/log/bash.out.log
    
    % find lots*of*files
    ...
    % echo "$(_)"
    ... # same output, but doesn't run the command again
    
    alias s='it=$($(history | tail -2 | head -1 | cut -d" " -f4-))'
    
    $ which python
    /usr/bin/python
    $ s
    $ file $it
    /usr/bin/python: symbolic link to `python2.6'
    
    grab() {     
      grab=$("$@")
      echo $grab
    }
    
    > grab date
    Do 16. Feb 13:05:04 CET 2012
    > echo $grab
    Do 16. Feb 13:05:04 CET 2012
    
    ~]$ 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
    
    $ which gradle 
    /usr/bin/gradle
    $ ls -alrt /usr/bin/gradle
    
    $ which gradle |: ls -altr {}
    
    $ alias :='xargs -I{}'
    
    $ cat shorttest.sh 
    #!/bin/bash
    shopt -s lastpipe
    
    exit_tests() {
        EXITMSG="$(cat /proc/self/fd/0)"
    }
    
    ls /bloop 2>&1 | exit_tests
    
    echo "My output is \"$EXITMSG\""
    
    
    $ bash shorttest.sh 
    My output is "ls: cannot access '/bloop': No such file or directory"
    
    shopt -s lastpipe
    
    exit_tests() {
        MYSTUFF="$(cat /proc/self/fd/0)"
        BADLINE=$BASH_LINENO
    }
    
    error_msg () {
        echo -e "$0: line $BADLINE\n\t $MYSTUFF"
        exit 1
    }
    
    ls /bloop 2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg