Homokozó:Programozás/2
.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;

Test #2 

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 :)