On Sun, Jul 24, 2011 at 12:35:19PM +0800, lolilolicon wrote: > dmenu_run doesn't really run the user input as a shell command line. > For instance, run dmenu_run from a terminal, then in the menu type: > > echo hello\ world > > The terminal output is "hello\ world" instead of "hello world". > > `eval' solves the problem, but when it comes to eval, I can't really > be sure, so please point out the possible errors/risks.
Assuredly the least of the evils in this script -- the eval is necessary. More noteworthy is the parsing of ls here, which can easily be refactored out and still be /bin/sh compat. It also explodes on first run, and then there's the needless invocation of mkdir every time the cache is regenerated. suckless could suck a lot less at shell scripting. dmenu_run has gone through several iterations of bad and worse. d #!/bin/sh CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run IFS=: LC_COLLLATE=C gencache() { lsx $PATH | sort -u >"$CACHE" } if [ ! -e "$CACHE" ]; then mkdir -p "${CACHE%/*}" gencache fi for path in $PATH; do if [ "$path" -nt "$CACHE" ]; then gencache break fi done unset IFS cmd=$(dmenu "$@" < "$CACHE") && eval exec "$cmd" > > `LC_ALL=C' is for sort. > > diff -up a/dmenu_run b/dmenu_run > --- a/dmenu_run 1970-01-01 00:00:00.000000000 +0000 > +++ b/dmenu_run 1970-01-01 00:00:00.000000000 +0000 > @@ -1,9 +1,9 @@ > #!/bin/sh > CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run > ( > - IFS=: > + IFS=: LC_ALL=C > if test "`ls -dt $PATH "$CACHE" 2> /dev/null | sed 1q`" != "$CACHE"; > then > mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE" > fi > ) > -cmd=`dmenu "$@" < "$CACHE"` && exec $cmd > +cmd=`dmenu "$@" < "$CACHE"` && eval exec "$cmd" >