Tiny Core Linux
General TC => Programming & Scripting - Unofficial => Topic started by: althalus on July 16, 2010, 12:20:29 AM
-
So ondemand is nice, but it still requires interaction with the mouse, and I can type firefox far faster than I can identify it in a list. Since I already mostly use either dmenu or tablaunch for launching apps, I wrote the following simple little wrapper for dmenu that I set up on a hotkey to quickly and easily load extensions with just a couple of keystrokes. (shouldn't need to say that it requires dmenu.tcz loaded)
#!/bin/sh
cd `cat /opt/.tce_dir`/optional
tcz=`ls *.tcz | dmenu -p "load extension: "` && exec tce-load -i $tcz
Mayhap anyone else using dmenu will find it useful.
-
I'm using a slightly less simple script which makes dmenu show a list of extensions and indicate which ones are already loaded.
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1
TCZS="$(ls -1 /etc/sysconfig/tcedir/optional/*.tcz 2>/dev/null | sed 's:^/etc/sysconfig/tcedir/optional/::g;s/.tcz$//g' | sort -f)"
INSTALLED="$(for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
tce-load -i $(echo "$TCZS" | dmenu -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &
The only issue I have is that this loop is relatively slow.
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
It can take a few seconds to complete depending on how many extensions are available.
Would be great if anyone could think of a faster way.
-
INSTALLED="$[for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
This loop is unnecessary. The shell will break them the same way either way, so just use INSTALLED="/usr/local/tce.installed/*".
String operations and forks are in general slow. You might be able to replace the echo/sed pair with the shell's string replacement operator, but if that's still too slow, the approach needs rethinking.
-
The loop for the INSTALLED variable was a workaround as I couldn't get the subsequent loop to succeed without sed complaining about "bad option in substitution expression". Maybe sed doesn't like the path containing a dot.
Still, your suggestion to remove that loop led to some simplification. It now cd into respective directories like the OPs script does.
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1
cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
tce-load -i $(echo "$TCZS" | dmenu -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &
-
You might be able to replace the echo/sed pair with the shell's string replacement operator
In case you meant something like this
for i in * ; do TCZS="${TCZS//$i/:: $i}" ; done
it's either incredibly slow so that I loose the patients to wait for it to finish, or I'm doing something wrong.
-
Yes, I meant that, perhaps it is that slow in bb ash.
You can always write it in C++ and have it done in O(log n) time ;)
-
So, not being smart enough to write proper shell scripts means one has to learn C++. q:
BTW, the script currently looks like this, showing an extra dmenu while generating the list of tczs to prevent confusion.
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1
cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
echo "Building menu..." | dmenu -b -w 300 -h 300 -y 19 -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000' >/dev/null 2>&1 &
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
killall dmenu
tce-load -i $(echo "$TCZS" | dmenu -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &
Having 517 tczs on 7.x it takes about one second on my netbook. My 6.x install has 1139 tczs.
I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.
-
I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.
" just can't find" probably " have not yet found" ;)
Maby awk can replace tha strings ? at least i hear its good for those sorts of things !
-
Yeah, thanks for the suggestion. I'm trying all day using awk which I'm not good at. I try to improve this scripts speed from time to time whenever the delay bugs me too much. I keep reading the same search results on the web about awk though. Maybe because I don't how to search for what I don't understand. Doh.
-
I sure that both awk and sed are as slow as Molasses :o
for speed, I'd use
for f in *.tcz; do echo "${f%%.*}"; done
which is faster and better that using ls
-
Thanks. Applied with a small adjustment to not mess up filenames containing dots (f.e. Xorg-7.7.tcz).
TCZS="$(for f in *.tcz; do echo "${f%%.tcz}" ; done | sort -f)"
-
Oh well in that case you should take the shortest pattern from the end of $var (use one % instead of %%)
for f in *.tcz; do echo "${f%.*}"; done
:p
-
I always forget that syntax. o.O
-
Thanks coreplayer2. Your suggestion to use a loop for the tczs got me thinking - Why not reusing that loop.
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1
PROMPT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: ${f%.*}" || echo "${f%.*}" ; done | sort -f)"
TCZ="$(echo "$TCZS" | dmenu -i -xs -c -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ"
This makes code execution almost instantaneously!
As it is right now, the only problem is the sort part. I can't get it to ignore the leading ":: " .
-
Yay! found a way I'm quite happy with. Thanks everyone!
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1
PROMPT="*.tcz"
OPTS="-i -xs -c -b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo " ${f%.*}" || echo "${f%.*}" ; done | sort -bf | sed 's/ /:: /')"
TCZ="$(echo "$TCZS" | dmenu -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ" &
time dmenu-tce-load
real 0m 0.04s
user 0m 0.03s
sys 0m 0.02s
-
Hmmm
well this works for me so I think you can ditch the ugly sed :p
for f in /usr/local/tce.installed/* ; do echo ":: ${f##*/}"; done | sort -bf
:: squashfs-tools
:: sstrip
:: submitqc
:: ttf-bitstream-vera
:: udev-extra
:: udev-lib
:: usbutils
:: wbar
:: wget
:: xdg-utils
:: Xlibs
:: Xorg-7.7-lib
:: Xprogs
:: Xvesa
:: xzgv
:: zsync
Which I think is the objective..?
-
Thanks but nope. The main objective is to show a list of loadable extensions to choose from. In addition, instead of leaving out those already loaded, show them too but with some kind of indication (f.e. "::").
This is especially helpful for checking if a certain extension is loaded without having to know if it is present.
Then, for readability and my personal preference, the list should be sorted like humans do.
Not:
:: X.tcz
:: a.tcz
:: b.tcz
:: z.tcz
c.tcz
x.tcz
y.tcz
But:
:: a.tcz
:: b.tcz
c.tcz
:: X.tcz
x.tcz
y.tcz
:: z.tcz
If I could get sort to ignore ":: " that would certainly be preferable over the additional sed . But meh.. couldn't get it to work. Anyway, the script doesn't behave like a sprinting snail anymore. Doing a little extra work 500 times is way faster than 500*500 times. q:
Still, if you can think of anything to bump me in the right direction, I'd be the last who complains.
-
Anything like this ?
"view info.lst and display already downloaded + loaded extentions" http://forum.tinycorelinux.net/index.php/topic,13056.msg71819.html#msg71819
show a list of loadable extensions to choose from. In addition, instead of leaving out those already loaded, show them too but with some kind of indication (f.e. "::").
-
Interesting. I'm happy with my dmenu script now but an additional dmenu apps browser might be nice. Thanks.
-
If I could get sort to ignore ":: " that would certainly be preferable over the additional sed . But meh.. couldn't get it to work.
Please don't misunderstand, I luv sed. Sed is awesome but I've found there are much faster methods in repetitive tasks
Let me to give a hint, use sort earlier.. :p
Though I didn't time it, this executed really fast
cd /etc/sysconfig/tcedir/optional
tczs=$(ls *.tcz | sort -bf)
for f in $tczs ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: $f" || echo "$f"; done
Of course I had to test the theory
:: unzip.tcz
...
v4l-dvb-4.2.7-tinycore64.tcz
vlc.tcz
:: wbar.tcz
:: webkitgtk4.tcz
wget.tcz
wireless-4.2.7-tinycore64.tcz
wireless_tools.tcz
wpa_supplicant-dbus.tcz
x264.tcz
:: xcursor-themes.tcz
:: xf86-input-evdev.tcz
:: xf86-video-vesa.tcz
Xfbdev.tcz
:: xkeyboard-config.tcz
:: Xlibs.tcz
:: Xorg-7.7-3d.tcz
:: Xorg-7.7-bin.tcz
:: Xorg-7.7-lib.tcz
:: Xorg-7.7.tcz
:: Xorg-fonts.tcz
:: xorg-server.tcz
:: Xprogs.tcz
:: zip.tcz
-
First, I'm sure I'm not misunderstanding you. Tools like sed are great but the less tools the better.
Second, I luv you. You made sed obsolete for me. (: time shows the same results but the code is looking faster. (;
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1
EXT="*.tcz"
OPT="-i -xs -c -b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
cd /etc/sysconfig/tcedir/optional
#TCZS="$(for f in $EXT ; do X="${f%.*}" && [ -e "/usr/local/tce.installed/$X" ] && echo " $X" || echo "$X" ; done | sort -bf | sed 's/ /:: /')"
TCZS=$(ls $EXT | sort -bf)
TCZS=$(for f in $TCZS ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: $f" || echo "$f"; done)
TCZ="$(echo "$TCZS" | dmenu -p "$EXT" $OPT 2>/dev/null)" \
&& tce-load -i "$TCZ" &
-
Hey mocore, thanks! I've implemented downloading and parsing info.lst .
#!/bin/sh
INST="/usr/local/tce.installed"
[ "$(which dmenu)" ] || [ -e "$INST/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1 || { echo "dmenu not available."; exit 1; }
EXT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19"
LST="info.lst"
DIR="/tmp"
INFO="$DIR/$LST"
while getopts wila OPTION
do
case ${OPTION} in
w) WGET=TRUE ;;
i|l) LOAD=TRUE ;;
a) ALL=TRUE ;;
esac
done
cd /etc/sysconfig/tcedir/optional
if [ "$WGET" ]; then
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #689ACF"
if [ ! -e "$INFO" ]; then
echo "Downloading $LST ..." | dmenu -p "$EXT" $OPTS 2>/dev/null &
. /etc/init.d/tc-functions
getMirror
wget -P "$DIR" "$MIRROR/$LST"
[ "$?" == 0 ] || { killall dmenu 2>/dev/null; echo "Failed!" | dmenu -p "$EXT" $OPTS 2>/dev/null; exit 1; }
fi
if [ "$ALL" ]; then
MENU="$(for f in $(ls $EXT | sort -fu - ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="+ $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
else
MENU="$(for f in $(cat ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="+ $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
fi
if [ "$LOAD" ]; then
CMD='xterm -T "Download and Load $TCZ" -e $SHELL -c "tce-load -w $TCZ && tce-load -i $TCZ; $SHELL"'
else
CMD='xterm -T "Download $TCZ" -e $SHELL -c "tce-load -w $TCZ; $SHELL"'
fi
else
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
MENU="$(for f in $(ls $EXT | sort -f); do X="${f%.*}"; [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; echo "$X"; done)"
CMD='tce-load -i $TCZ'
fi
killall dmenu 2>/dev/null
TCZ="$(echo "$MENU" | dmenu -p "$EXT" -i -xs -c $OPTS 2>/dev/null)" \
&& (TCZ="$(echo "$TCZ" | sed 's_[+|::|@]__g')" ; eval ${CMD}) &
-
Using "+" (plus sign) to indicate downloadable extensions is not a good idea - those characters get removed from the string before it's shipped to tce-load but there are actually extensions that have a "+" in their file name (f.e. dvd+rw-tools.tcz). Now using "<".
#!/bin/sh
INST="/usr/local/tce.installed"
[ "$(which dmenu)" ] || [ -e "$INST/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1 || { echo "dmenu not available."; exit 1; }
EXT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19"
LST="info.lst"
DIR="/tmp"
INFO="$DIR/$LST"
while getopts wila OPTION
do
case ${OPTION} in
w) WGET=TRUE ;;
i|l) LOAD=TRUE ;;
a) ALL=TRUE ;;
esac
done
cd /etc/sysconfig/tcedir/optional
if [ "$WGET" ]; then
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #689ACF"
if [ ! -e "$INFO" ]; then
echo "Downloading $LST ..." | dmenu -p "$EXT" $OPTS 2>/dev/null &
. /etc/init.d/tc-functions
getMirror
wget -P "$DIR" "$MIRROR/$LST"
[ "$?" == 0 ] || { killall dmenu 2>/dev/null; echo "Failed!" | dmenu -p "$EXT" $OPTS 2>/dev/null; exit 1; }
fi
if [ "$ALL" ]; then
MENU="$(for f in $(ls $EXT | sort -fu - ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="< $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
else
MENU="$(for f in $(cat ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="< $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
fi
if [ "$LOAD" ]; then
CMD='xterm -fg gold -bg black -g 80x9 -T "Download and Load: $TCZ" -e $SHELL -c "tce-load -w $TCZ && tce-load -i $TCZ; $SHELL"'
else
CMD='xterm -fg gold -bg black -g 80x9 -T "Download: $TCZ" -e $SHELL -c "tce-load -w $TCZ; $SHELL"'
fi
else
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
MENU="$(for f in $(ls $EXT | sort -f); do X="${f%.*}"; [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; echo "$X"; done)"
CMD='xterm -g 80x9 -T "TCE-Load: $TCZ" -e tce-load -i $TCZ'
fi
### If running tce-load from /etc/sysconfig/tcedir/optional , copy2fs.flg will be ignored!
#cd --
killall dmenu 2>/dev/null
TCZ="$(echo "$MENU" | dmenu -p "$EXT" -i -xs -c $OPTS 2>/dev/null)" \
&& (TCZ="$(echo "$TCZ" | sed 's_[<|::|@]__g')" ; eval ${CMD}) &