Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 837

Answer by Kamil Maciorowski for How to refer to the output of a command as an argument in the next command in Bash shell?

$
0
0

$_ works because the shell knows the previous command. In general the shell does not know the output from an external command; the shell is not a relay for output, the executable prints to the tty directly.

You need either to plan ahead and capture or pipe the output in the first place, or to get the output back from your terminal (terminal emulator, terminal multiplexer). Copying and pasting is one way to do the latter. An example of another way is below.

The following quick and dirty solution works reasonably well in bash 5.2.37 in tmux 3.5a.

# in bash_paste_last_output() {local outputoutput="$(tmux capture-pane -pJ | grep -v '^$' | grep -v '^kamil@.*:.*$ ' | tail -n 1)"output="${output@Q}"READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}${output}${READLINE_LINE:$READLINE_POINT:${#READLINE_LINE}}";READLINE_POINT="$((READLINE_POINT+${#output}))"}bind -x '"\C-x\C-v":_paste_last_output'

The function gets the visible contents of the tmux pane, filters out empty lines and lines most likely starting with a prompt (important:^kamil@.*:.*$ matches my prompt, adjust the pattern to your needs), finally it picks the last line.

Activate the function with Ctrl+x,Ctrl+v while typing a command (like your vim -R ). The function will paste the line it picked and it will quote it properly.

Notes:

  1. grep -v '^kamil@.*:.*$ ' filters out lines with my prompt; adjust the pattern to your prompt.

  2. The function processes the visible content of the tmux pane. Use tmux capture-pane -pJ -S - -E - to process everything tmux remembers.

  3. The function may pick a wrong line if you trigger it when:

    • multi-line command is being typed;
    • multi-line command has been cancelled (and thus it looks like output);
    • multi-line command has been executed and printed nothing;
    • the last command has printed an error or a warning (so it looks like output);
    • the last command has printed an incomplete line (so it merges with the prompt);
    • a background job has printed or is printing to the terminal and interferes.

    The list is not exhaustive.

  4. What the function pastes may be distorted if:

    • the picked line contained tab(s) (there will be spaces now);
    • the picked line contained non-printable character(s).

    The list is not exhaustive

Basically the whole procedure is just automated copy-and-paste. The function gets data from the terminal, applies simple heuristics for choosing what to copy, finally it "pastes" in a somewhat improved way.

For choosing what to copy, a better solution would be to use OSC 133 markers designed to be boundaries between prompt, command, its output; but tmux capture-pane -pJ does not preserve them, even with -e, even with -eC.

An even better solution would be to implement support for these markers in tmux, so tmux itself could give you the n-th to last output on demand. (It would be what tmux got between the n-th to last FTCS_COMMAND_EXECUTED and the first FTCS_COMMAND_FINISHED that followed. Error messages would still count as output though.)


Viewing all articles
Browse latest Browse all 837

Trending Articles