Tiny Core Linux
General TC => Programming & Scripting - Unofficial => Topic started by: deetee on May 23, 2013, 03:29:07 AM
-
Hi all!
For work with the shell I often use the midnight commander (mc). Unfortunately mc (and the libs) are (in relation to the tiny size of TC) relatively big (>6MB).
There are smaller file managers out there (like lfm or vifm) - but they are not (yet) supported by TC.
So I had the crazy idea to write a file manager application as shell script (!?!) which has some advantages in relation to "regular" compiled programs (small; easy to maintain; no dependencies except busybox/ash; close to the operating system; customized to TC/busybox/ash; processor independent).
After some hours of programming I got a working version (see attachment; size: 13k) which I called TFM (tiny file manager).
It's relatively stable (if you do what's intended) and supports main features of a file commander (not the wide spectrum of mc).
One aim was to create a minimal "screen impact" (now 10 lines) to preserve the information on the rest of the screen (i.e. when working with a subshell).
Because of the cursor movements based on ANSI-escape-sequences and querying escaped keys the display is sometimes a little bit "disturbed".
Unfortunately multi-file-operations (tagging) are not (yet) implemented (I don't have a clue how to do it).
As there is no (script) code which is not improvable and I'm a scripting newbie, I ask you for help to make my code better, smaller, more efficient and to enhance the features of TFM.
I hope the code is reasonably readable and self-explanatory (get first help with F1).
TIA
deetee
-
There are smaller file managers out there (like lfm or vifm) - but they are not (yet) supported by TC.
lfm is written in Python, so all together it is much bigger than mc.
-
Hi deetee
Because of the cursor movements based on ANSI-escape-sequences and querying escaped keys the display is sometimes a little bit "disturbed".
Not true. The reason the screen flickers so much is because of the way the script is written. The key to fast program
execution is to make the computer do as little work as possible. That includes not performing unnecessary screen
updates, which can be slow. Your biggest time killer seems to be this section of code in _print_pan1():
echo -n $PANCOLOR
i=1
while :; do
if [ $i -ge $(($MAXFILELIST + 1)) ]; then break; fi
echo -n "${CSI}$(($ROW1 + i));${COL1}H$CLEARSTRING"; i=$(($i + 1))
done
Try moving it to _change_dir_down() and _change_dir_up(). Same goes for _print_pan2().
Though it probably does not consume a lot of time, the same holds true for the _print_path call. Remove it from
_print() and place it in _change_dir_down() and _change_dir_up().
In the main program, move the _print call after the esac statement and add a continue statement to all the cases
that call _print_all() so you don't update a panel twice.
It might be worth changing:
'F3'|3) cat $CHOSENFILE | more; _print_all ;; # cat
to:
'F3'|3) cat $CHOSENFILE | less; _print_all ;; # cat
This will allow a user to page up and down through the file. Consider changing cat to view in the help panel.
Consider replacing these type of statements:
if ls -A $PATH2 | grep -q -w $CHOSENFILE; then
with something similar to:
if [ -e $PATH2/$CHOSENFILE ]; then
-
Hi Rich!
Thank you very much for your work. To analyze in detail and improve my program sustainable (in this short time) indicates that you are a "professional scripter" - thanks to learn from you.
I agree to all of your tips - the program is faster (i.e. your "less"-hint) and less flickering (see attachment).
Unfortunately, if the number of files in a directory is less and the keys are pressed fast, some "residual" parts of the status line remain in the panel area (till you i.e. change dir) because the pan area is not cleaning up every time now. But the advantage of no flickering is worth to live with this residuals.
By the way:
Do you have some hints to expand the status line with valuable and useful information. I.e. is it worth to show cpu% or mem% or batt%?
In addition I would like to improve the user menu (F2). Do you have any ideas which console commands are used often and are complex to type (i.e. finding files, show hardware status)?
deetee
-
Hi deetee
Thank you very much for your work. To analyze in detail and improve my program sustainable (in this short time) indicates that you are a "professional scripter" - thanks to learn from you.
You are quite welcome, however, "professional" is too strong a word. Amateur would be more than generous.
Unfortunately, if the number of files in a directory is less and the keys are pressed fast, some "residual" parts ...
Yes, those are two different issues. One is caused by changing into a directory containing less than a panel full of
entries AND less entries then the previous directory. That case is handled by clearing the panel when changing
directories. The other is caused by not being able to process the keyboard fast enough, and that is what you need to address.
On my machine, from the time you hit the UP or DOWN arrow key, to the time your program hits the next call to _get_key
takes about 0.22 seconds. About 0.08 seconds are spent in _print_bar and another 0.08 seconds in _print_status. In my
opinion, you are making far too many ls calls, and it is one of the things hurting the execution speed. I would begin by
looking at _print_status. There is no need to calculate directory size and disk space used unless someone copies, deletes,
or moves a file. Make those values global, and only recalculate them when one of your routines does something to change
them. Also, the size of the disk never changes, place that into a global when the program starts. Since those values are
printed one after the other in your status bar, you can then simply:
echo -n "/$DIRSIZE $DISKUSED/$DISKSIZE "
By including a trailing space, you don't have to make an extra echo call prior to printing the time. This section:
echo -n " " # permission
echo -n $( (ls -lA $PATH0 | grep "^d" ; ls -lA $PATH0 | grep "^-") |
awk '{ print $1;}' | head -$FILECHOOSE | tail -1)
consumes 0.03 seconds of _print_status. You could reduce that to about 0.01 seconds like this:
echo -n $(ls -lA $PATH0 | grep $CHOSENFILE | cut -d" " -f1)
Here is how I did the timing measurements, modify main like this:
echo $CUROFF
Time1=`cat /proc/uptime | cut -d" " -f1`
while :
do
_print
Time2=`cat /proc/uptime | cut -d" " -f1`
echo -n "${CSI}$(($STATUSLINE + 2));1H`dc $Time2 $Time1 sub p`$CLEARSTRING"
echo -n "${CSI}$(($STATUSLINE + 3));1H`dc $Time4 $Time3 sub p`$CLEARSTRING"
_get_key
Time1=`cat /proc/uptime | cut -d" " -f1`
The first echo statement times from when you hit a key until you are ready to process the next key. The secon echo
statement is for timing other sections of the script using Time3 and Time4 like this:
_print(){ # print actual pan and status
_print_path
if [ $PAN -eq 1 ]; then _print_pan1
else _print_pan2; fi
_print_bar
Time3=`cat /proc/uptime | cut -d" " -f1`
_print_status
Time4=`cat /proc/uptime | cut -d" " -f1`
}
Here I'm measuring the execution time of _print_status. Timing resolution is 0.01 seconds. Always make several
measurements to check for consistent results. This post is rather long, so I'll end it by quoting my previous post:
The key to fast program execution is to make the computer do as little work as possible.
-
Hi Rich!
You are great - I can't find the words how you atomize and analyze my code - thanks for spending so much of your time to improve my program.
All that you say makes sense. Today I tried to add a cpu-usage to my status line (I did it with a top/head/tail/awk/printf-command) and I observed what you explained: The program stucked completely.
Unfortunately I am off my computer this weekend (typing this on my phone). But next week I will focus on your hints and try to fasten this program which seems to become really useable and useful.
Regards
deetee
-
Hi deetee
I once read Linux command line utilities being described as "Doing only one thing, but doing it really well". I think you should
apply the same philosophy and avoid adding non-filemanager related information to your status bar.