Here's how I'd do it:
- make your shell set the title to "bash" when at the prompt, and the name of the command when it runs a command, or anything so you can tell them apart
- create a script that calls
wmctrl to list open windows, then:
- if
wmctrl finds a window with a title of "bash", raise it
- else start an
xterm
- use
xbindkeys to call that script when you press your shortcut
making your shell set the window title when you run a command
Here's a simplified version of how I do it in bash. I haven't double checked the code, but it works on my machine.
# set the title when we run a command
setcommandhook()
{
if $has_debug_trap
then
trap 'command=$BASH_COMMAND; eval settitle "\"${title}\""; trap - DEBUG' DEBUG
fi
}
# set the xterm title
settitle()
{
printf "\033]0;$*\007"
}
promptstring='$(hostname):$(pwd)$ '
title='$(hostname) "${command:-$0}"'
# prompt and window title
if test -n "${title}"
then
PROMPT_COMMAND='command=; eval settitle "\"${title}\""'
if $has_debug_trap
then
PROMPT_COMMAND="$PROMPT_COMMAND; setcommandhook"
fi
fi
if test -n "${promptstring}"
then
PS1='$(eval echo -n "\"${promptstring}\"")'
fi
Doing it in zsh is easier, because it has the preexec hook.
You can see my shell configs for more details, e.g. the getcommand function which handles commands like fg in a nicer way.
raising the xterm that has a bash prompt otherwise starting a new one
Write a script that uses wmctrl -l to list windows, looking for one with bash in the title. If one is found, then run wmctrl -i -a <id returned by wmctrl -l> to raise it, else just call xterm.
Here is a script that does it:
#!/bin/bash
#
# bashprompt
#
# if there is an xterm open at a bash prompt, raise/focus that window
# if there isn't start a new xterm
#
# requires that your xterm window title has "bash" at the end
# when there is no command running and doesn't have "bash" at the end
# when a command is running
#
# see <http://unix.stackexchange.com/questions/6842> for more details
#
# Mikel Ward <mikel@mikelward.com>
# change this to whatever is unique about your window title
# (i.e. a string that appears in the title when the shell is at a prompt
# but does not appear when running a command)
prompttitle="bash$"
terminalprog="xterm"
if ! type wmctrl >/dev/null 2>&1; then
echo "wmctrl can't be found, please install it" 1>&2
exit 1
fi
if ! output="$(wmctrl -l)"; then
echo "Error running wmctrl -l" 1>&2
exit 1
fi
while IFS=$'\n' read -r line; do
if [[ $line =~ $prompttitle ]]; then
id=${line%% *}
break
fi
done <<EOF
$output
EOF
if test -n "$id"; then
wmctrl -i -a "$id"
else
"$terminalprog"&
fi
Or download it from my scripts repository.
running the script when you press Win+R
Assuming your script is called /usr/local/bin/bashprompt, make a file ~/.xbindkeysrc containing:
"/usr/local/bin/bashprompt"
Mod4 + r
then run xbindkeys. Add it to your .Xclients file or similar to make it start up automatically.
bash,zsh, or something else? – Mikel Feb 3 '11 at 7:49