Main Terminal Window Displaying Commands Only
Solution 1:
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 functionfoo
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 …
– runxterm
, 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 offoo
= the full chain of commands afterfoo
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.