You are not logged in.
Please note: bashrun is now hosted on sourceforge http://bashrun.sourceforge.net/. There is a package in the community repository.
The following information is outdated, it is kept here only to keep context for this thread.
This script will give you an xterm bash session for executing a just a single command, i.e. a nice application launcher featuring bash completion, history and all the other features you're used to from bash.
This basically works by running bash with the -t option in xterm and rebinding <Return> to mean " & \n" in .bashrunrc.
EDITED: - now HISTCONTROL works as advertised by bash(1)
- added example HISTCONTROL in .bashrunrc
- included example for urxvt
EDITED: - now self-contained, creates .bashrunrc if necessary
- added support for other terminals (see $XTERM in .bashrunrc)
screenshot:
bin/bashrun:
#!/bin/sh
#
# usage: bashrun [geometry] (default: 40x1)
#
# NOTE: commands entered will have an '&' appended before being run,
# so don't append it yourself, it will fail silently.
#
# rcfile: $HOME/.bashrunrc
#
# ---------------------------------------------------------------------
GEOM=${1:-40x1}
# create .bashrunrc unless present
BASHRUNRC=$HOME/.bashrunrc
if [ ! -f $BASHRUNRC ]; then
(
cat <<'EOF'
# which X terminal to use:
# (xterm|rxvt|urxvt|mrxvt|aterm|mlterm)
XTERM=xterm
# history file and options:
HISTFILE=$HOME/.bashrun_history
HISTCONTROL=ignoredups:erasedups
# bind <TAB> to menu-complete. Makes <TAB> cycle through completions on
# the current line instead of paging all possible completions
bind '"\t": menu-complete'
# bind <C-g> to send ^D
# (<C-g> is the default quit-chain-key in emacs, ratpoison, etc)
bind '"\C-g"':"\"\x04\""
# set a simple prompt
PS1=">"
# ***DO NOT EDIT BEYOND THIS LINE***
#
# bind ENTER to add ' &' to command
bind '"\x0d"':"\" &\n\""
EOF
) > $BASHRUNRC
fi
XTERM=xterm
. $BASHRUNRC
error() {
if [ `which zenity` ]; then
zenity --title bashrun --error --text "$@"
elif [ `which kdialog` ]; then
kdialog --title bashrun --error "$@"
elif [ `which xmessage` ]; then
xmessage "$@"
fi
echo -en "\007"
echo $@
}
# run bash terminal
if [ "$XTERM" == "xterm" ]; then
$XTERM -name 'bashrun' \
-title 'bashrun' \
-geometry $GEOM \
-e "/bin/bash --rcfile $BASHRUNRC -i -t"
elif [[ "$XTERM" == "aterm" || "$XTERM" == "mlterm" ]]; then
$XTERM -name 'bashrun' \
-title 'bashrun' \
-geometry $GEOM +sb \
-e /bin/bash --rcfile $BASHRUNRC -i -t
elif [[ "$XTERM" == "urxvt" || "$XTERM" == "rxvt" ]]; then
$XTERM -name 'bashrun' \
-title 'bashrun' \
-geometry $GEOM +sb\
-e sh -c "/bin/bash --rcfile $BASHRUNRC -i -t"
elif [ "$XTERM" == "mrxvt" ]; then
$XTERM -name 'bashrun' \
-title 'bashrun' \
-geometry $GEOM +sb -ht \
-e sh -c "/bin/bash --rcfile $BASHRUNRC -i -t"
else
error "$XTERM is not supported. Please check $BASHRUNRC"
exit 1
fi
# history cleanup...
# remove trailing whitespace and '&' from the last history line
tac $HISTFILE | sed "1s/\&//;s/ *$//" | tac > $HISTFILE
# HISTCONTROL won't work on its own because bash applies the
# 'ignoredups' and 'erasedups' rules to 'command &'.
# apply 'ignoredups' if set
if [[ "$HISTCONTROL" =~ "ignoredups" || "$HISTCONTROL" =~ "ignoreboth" ]]; then
uniq $HISTFILE $HISTFILE.tmp
mv $HISTFILE.tmp $HISTFILE
fi
# apply 'erasedups' if set
if [[ "$HISTCONTROL" =~ "erasedups" ]]; then
tac $HISTFILE | gawk '!x[$0]++' - | tac > $HISTFILE
fi
optionally, in .config/openbox/rc.xml <applications>, add
<application name="bashrun">
<decor>no</decor>
<focus>yes</focus>
<skip_pager>yes</skip_pager>
<layer>above</layer>
</application>
Have fun,
Henning
Last edited by hbekel (2009-03-06 23:13:05)
Offline
So simple, it's beautiful. I like this more than gmrun because I can't get gmrun to start from my home directory.
Last edited by MarCustomized (2008-10-04 16:58:30)
Offline
I can't get this working with urxvt. It opens, then closes instantly.
Offline
I can't get this working with urxvt. It opens, then closes instantly.
the -c switch is different for urxvt. Try
urxvt -name 'bashrun' \
-title 'bashrun' \
-geometry $GEOM \
-e sh -c "/bin/bash --rcfile $HOME/.bashrunrc -i -t"
and it should work.
Offline
Brilliant!
Offline
NOTE: I've just edited the original post make HISTCONTROL work with this script.
Offline
Can I convince you to set up a sourceforge (or other standard location) page for these scripts? I'd love to setup a package for AUR. I'm sure there are other users (especially of the various *box WMs) that would appreciate the simple elegance of this script.
Offline
I've accomplished the same thing in another way:
urxvt -T 'run' -geometry 50x1+0+1 -externalBorder 0 -internalBorder 0 &
~/.devilspie/run.ds:
( if
( and
( matches ( window_name ) "run" )
)
( begin
( pin )
( undecorate )
( skip_pager )
( skip_tasklist )
( wintype "utility" )
( stick )
)
)
This way the launcher seems integrated in conky:
http://hostopen.net/ubr_upload/2008-10- … _scrot.png
Offline
I've accomplished the same thing in another way:
urxvt -T 'run' -geometry 50x1+0+1 -externalBorder 0 -internalBorder 0 &
This doesn't exit immediately after sending the command into background, which was the point of my script...
Offline
dmz wrote:I've accomplished the same thing in another way:
urxvt -T 'run' -geometry 50x1+0+1 -externalBorder 0 -internalBorder 0 &
This doesn't exit immediately after sending the command into background, which was the point of my script...
What? The only reason it doesn't exit is because I dont want it to exit. Of course you could bind this to whatever you prefer.
Offline
hbekel wrote:dmz wrote:I've accomplished the same thing in another way:
urxvt -T 'run' -geometry 50x1+0+1 -externalBorder 0 -internalBorder 0 &
This doesn't exit immediately after sending the command into background, which was the point of my script...
What? The only reason it doesn't exit is because I dont want it to exit. Of course you could bind this to whatever you prefer.
I see, the "same thing" part refers only to sizing/wm handling...
Offline
Very cool idea.
For those, who use mrxvt:
mrxvt -name 'bashrun' -title 'bashrun' -geometry $GEOM -bl +sb -ht -e /bin/bash --rcfile $HOME/.bashrunrc -i -t
Add -bl +sb -ht to hide window decorations, scrollbar and tabbar.
Don't use quotation marks after -e.
Offline
Thanks frip
NOTE: I've updated the OP, including support for (xterm|rxvt|urxvt|mrxvt|aterm|mlterm). just set XTERM in .bashrunrc to choose your terminal.
Last edited by hbekel (2008-10-05 14:35:25)
Offline
Thanks frip
NOTE: I've updated the OP, including support for (xterm|rxvt|urxvt|mrxvt|aterm|mlterm). just set XTERM in .bashrunrc to choose your terminal.
Great work, thanks!
Changing the elif line for urxvt to something like this makes it possible to use "urxvtc" (urxvt in client mode):
elif [[ "$XTERM" == "urxvt" || "$XTERM" == "rxvt" || "$XTERM" == "urxvtc" ]]; then
Also, is there any way to make the bashrun window close with Esc key?
Offline
Great idea!
Too bad it's hard/impossible to control the window decoration etc from inside bashrun when using xterm. I want to achieve a look like on your screenshot, but it seems like I cannot tell xterm to have no window decorations. seems like I need to change that in my window manager/decorator. I'm using xfwm but I don't think I can do this. I'll probably start using compiz again later, which definitely can do it, but still it would be nice to be able to control it from the bashrun script.
xterm supports 'classes' but I haven't figured out yet what I can do with those.
< Daenyth> and he works prolifically
4 8 15 16 23 42
Offline
Great idea!
Too bad it's hard/impossible to control the window decoration etc from inside bashrun when using xterm. I want to achieve a look like on your screenshot, but it seems like I cannot tell xterm to have no window decorations. seems like I need to change that in my window manager/decorator. I'm using xfwm but I don't think I can do this. I'll probably start using compiz again later, which definitely can do it, but still it would be nice to be able to control it from the bashrun script.xterm supports 'classes' but I haven't figured out yet what I can do with those.
You could use devilspie. Maybe it could be bundled with the script somehow....
The day Microsoft makes a product that doesn't suck, is the day they make a vacuum cleaner.
--------------------------------------------------------------------------------------------------------------
But if they tell you that I've lost my mind, maybe it's not gone just a little hard to find...
Offline
When I start a process in the background of a normal shell/terminal, then close it, then that process also exits. What in this script prevents that? (I love the script, by the way. I tried writing something similar once but couldn't get around this problem.)
And how would I change your C-g shortcut to the escape key instead? I cannot for the life of me get an escape sequence that works.
Last edited by fflarex (2008-10-05 22:53:21)
Offline
When I start a process in the background of a normal shell/terminal, then close it, then that process also exits. What in this script prevents that? (I love the script, by the way. I tried writing something similar once but couldn't get around this problem.)
And how would I change your C-g shortcut to the escape key instead? I cannot for the life of me get an escape sequence that works.
The trick is to use the -t option of bash. The bash manpage simply reads " -t Exit after reading and executing one command." This seems to include detaching the process from bash if it is send into the background.
I'm not sure whether it is possible to bind the escape key in readline/bash at all -- I guess that's because it's a meta key. Not sure, though. I've tried to do it, but couldn't get it to work either...
Offline
Offline
It's possible to use xdotool (http://aur.archlinux.org/packages.php?ID=14789) to send arbitrary keystrokes to applications. If your windowmanager supports dynamic keybinding, you can use the following method to make bashrun exit via escape:
1. in your wm, bind <Escape> to escape.sh, which sends ctrl-c to bashrun
2. run bashrun
3. unbind <Escape> again
This is an example for openbox (be sure to backup your rc.xml):
bashrun-escape-sh:
#!/bin/sh
xmled -i add '//keyboard' ~/.config/openbox/rc.xml <<EOF
<keybind key="Escape">
<action name="Execute">
<command>escape.sh</command>
</action>
</keybind>
EOF
openbox --reconfigure
bashrun
xmled -i remove '//keybind[@key="Escape"]' ~/.config/openbox/rc.xml
openbox --reconfigure
escape.sh:
#!/bin/sh
WID=`xdotool search "bashrun" | head -1`
xdotool windowfocus $WID
xdotool key ctrl+c
xmled (ruby):
#!/usr/bin/env ruby
require "getoptlong"
require "rexml/document"
include REXML
$VERSION="0.1"
def usage
STDERR.puts <<EOF
xmled: modify xml documents
Usage: xmled [-i] <command> <xpath> <file> [<input>] [<output>]
-i, --inplace: write directly to <file>, ignore <output>
command: show|add|replace|remove
xpath : XPath expression to the target node
file : Xml file to be modified
input : String or file containing an xml document
Defaults to stdin.
output : output filename. Defaults to stdout.
Commands:
show <xpath> <file>
Print out xml matched by <xpath>
add <xpath> <file> <input>
adds the root node of the <input> document to the
target node specified by <xpath>
remove <xpath> <file>
removes the target node
replace <xpath> <file> <input>
replaces the target node with the root node of
the <input> document
EOF
exit 0
end
def error(msg, code=1)
STDERR.puts msg
exit code
end
inplace = false
opts = GetoptLong.new(
["--inplace", "-i", GetoptLong::NO_ARGUMENT],
["--help","-h", GetoptLong::NO_ARGUMENT],
["--version","-v", GetoptLong::NO_ARGUMENT]
)
opts.each do |opt, arg|
if opt == "--inplace"
inplace = true
end
if opt == "--help"
usage()
end
if opt == "--version"
error "xmled #{$VERSION}", 0
end
end
usage unless ARGV.size >= 2
(command, xpath, file, input, output) = ARGV
file = File.expand_path file if file
output = File.expand_path output if output
unless command =~ /show|add|replace|remove/
error "Unknown command: #{command}", 1
end
unless xpath
error "No XPath expression given."
end
begin
doc = Document.new File.new file
rescue Exception => e
error e.message
end
target = doc.elements[xpath]
unless target.is_a? Element
error "No match for '#{xpath}' in #{file}."
end
if command == "show"
puts target
exit
end
if not input
input = Document.new STDIN.read unless command == "remove"
elsif File.exists? File.expand_path(input)
input = Document.new File.new File.expand_path input
else
input = Document.new input
end
input = input.root if input
if command == "show"
puts target
exit
elsif command == "add"
target.add input
elsif command == "remove"
target.parent.delete_element target
elsif
command == "replace"
parent = target.parent
parent.delete_element target
parent.add input
end
if inplace
f = File.new(file, "w")
doc.write(f)
f.close
elsif output
f = File.new(output, "w")
else
puts doc
end
Last edited by hbekel (2008-10-08 00:48:47)
Offline
Offline
If I could just get this to run in Gnome without decor I would be laughing..... /me goes searching
Mr Green
Offline