Can zsh access the stdout of last run program?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
9
down vote

favorite
5












I often use find or locate to find out about paths.



(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz


The next step is often to open or otherwise manipulate the files. In a happy case like above, I can do this:



(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz


But nobody's too happy when there are many lines of output, some of which may not be paths or something else of that kind. Besides, rerunning potentially wasteful commands is not that elegant either.



Would there be a way to hook up zsh to store the stdout into an array for later manipulation? After all, it's the shell's job to redirect the streams to the user. I'm thinking it could store the first N and last N lines in a variable for immediate later use, like $? and others.



Ok so this is pretty cool: https://unix.stackexchange.com/a/59704/5674. I'm now asking about the zsh know-how (and porting the code to zsh) to rig this kind of capture after each run line.










share|improve this question























  • It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
    – Stéphane Chazelas
    Feb 26 '14 at 14:22










  • @StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
    – progo
    Feb 26 '14 at 14:34










  • Yes, you could do it using screen or script and precmd and preexec hooks.
    – Stéphane Chazelas
    Feb 27 '14 at 10:09














up vote
9
down vote

favorite
5












I often use find or locate to find out about paths.



(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz


The next step is often to open or otherwise manipulate the files. In a happy case like above, I can do this:



(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz


But nobody's too happy when there are many lines of output, some of which may not be paths or something else of that kind. Besides, rerunning potentially wasteful commands is not that elegant either.



Would there be a way to hook up zsh to store the stdout into an array for later manipulation? After all, it's the shell's job to redirect the streams to the user. I'm thinking it could store the first N and last N lines in a variable for immediate later use, like $? and others.



Ok so this is pretty cool: https://unix.stackexchange.com/a/59704/5674. I'm now asking about the zsh know-how (and porting the code to zsh) to rig this kind of capture after each run line.










share|improve this question























  • It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
    – Stéphane Chazelas
    Feb 26 '14 at 14:22










  • @StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
    – progo
    Feb 26 '14 at 14:34










  • Yes, you could do it using screen or script and precmd and preexec hooks.
    – Stéphane Chazelas
    Feb 27 '14 at 10:09












up vote
9
down vote

favorite
5









up vote
9
down vote

favorite
5






5





I often use find or locate to find out about paths.



(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz


The next step is often to open or otherwise manipulate the files. In a happy case like above, I can do this:



(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz


But nobody's too happy when there are many lines of output, some of which may not be paths or something else of that kind. Besides, rerunning potentially wasteful commands is not that elegant either.



Would there be a way to hook up zsh to store the stdout into an array for later manipulation? After all, it's the shell's job to redirect the streams to the user. I'm thinking it could store the first N and last N lines in a variable for immediate later use, like $? and others.



Ok so this is pretty cool: https://unix.stackexchange.com/a/59704/5674. I'm now asking about the zsh know-how (and porting the code to zsh) to rig this kind of capture after each run line.










share|improve this question















I often use find or locate to find out about paths.



(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz


The next step is often to open or otherwise manipulate the files. In a happy case like above, I can do this:



(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz


But nobody's too happy when there are many lines of output, some of which may not be paths or something else of that kind. Besides, rerunning potentially wasteful commands is not that elegant either.



Would there be a way to hook up zsh to store the stdout into an array for later manipulation? After all, it's the shell's job to redirect the streams to the user. I'm thinking it could store the first N and last N lines in a variable for immediate later use, like $? and others.



Ok so this is pretty cool: https://unix.stackexchange.com/a/59704/5674. I'm now asking about the zsh know-how (and porting the code to zsh) to rig this kind of capture after each run line.







terminal zsh output






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 13 '17 at 12:37









Community♦

1




1










asked Feb 26 '14 at 13:46









progo

874712




874712











  • It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
    – Stéphane Chazelas
    Feb 26 '14 at 14:22










  • @StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
    – progo
    Feb 26 '14 at 14:34










  • Yes, you could do it using screen or script and precmd and preexec hooks.
    – Stéphane Chazelas
    Feb 27 '14 at 10:09
















  • It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
    – Stéphane Chazelas
    Feb 26 '14 at 14:22










  • @StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
    – progo
    Feb 26 '14 at 14:34










  • Yes, you could do it using screen or script and precmd and preexec hooks.
    – Stéphane Chazelas
    Feb 27 '14 at 10:09















It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
– Stéphane Chazelas
Feb 26 '14 at 14:22




It's not really the shell's job to redirect the stream to the user. The applications write their output to the terminal device, the shell is not involved in that.
– Stéphane Chazelas
Feb 26 '14 at 14:22












@StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
– progo
Feb 26 '14 at 14:34




@StephaneChazelas, but it is the shell's job to, say, redirect streams into files per user's requests. There are also recipes for zsh that color stderr in red to separate it from stdout. I think that indicates the shell's role in the streaming matters.
– progo
Feb 26 '14 at 14:34












Yes, you could do it using screen or script and precmd and preexec hooks.
– Stéphane Chazelas
Feb 27 '14 at 10:09




Yes, you could do it using screen or script and precmd and preexec hooks.
– Stéphane Chazelas
Feb 27 '14 at 10:09










4 Answers
4






active

oldest

votes

















up vote
3
down vote



accepted










There is no feature to capture the output from the screen on most terminal emulators. I seem to recall the author of xterm (the “reference” terminal emulator) stating that it would be difficult to implement. Even if that was possible, the shell would have to keep track of where the last prompt had been.



So you won't escape having to run the command again, unless you use a terminal-specific, manual mechanism such as copy-pasting with the mouse in xterm or with the keyboard in Screen.



It would be highly impractical for the shell to automatically capture the output of commands, because it cannot distinguish between commands that have complex terminal and user interactions from commands that simply output printable characters.



You can rerun the command and capture its output. There are various ways to do each. To rerun the command, you can use:




  • !! history substitution — most convenient to type;


  • fc -e -, which can be used in a function.

To capture the output, you can use command substitution, or a function like the following:



K () 
lines=("$(f@)$(cat)")

!! |K


This sets the lines array to the output of the command that's piped into it.






share|improve this answer




















  • So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
    – progo
    Feb 27 '14 at 8:52

















up vote
3
down vote













Here's a first cut of something to put the last line of output in a variable called $lastline.



precmd () 
exec 2>&- >&-
lastline=$(tail -1 ~/.command.out)
sleep 0.1 # TODO: synchronize better
exec > /dev/tty 2>&1


preexec()
exec > >(tee ~/.command.out&)



This uses zsh's preexec hook to run exec with tee to store a copy of the command's stdout, then uses precmd to read the stored output and restore stdout to be just the terminal for showing the prompt.



But it still needs some work. For example, since stdout is no longer a terminal, programs such as vim and less don't work properly.



There's some useful related information in these questions:



  • Can I configure my shell to print STDERR and STDOUT in different colors?

  • Show only stderr on screen but write both stdout and stderr to file





share|improve this answer






















  • Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
    – progo
    Feb 27 '14 at 8:48










  • exec without a program name just sets redirections.
    – Mikel
    Feb 27 '14 at 15:06

















up vote
1
down vote













You can do this by just piping your results to tee, which just saves the output to a file and displays it at the same time.



So for example, you could do this, which shows your output like normal, but also saves it to the file /tmp/it



locate foobar.mmpz | tee /tmp/it



then cat that file and grep it to select things, e.g.



cat /tmp/it | grep progo | grep lms



then to use it, you could just do this:



vi $(!!)






share|improve this answer



























    up vote
    0
    down vote













    I came up with this half-baked solution:



    alias -g ___='$"$(f@)$(eval "$(fc -ln -1)")": -1'


    This allows you to write ___ at any point in the command line. The previous command will be re-run and the ___ will be replaced with the last line of its output. Example usage:



    $ touch foo bar baz
    $ ls -1
    bar
    baz
    foo
    $ vim ___


    The last command will be expanded to vim foo.



    This does have some sharp edges! If you include ___ in a command but the previous command also included a ___, the shell will hang in some weird state for a while. (You can get out of this state immediately with Ctrl-C). You also can’t press Tab to expand the ___, like you can with !$ and other constructions. And of course, if you wanted to do something with an output line other than the last one, this won’t help you.



    (I picked the name ___ because it’s something I’ve never wanted to include as a word in a command line, not even as an argument. You could pick a different name, but take care not to choose something that might be expanded for you inadvertently.)





    share




















      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "106"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f117054%2fcan-zsh-access-the-stdout-of-last-run-program%23new-answer', 'question_page');

      );

      Post as a guest






























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      3
      down vote



      accepted










      There is no feature to capture the output from the screen on most terminal emulators. I seem to recall the author of xterm (the “reference” terminal emulator) stating that it would be difficult to implement. Even if that was possible, the shell would have to keep track of where the last prompt had been.



      So you won't escape having to run the command again, unless you use a terminal-specific, manual mechanism such as copy-pasting with the mouse in xterm or with the keyboard in Screen.



      It would be highly impractical for the shell to automatically capture the output of commands, because it cannot distinguish between commands that have complex terminal and user interactions from commands that simply output printable characters.



      You can rerun the command and capture its output. There are various ways to do each. To rerun the command, you can use:




      • !! history substitution — most convenient to type;


      • fc -e -, which can be used in a function.

      To capture the output, you can use command substitution, or a function like the following:



      K () 
      lines=("$(f@)$(cat)")

      !! |K


      This sets the lines array to the output of the command that's piped into it.






      share|improve this answer




















      • So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
        – progo
        Feb 27 '14 at 8:52














      up vote
      3
      down vote



      accepted










      There is no feature to capture the output from the screen on most terminal emulators. I seem to recall the author of xterm (the “reference” terminal emulator) stating that it would be difficult to implement. Even if that was possible, the shell would have to keep track of where the last prompt had been.



      So you won't escape having to run the command again, unless you use a terminal-specific, manual mechanism such as copy-pasting with the mouse in xterm or with the keyboard in Screen.



      It would be highly impractical for the shell to automatically capture the output of commands, because it cannot distinguish between commands that have complex terminal and user interactions from commands that simply output printable characters.



      You can rerun the command and capture its output. There are various ways to do each. To rerun the command, you can use:




      • !! history substitution — most convenient to type;


      • fc -e -, which can be used in a function.

      To capture the output, you can use command substitution, or a function like the following:



      K () 
      lines=("$(f@)$(cat)")

      !! |K


      This sets the lines array to the output of the command that's piped into it.






      share|improve this answer




















      • So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
        – progo
        Feb 27 '14 at 8:52












      up vote
      3
      down vote



      accepted







      up vote
      3
      down vote



      accepted






      There is no feature to capture the output from the screen on most terminal emulators. I seem to recall the author of xterm (the “reference” terminal emulator) stating that it would be difficult to implement. Even if that was possible, the shell would have to keep track of where the last prompt had been.



      So you won't escape having to run the command again, unless you use a terminal-specific, manual mechanism such as copy-pasting with the mouse in xterm or with the keyboard in Screen.



      It would be highly impractical for the shell to automatically capture the output of commands, because it cannot distinguish between commands that have complex terminal and user interactions from commands that simply output printable characters.



      You can rerun the command and capture its output. There are various ways to do each. To rerun the command, you can use:




      • !! history substitution — most convenient to type;


      • fc -e -, which can be used in a function.

      To capture the output, you can use command substitution, or a function like the following:



      K () 
      lines=("$(f@)$(cat)")

      !! |K


      This sets the lines array to the output of the command that's piped into it.






      share|improve this answer












      There is no feature to capture the output from the screen on most terminal emulators. I seem to recall the author of xterm (the “reference” terminal emulator) stating that it would be difficult to implement. Even if that was possible, the shell would have to keep track of where the last prompt had been.



      So you won't escape having to run the command again, unless you use a terminal-specific, manual mechanism such as copy-pasting with the mouse in xterm or with the keyboard in Screen.



      It would be highly impractical for the shell to automatically capture the output of commands, because it cannot distinguish between commands that have complex terminal and user interactions from commands that simply output printable characters.



      You can rerun the command and capture its output. There are various ways to do each. To rerun the command, you can use:




      • !! history substitution — most convenient to type;


      • fc -e -, which can be used in a function.

      To capture the output, you can use command substitution, or a function like the following:



      K () 
      lines=("$(f@)$(cat)")

      !! |K


      This sets the lines array to the output of the command that's piped into it.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Feb 27 '14 at 2:38









      Gilles

      518k12410341563




      518k12410341563











      • So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
        – progo
        Feb 27 '14 at 8:52
















      • So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
        – progo
        Feb 27 '14 at 8:52















      So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
      – progo
      Feb 27 '14 at 8:52




      So be it. I now realize in light of good explanations that a completely automatic approach is too difficult as is, the second best thing is something like that K of yours.
      – progo
      Feb 27 '14 at 8:52












      up vote
      3
      down vote













      Here's a first cut of something to put the last line of output in a variable called $lastline.



      precmd () 
      exec 2>&- >&-
      lastline=$(tail -1 ~/.command.out)
      sleep 0.1 # TODO: synchronize better
      exec > /dev/tty 2>&1


      preexec()
      exec > >(tee ~/.command.out&)



      This uses zsh's preexec hook to run exec with tee to store a copy of the command's stdout, then uses precmd to read the stored output and restore stdout to be just the terminal for showing the prompt.



      But it still needs some work. For example, since stdout is no longer a terminal, programs such as vim and less don't work properly.



      There's some useful related information in these questions:



      • Can I configure my shell to print STDERR and STDOUT in different colors?

      • Show only stderr on screen but write both stdout and stderr to file





      share|improve this answer






















      • Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
        – progo
        Feb 27 '14 at 8:48










      • exec without a program name just sets redirections.
        – Mikel
        Feb 27 '14 at 15:06














      up vote
      3
      down vote













      Here's a first cut of something to put the last line of output in a variable called $lastline.



      precmd () 
      exec 2>&- >&-
      lastline=$(tail -1 ~/.command.out)
      sleep 0.1 # TODO: synchronize better
      exec > /dev/tty 2>&1


      preexec()
      exec > >(tee ~/.command.out&)



      This uses zsh's preexec hook to run exec with tee to store a copy of the command's stdout, then uses precmd to read the stored output and restore stdout to be just the terminal for showing the prompt.



      But it still needs some work. For example, since stdout is no longer a terminal, programs such as vim and less don't work properly.



      There's some useful related information in these questions:



      • Can I configure my shell to print STDERR and STDOUT in different colors?

      • Show only stderr on screen but write both stdout and stderr to file





      share|improve this answer






















      • Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
        – progo
        Feb 27 '14 at 8:48










      • exec without a program name just sets redirections.
        – Mikel
        Feb 27 '14 at 15:06












      up vote
      3
      down vote










      up vote
      3
      down vote









      Here's a first cut of something to put the last line of output in a variable called $lastline.



      precmd () 
      exec 2>&- >&-
      lastline=$(tail -1 ~/.command.out)
      sleep 0.1 # TODO: synchronize better
      exec > /dev/tty 2>&1


      preexec()
      exec > >(tee ~/.command.out&)



      This uses zsh's preexec hook to run exec with tee to store a copy of the command's stdout, then uses precmd to read the stored output and restore stdout to be just the terminal for showing the prompt.



      But it still needs some work. For example, since stdout is no longer a terminal, programs such as vim and less don't work properly.



      There's some useful related information in these questions:



      • Can I configure my shell to print STDERR and STDOUT in different colors?

      • Show only stderr on screen but write both stdout and stderr to file





      share|improve this answer














      Here's a first cut of something to put the last line of output in a variable called $lastline.



      precmd () 
      exec 2>&- >&-
      lastline=$(tail -1 ~/.command.out)
      sleep 0.1 # TODO: synchronize better
      exec > /dev/tty 2>&1


      preexec()
      exec > >(tee ~/.command.out&)



      This uses zsh's preexec hook to run exec with tee to store a copy of the command's stdout, then uses precmd to read the stored output and restore stdout to be just the terminal for showing the prompt.



      But it still needs some work. For example, since stdout is no longer a terminal, programs such as vim and less don't work properly.



      There's some useful related information in these questions:



      • Can I configure my shell to print STDERR and STDOUT in different colors?

      • Show only stderr on screen but write both stdout and stderr to file






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Apr 13 '17 at 12:36









      Community♦

      1




      1










      answered Feb 26 '14 at 19:46









      Mikel

      38.4k997125




      38.4k997125











      • Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
        – progo
        Feb 27 '14 at 8:48










      • exec without a program name just sets redirections.
        – Mikel
        Feb 27 '14 at 15:06
















      • Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
        – progo
        Feb 27 '14 at 8:48










      • exec without a program name just sets redirections.
        – Mikel
        Feb 27 '14 at 15:06















      Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
      – progo
      Feb 27 '14 at 8:48




      Yes, perhaps a 100% automatic approach is not going to work. There are many exec calls in the code, is the command running multiple times or am I caught in special semantics?
      – progo
      Feb 27 '14 at 8:48












      exec without a program name just sets redirections.
      – Mikel
      Feb 27 '14 at 15:06




      exec without a program name just sets redirections.
      – Mikel
      Feb 27 '14 at 15:06










      up vote
      1
      down vote













      You can do this by just piping your results to tee, which just saves the output to a file and displays it at the same time.



      So for example, you could do this, which shows your output like normal, but also saves it to the file /tmp/it



      locate foobar.mmpz | tee /tmp/it



      then cat that file and grep it to select things, e.g.



      cat /tmp/it | grep progo | grep lms



      then to use it, you could just do this:



      vi $(!!)






      share|improve this answer
























        up vote
        1
        down vote













        You can do this by just piping your results to tee, which just saves the output to a file and displays it at the same time.



        So for example, you could do this, which shows your output like normal, but also saves it to the file /tmp/it



        locate foobar.mmpz | tee /tmp/it



        then cat that file and grep it to select things, e.g.



        cat /tmp/it | grep progo | grep lms



        then to use it, you could just do this:



        vi $(!!)






        share|improve this answer






















          up vote
          1
          down vote










          up vote
          1
          down vote









          You can do this by just piping your results to tee, which just saves the output to a file and displays it at the same time.



          So for example, you could do this, which shows your output like normal, but also saves it to the file /tmp/it



          locate foobar.mmpz | tee /tmp/it



          then cat that file and grep it to select things, e.g.



          cat /tmp/it | grep progo | grep lms



          then to use it, you could just do this:



          vi $(!!)






          share|improve this answer












          You can do this by just piping your results to tee, which just saves the output to a file and displays it at the same time.



          So for example, you could do this, which shows your output like normal, but also saves it to the file /tmp/it



          locate foobar.mmpz | tee /tmp/it



          then cat that file and grep it to select things, e.g.



          cat /tmp/it | grep progo | grep lms



          then to use it, you could just do this:



          vi $(!!)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 '17 at 13:07









          Brad Parks

          4101521




          4101521




















              up vote
              0
              down vote













              I came up with this half-baked solution:



              alias -g ___='$"$(f@)$(eval "$(fc -ln -1)")": -1'


              This allows you to write ___ at any point in the command line. The previous command will be re-run and the ___ will be replaced with the last line of its output. Example usage:



              $ touch foo bar baz
              $ ls -1
              bar
              baz
              foo
              $ vim ___


              The last command will be expanded to vim foo.



              This does have some sharp edges! If you include ___ in a command but the previous command also included a ___, the shell will hang in some weird state for a while. (You can get out of this state immediately with Ctrl-C). You also can’t press Tab to expand the ___, like you can with !$ and other constructions. And of course, if you wanted to do something with an output line other than the last one, this won’t help you.



              (I picked the name ___ because it’s something I’ve never wanted to include as a word in a command line, not even as an argument. You could pick a different name, but take care not to choose something that might be expanded for you inadvertently.)





              share
























                up vote
                0
                down vote













                I came up with this half-baked solution:



                alias -g ___='$"$(f@)$(eval "$(fc -ln -1)")": -1'


                This allows you to write ___ at any point in the command line. The previous command will be re-run and the ___ will be replaced with the last line of its output. Example usage:



                $ touch foo bar baz
                $ ls -1
                bar
                baz
                foo
                $ vim ___


                The last command will be expanded to vim foo.



                This does have some sharp edges! If you include ___ in a command but the previous command also included a ___, the shell will hang in some weird state for a while. (You can get out of this state immediately with Ctrl-C). You also can’t press Tab to expand the ___, like you can with !$ and other constructions. And of course, if you wanted to do something with an output line other than the last one, this won’t help you.



                (I picked the name ___ because it’s something I’ve never wanted to include as a word in a command line, not even as an argument. You could pick a different name, but take care not to choose something that might be expanded for you inadvertently.)





                share






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  I came up with this half-baked solution:



                  alias -g ___='$"$(f@)$(eval "$(fc -ln -1)")": -1'


                  This allows you to write ___ at any point in the command line. The previous command will be re-run and the ___ will be replaced with the last line of its output. Example usage:



                  $ touch foo bar baz
                  $ ls -1
                  bar
                  baz
                  foo
                  $ vim ___


                  The last command will be expanded to vim foo.



                  This does have some sharp edges! If you include ___ in a command but the previous command also included a ___, the shell will hang in some weird state for a while. (You can get out of this state immediately with Ctrl-C). You also can’t press Tab to expand the ___, like you can with !$ and other constructions. And of course, if you wanted to do something with an output line other than the last one, this won’t help you.



                  (I picked the name ___ because it’s something I’ve never wanted to include as a word in a command line, not even as an argument. You could pick a different name, but take care not to choose something that might be expanded for you inadvertently.)





                  share












                  I came up with this half-baked solution:



                  alias -g ___='$"$(f@)$(eval "$(fc -ln -1)")": -1'


                  This allows you to write ___ at any point in the command line. The previous command will be re-run and the ___ will be replaced with the last line of its output. Example usage:



                  $ touch foo bar baz
                  $ ls -1
                  bar
                  baz
                  foo
                  $ vim ___


                  The last command will be expanded to vim foo.



                  This does have some sharp edges! If you include ___ in a command but the previous command also included a ___, the shell will hang in some weird state for a while. (You can get out of this state immediately with Ctrl-C). You also can’t press Tab to expand the ___, like you can with !$ and other constructions. And of course, if you wanted to do something with an output line other than the last one, this won’t help you.



                  (I picked the name ___ because it’s something I’ve never wanted to include as a word in a command line, not even as an argument. You could pick a different name, but take care not to choose something that might be expanded for you inadvertently.)






                  share











                  share


                  share










                  answered 6 mins ago









                  bdesham

                  292212




                  292212



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f117054%2fcan-zsh-access-the-stdout-of-last-run-program%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay