1

I often lose track of the command flow due to the long text output of some commands, so I would like to have a main terminal window where user commands are executed and other terminal windows that „pop up“ displaying the commands' output and then are closed with the use of a short-cut.

Is it possible to code such a behavior? Any tips about the language I should use?

An even more user-friendly interaction would be for the terminal to ask whether it should display the output externally if it exceeds a user-set limit.

  • 1
    The easiest way might be to pipe the output into less, i.e. type MYCOMMAND | less if you run a command from which you expect long output. That way the output will be visible in a scrollable pager which you exit by pressing the Q key. Once you exit less, you're back to the shell and it will look like there was no output at all. It all happens in the same terminal though, no separate windows. – Byte Commander Sep 8 '17 at 20:31
7

I know little about programming languages, but Bash can definitely set up to behave like you want it, so here's how I would do it.

General Setup

Define a function in your ~/.bash_aliases or ~/.bashrc file that allows you to start your command in a new terminal, e.g.

foo () { ( xterm -hold -e bash -c "$*" & ) ;}

This way foo echo bar opens up a new xterm which shows just the output of echo bar, here this would be a window with just the word bar in it. A chain of commands must be quoted, e.g. foo "echo bar && echo baz". You can substitute xterm by the terminal emulator of your choice, but you need to figure out what the stay open option is – read the man page. Option -e should work for all of them. Note that as a function name you can choose even a single symbol like :, _ or · (AltR+,).

Explanations

  • foo () { … ;} – define a function foo which does
  • ( … ) – start in a subshell, this releases the original terminal so that a new command can be executed even when other output terminals are still open
  • xterm -hold -e … – run xterm, run and -hold it open after the command finished
  • bash -c " … " – execute the command(s) , needed for being able to run multiple commands
  • $* – matches every argument of foo = the full chain of commands after foo

Fine-tuning

Closing the output terminal window

You can close the output terminal using your desktop environment's standard shortcut for that – Alt+F4 by default.

If you want the output terminal to stay open for let's say five seconds after the command finished, you need to define the function like so:

foo () { ( xterm -e bash -c "$* && sleep 5" & ) ;}

Replace && by & for the terminal to stay open only until the command is finished, but at least five seconds.

Input facilitation

Using xdotool (ugly and dirty, boo)

It'll bother you to type foo before every single command in your main terminal, so I set up a dirty workaround for that – install xdotool first if necessary. When you open your main terminal, first set this variable:

PROMPT_COMMAND='xdotool type "foo "'

This will automatically type foo followed by a space after, but unfortunately also before every new prompt. All left for you to do is to type your (chain of) command(s).

Using a perl function (massively cool)

The question how to perform the following was asked on Unix.SE and got a brilliant answer by Stéphane Chazelas, whose solution is used here. If this helps you in any way please visit the linked question and upvote his answer.

Add the following lines to your ~/.bashrc file and save it:

insert() { perl -le 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@" ;}
auto_enter() { bind $'"\u200b":"\1'$1' \5"'; PROMPT_COMMAND="insert $'\u200b'" ;}

Now when you open a new terminal and run auto_enter foo, the string “foo ” (with the space automatically added) will appear after every new prompt. If you type something while a command is executed, “foo ” is going to be inserted even before this text.

User-friendly interaction

This version of the function saves the output in a temp file, counts its lines and asks the user whether to display it in a new window:

foo () {
  limit=10 # set line limit
  tf=$(mktemp) # create temp file
  "$@" > $tf # execute command, save output in temp file
  lc=$(wc -l < $tf) # get output's line count
  [ $lc -ge $limit ] && # if line count >= limit then
  ( read -p "The output is $lc lines long, do you want to open it in a new window (y/n)? " yn
    case $yn in
        [Yy]* ) xterm -hold -e "cat $tf" & exit;; # open in new window, send to background and exit
        [Nn]* ) cat $tf; exit;; # print output to stdout and exit
        * ) echo "Please answer yes or no.";; # wrong answer
    esac ) || # else
  cat $tf # print output to stdout
}

Of course this can be highly tweaked and customized, but I think it's a good start.

And Now for Something Completely Different™

A totally different way of achieving your goal is using shell output redirection. who gives you a list of running terminals, e.g.:

> who
username tty7         2017-09-07 20:46 (:0)
username pts/2        2017-09-07 20:47 (:0)
username pts/1        2017-09-07 21:05 (:0)

You can send the output to any of them by simply appending e.g. > /dev/pts/1 to your command, which of course can also be used in a function as shown above.

GNOME Terminal emulator (gnome-terminal) sessions are not displayed by who, nonetheless the pts devices exist equally for them. You can determine open terminal sessions just by trying or with ls /dev/pts | sed '/^[0p]/d' instead.

  • No matter how many new terminals I open, who gives me only username tty7 – Sandro Sivsivadzé Sep 8 '17 at 21:09
  • 1
    I use the GNOME Terminal emulator. Installed by default on my Ubuntu. – Sandro Sivsivadzé Sep 8 '17 at 21:39
  • 1
    It works with xterm. I get the running terminals list after who. – Sandro Sivsivadzé Sep 8 '17 at 21:42
  • 3
    You don't know how much I enjoyed working this out… – dessert Sep 8 '17 at 23:05
  • 1
    @dessert - very cool tip, thanks! Works very well with terminals where you can have a split screen, like KDE's Konsole: img.ctrlv.in/img/17/09/09/59b3e80a09d1f.png – Andy Turfer Sep 9 '17 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.