25

To keep the overview I like to place multiple commands always in the same order and start them automatically together (gradle, git, database, scala-REPL, jboss...)

-H (hold) seems to mean that the terminal isn't closed after termination, but how do I terminate such a process willfully? Not at all? In such a way that I can continue to use the terminal.

I'm using xubuntu with with xfce4-terminal and bash. Is there a better GUI-solution to startup multiple commands, with the ability to continue working in that window/tab?

Update: If you don't know these commands: Jboss and gradle are continously producing output, which you don't want to have intermixed in the same terminal. And sometimes they need to be interrupted with ^C, and restarted. I don't like to reopen an xfce4-term and navigate to the directory I need to act in.

Database and scala-REPL are interactive so there is no sense in starting them in the background.

My current startup-script just navigates to the desired directories, and opens all tabs in the right order to find them always at the same position, naming every tab for its purpose:

xfce4-terminal -T eclipse   --working-directory=/home/stefan/oximity -e "/opt/eclipse/eclipse" \
    --tab -T arandr --working-directory=/home/stefan/oximity -e "arandr /home/stefan/.screenlayout/oximity.sh" \
    --tab -T bash       --working-directory=/home/stefan/oximity \
    --tab -T gradle     --working-directory=/home/stefan/oximity/med \
    --tab -T git        --working-directory=/home/stefan/oximity/med \
    --tab -T mysql      --working-directory=/opt/mini/mysql \
    --tab -T jboss      --working-directory=/opt/mini/jboss \
    --tab -T jboss-log  --working-directory=/opt/mini/jboss/standalone/log \
    --tab -T scala-REPL --working-directory=/home/stefan/proj/mini/forum -e /opt/scala/bin/scala

Eclipse and arandr are detached from the shell and run in their own window, so there the -e (execute) param works. I think for the scala-REPL it works since it is the last command in the list.

user unknown
  • 10,482
  • Your question is still unclear to me. You want a terminal to revert to shell once the command it was started with terminates? Something like xterm -e 'stuff;bash'? – frostschutz May 25 '13 at 09:48
  • 1
    This question still needs work! I found this thread, I think this is what the OP is looking for: How to keep xfce4-terminal open?. He wants to know how to access a tab where the "-H" switch has been used and continue to use it as a normal terminal window. OP, can you please confirm if I'm correct? – slm May 25 '13 at 12:54
  • @slm: Yes, I like to keep the terminal open to process further commands - I just like to start the first of my commands automatically and have multiple, named tabs. – user unknown May 25 '13 at 13:03

4 Answers4

24

The -H/-hold option is to keep the terminal emulator Window open once the applications started in it (shell or other) has exited. In that state, nothing more can happen.

If you want to start a command as a job of an interactive shell in the xfce4-terminal terminal emulator and keep the shell running and use it interactively after the application has exited, with bash, you can make use of the $PROMPT_COMMAND environment variable, to have xfce-terminal start an interactive shell that starts the given command just before the first prompt.

xfce4-terminal \
  -T eclipse \
  --working-directory=/home/stefan/oximity \
  -e 'env PROMPT_COMMAND="unset PROMPT_COMMAND; /opt/eclipse/eclipse" bash' \
  \
  --tab -T arandr \
  --working-directory=/home/stefan/oximity \
  -e 'env PROMPT_COMMAND="unset PROMPT_COMMAND; arandr /home/stefan/.screenlayout/oximity.sh" bash' \
  \
  --tab -T bash \
  --working-directory=/home/stefan/oximity \
  ...

That way, the commands are jobs of that shell which means you can suspend them with Ctrl-Z and resume them later with fg/bg as if you had entered them at the prompt of that interactive shell.

That assumes though that you don't set the $PROMPT_COMMAND in your ~/.bashrc. Also note that the exit status of the command will not be available in $?.

To make it even more like the command was entered at the shell prompt you can even add it to the history list. Like:

xfce4-terminal -T /etc/motd -e 'env PROMPT_COMMAND="
  unset PROMPT_COMMAND
  history -s vi\ /etc/motd
  vi /etc/motd" bash'

That way, once you exit vi, you can press the Up key to recall that same vi command.

An easier way to write it:

PROMPT_COMMAND='unset PROMPT_COMMAND; history -s "$CMD"; eval "$CMD"' \
  xfce4-terminal --disable-server \
          -T /etc/motd -e 'env CMD="vi /etc/motd" bash' \
    --tab -T       top -e 'env CMD=top bash'

The:

xfce4-terminal -e 'sh -c "cmd; exec bash"'

solution as given in other answers works but has some drawbacks:

  1. If you press Ctrl-C while cmd is running, that kills the outer sh since there's only one process group for both sh and cmd.
  2. You can't use Ctrl-Z to suspend cmd
  3. Like in the $PROMPT_COMMAND approach, the exit status of the command will not be available in $?.

You can work around 1 above by doing:

xfce4-terminal -e 'sh -c "trap : INT; cmd; exec bash"'

Or:

xfce4-terminal -e 'sh -ic "cmd; exec bash"'

With that latter one, you'll also be able to suspend the process with Ctrl-Z, but you won't be able to use fg/bg on it. You'll be able to continue it in background though by doing a kill -s CONT on the pid of cmd.

  • Wow. That is pretty complicated, but it seems to work. :) I don't know why the reward vanished. Unfortuantely I hadn't time before to test the hints. – user unknown Jun 02 '13 at 21:52
  • I don't really understand all rules of the bounty system. Since I think you deserve the bounty, I restart a new bounty. – user unknown Jun 02 '13 at 21:59
  • Yeah the bounties expire after 7 days, and you have 24 hours afterwards to award them. If you don't aware them they get assigned to whatever user has the highest rep (2 or higher). Here's more than you ever wanted to know about bounties 8-): http://meta.stackexchange.com/questions/16065/how-does-the-bounty-system-work – slm Jun 02 '13 at 22:25
  • Good answer as always @StephaneChazelas. Nice trick w/ the trap and -i switch. – slm Jun 02 '13 at 22:30
  • I spent hours searching for how to do this (on any terminal emulator) and gave up. I just started using xfce4-terminal and stumbled on this Q&A while looking for something else. This would be worth a "terminal-emulator-agnostic" blog post. (Obviously the CLI examples would have to be specific.) – crantok Aug 26 '16 at 07:18
  • PROMPT_COMMAND seems to be specific to bash. Any way to make this work with zsh? – friederbluemle Mar 27 '17 at 04:20
  • The command 'history -s text' is not recorded when you run it from a bash script. Probably for security reasons. – Adrian Lopez Aug 25 '17 at 13:31
  • 1
    @AdrianLopez, in bash scripts, there's no history at all as there's no line editing or user interaction unless you use read -e in your script (and you'll see that history -s text works there to prime the history seen by that read -e). Here, we're not running history -s from a script, but from the $PROMPT_COMMAND hook of an interactive shell. – Stéphane Chazelas Aug 25 '17 at 13:42
  • 1
    @StéphaneChazelas Amazing. Following your other valuable answer here, I must add that xfce4-terminal as at least of version 0.6.3 now wants an extra parameter -- --disable-server -- to pass through environment. Ref: https://lists.debian.org/debian-user/2017/10/msg00045.html . – ジョージ Dec 11 '18 at 11:14
5

As far as I understood your question, you want to run some processes in a terminal, being able to Ctrl+C them and, after that, keep the window open, with the shell.

If I am right, this could be accomplished with a command like this:

xfce4-terminal -e "bash -c 'COMMAND; exec bash'"
Anthon
  • 79,293
  • Does it work with multiple tabs? – user unknown May 27 '13 at 06:50
  • @userunknown Sure. Just add --tab before the other commands. For example, if you wanted to run "ls /etc" and "ls /dev", you would issue:

    xfce4-terminal -e "bash -c 'ls /etc; exec bash'" --tab -e "bash -c 'ls /dev; exec bash'"

    If you use Gnome Terminal, you have to write --tab also before the first command.

    – Rafael Cavalcanti May 27 '13 at 08:00
  • This is a little helpful, while not as far as I hoped for. When I start gradle with xfce4-terminal --working-directory=/home/stefan/oximity/med -e "bash -c 'gradle explodedWar explodedWarSync;bash'" \ a tab is opened, named but it shows "gradle: command not found" while entering the command there works fine. Git, mysql and scala work fine that way, but for jboss, Ctrl-C terminates the whole jboss-tab. I could only prepare the shell starting there - maybe echoing the command to input. I don't really understand what's making the differences here. – user unknown Jun 02 '13 at 21:11
1

multiple apps in xfce4-terminal tabs

Adding an interactive shell to each xfce tab

You can use this hack to add a shell if/when you Ctrl+C a tab:

$ xfce4-terminal -H \
     --tab -T bash -e "bash -c 'top;bash'" \
     --tab -T git  -e "bash -c 'top;bash'"

This will give you the following:

   ss of xfce w/ tabs

   ss of xfce w/ top Ctrl+C

slm
  • 369,824
0

When exiting the shell without -H the terminal will be closed, too. With this flag the terminal will keep running, but the shell process is closed and cannot be revived.

I think you are trying to archieve that you just start your terminal and your development environment starts up?

You may create a shell script and put all your commands inside it. At the end of the script you just start your shell:

#!/bin/sh

gradle &
git &
... &
.... &
jboss &

$SHELL

# some cleanup commands if needed

Then call this script via xfce4-terminal -e /the/script. When quitting from $SHELL the parent process (your script) finished and the background tasks will receive the exit signal and quit, too.

If you want to keep them alive, use e.g. nohup jboss & in your script

krissi
  • 553
  • That doesn't work because gradle and jboss are permanently producing output. You don't like to have them mix up their output. The database- and scala-terminal are interactive. There is no sense in putting them into the background. The idea to open other commands in different tabs is, that the history is only filled with few different commands to one topic and therefore fast browsable. – user unknown May 25 '13 at 08:07