Programozás
szerző: Szervác Attila
2. lecke
Ch2: Residue, nested loop, sharp comment and operator, if, Love random


.2 Residue, nested loop, sharp comment and operator, if, Love random


You can get the residue (in an arithmetical expansion) by the % operator:

sh -c 'a=1234; printf "$((a%98))\n"'

Thus we can create safer nested loops:

sh -c 'limit=12; lc=$((23%limit)); a=0; while [ $a -le 1 ]; do b=1; while [ $b -le $lc ]; do printf "$((a*lc+b)) "; b=$((b+1)); done; b=1; printf "\n"; a=$((a+1)); done; # it was safer'

As we watched again: outside a quoted expression we can introduce our very-very important comments with the # character. The most important comment in every standard stored script file is the first sha(rp)-bang line at least minimal in the #!/bin/sh form which makes possible operating system to determine the actual interpreter (program) to run our program.

Before a parameter in a {parameter} expansion it can resolve for us the length of the our string (in the parameter). Between a parameter and a 'word' it removes smallest prefix matching the actual pattern expanded from the 'word' to a 'pattern'. (% can remove the smallest suffix… :-))

sh -c 'a="asdf"; printf "${#a} ${a#?}\n"'

Let’s open ( &close ) the /dev/urandom pseudo-random-generator file, read a string from it (terminated by a randomly arrived newline character from the /dev/urandom file stream) into our 's' variable & get the random number of the length of this prng data:

sh -c 'read s</dev/urandom; printf "${#s}\n"'

So let's see an example for the content of a standard script file (~ 10 lines) + see a basic example for the if conditional flow-control also:

#!/bin/sh # ANY optional sh arguments also can be here ...
if [ $1 ]; then printf "my first arg was: $1\n"; fi;
read -p " Gimme the size of your table you want then press Enter: " n;
# the read command AALWAYSS wait to get a Newline character!!!!!!!!!!
#   w: in this short example we assume the user type a small number...
a=1; b=1;
while [ $a -le $n ];
do while [ $b -le $n ]; do printf "%4d" "$((a*b))"; b=$((b+1));
done; a=$((a+1)); b=1; echo;
done; # :)
exit 0;

1: With Your effective skills of the arithmetic expansion write an efficient command, which printf the last 5 binary digits of a number.

2: With Your effective skill of the while loop: put all these codes into an s variable.

3: With Your baby arithmetic expansion skills animate this string by rotation, see the solve of these tests in the next page.


Here comes a beautiful funny solution of the test above:

sh -c 's=""; a=0; while [ $a -le 31 ]; do s="$s  :) $((a/16))$(((a%16)/8))$(((a%8)/4))$(((a%4)/2))$((a%2))"; a=$((a+1)); done; a=0; printf "\e[2J"; while [ $a -le 458 ] ; do s=${s#${s%?}}${s%?}; printf "\e[H\f\f$s"; a=$((a+1)); done; printf "\n\n END OF THE ANIMATION.\n\n"'

Enjoy it :)

Animations introduce a topic that the standard shell does not handle itself!, just as the most standard meta-language that can call any kind of program on the computer.

This is: the timing.

If You want to apply sleeping times in Your loop, in this case you can call the sleep (e.g. sleep 0.9) command: from the coreutils package.

In this part of our book, our goal is to get into the most elementary functions of the standard shell & introduce into next scripting languages (Perl, Python and so on...) and programming of a standard system (to different outputs) in general.

However sometimes we will show some little examples that use 1-2 little utilities from the coreutils package.

Szervác’s Dog – this little program demonstrates the real animation power of our Love, the Standard Shell

#!/bin/sh
#         ))__       __((
#         |__/       \__|
# )______))             ((______(
# /|    |)              (|     |\
while :; do
a="         ))__\f\e[13D         |__/\f\e[12D )_____))\f\e[10D /|    |)";
# printf "\e[10;1;f$a";
printf "\e[10;1;f\e[?25l"; c=0; while [ $c -le 43 ]; do printf "$a\e[3A\e[9D ";
sleep 0.018; c=$((c+1)); done;
a="__((        \f\e[13D\\__|         \f\e[10D((______( \f\e[10D(|     |\\";
while [ $c -ge 1 ]; do printf "$a \e[3A\e[13D";
sleep 0.018; c=$((c-1)); done;
printf "\e[4B\r\e[?25h";
done; # Enjoy :)