bash_in_gnome_terminal(){ local IFS printf -v cmd %q ". ~/.bashrc; set -m; $*" gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)" } bash_in_gnome_terminal tail -f ~/.xsession-errors bash_in_gnome_terminal 'grep -r pattern dir | less'
This solution is complicated (and crippled!) by the fact that the gnome-terminal command actually calls into a "terminal server" to spawn a terminal instance, and you cannot pass file descriptors to the process running in it.
With other terminals like xterm or mlterm the solution is simpler and more functional:
bash_in_xterm(){ local IFS xterm -e bash --rcfile <(printf '. ~/.bashrc; set -m; %s\n' "$*") }
Also, it would be nice if bash had an option to run some commands before an interactive shell (like vi +'cmd'), without a kludge like --rcfile <(...). Maybe it even has -- but I wasn't able to figure it out ;-)
The set -m is needed because bash sources the initialization files with the monitor mode off, ie without job control and the possibility of using ^Z, fg, bg, etc.
If you want the shell to exit and the terminal to close when the started command has exited, the function could be modified like this [assumes a recent version of bash]:
bash_in_gnome_terminal(){ local IFS set -- 'j="\j";'sigchld(){ traplocal "j="\j"; ((\$${j@P})) || exit"exit; }; trap sigchld CHLD;' "$@" printf -v cmd %q ". ~/.bashrc; set -m; $*" gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)" }
The ${var@P} form expands any prompt escapes in var, and the \j prompt escape expands to the number of jobs. Thence j="\j"; ((${jc@Pj@P})) || exit as called from the CHLD trap will exit the shell if there are no more jobs.
This whole thing could be made into a standalone script instead of a function:
#! /bin/bash # uncomment and edit the following line accordingly # set -- <fixed command and arguments> "$@" set -- 'j="\j";'sigchld(){ traplocal "j="\j"; ((\$${j@P})) || exit"exit; }; trap sigchld CHLD;' "$@" printf -v cmd %q ". ~/.bashrc; set -m; $*" gnome-terminal -- bash -c "bash --rcfile <(echo $cmd)"