Other tasks: 1, 2, 3, 4, 5, 6, 7.

General notes

Use your GitLab repository to submit your solutions. Please, use exact filenames as specified in the task name.

Please, respect language requirements of individual tasks. For Python, we expect Python 3 as the default (if you really need to use Python 2, use a proper shebang). For shell scripts, we expect that you will use Bash although none of the tasks requires any use of Bashisms for an efficient solution.

Deadline for this set of tasks is 2020-04-09 AoE, it is required to get at least 8 points from this group.

Tasks description

02/last_mod.sh (1 point)

Write a shell script that lists 7 most recently modified files in the current directory. By files we mean any kind of file (symlink, directory, normal file, …). Hidden files can be ignored.

02/smallest_bin.sh (1 point)

Write a shell script that prints filenames of 10 smallest files from /usr/bin that contain letter a in their filename.

Ignore files in subdirectories.

02/lines_4_7.sh (1 point)

Write a shell script that prints lines 4, 5, 6 and 7 from /etc/passwd.

02/group_sum.sh (1 point)

Write a shell script that prints sum of all group ids. Groups are defined in /etc/group (or better yet, with getent group), their id is the third column.

02/is_prime.sh (1 point)

Write a shell script that checks whether a number is a prime.

The script will accept single argument: number to check. There will be no printed output, the script is expected to be used as part of if condition, e.g. in the following snippet:

for i in $( seq 1 30 ); do
    if ./is_prime.sh "$i"; then
        echo "$i is prime."
    fi
done

Your script must be able to handle invalid invocation gracefully.

Hint: man 1 exit.

02/user_vars.sh (1 point)

Write a shell script that prints names of environment variables that contain username of the current user (use whoami). Print only variable names, not their content.

Typically, you should see the following output.

HOME
MAIL
OLDPWD
PWD
USER

02/rand_str.sh (1 point)

Write a shell script which prints a random string. It should take the length of the string as its first argument and the list of allowed characters as the second argument (in the same format as tr takes).

Example:

./rand_str.sh 10 a-zA-Z0-9

Note that /dev/urandom provides an unlimited stream of random bytes. Also note, that the comparison of characters depends on your system settings called locales. For this task use LC_COLLATE=C. You can set this variable in the beginning of your script. On unixadmin machine this variable is already set as mentioned.

02/circle.sh (2 points)

Write a shell script that prints a circle onto standard output. The circle radius will be passed as the first argument.

The script does not need to handle invalid invocation gracefully, the output can assume that characters in the console are square and off-by-1 errors (because of rounding etc.) are okay. This is an example for ./02/circle.sh 6:

      X
   XXXXXXX
  XXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
XXXXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
  XXXXXXXXX
   XXXXXXX
      X

02/real_user_names.sh (3 points)

Write a shell script that obtains real names of users and their logins from the output of command getent passwd. Then print the names (one entry per line) in format Real Name:login onto standard output, alphabetically sorted by login. If you use temporary files for swapping columns, do not forget to remove them.

If the entry does not specify real name at all (often true for system daemons, for example), skip the entry completely.

Note that while cat /etc/passwd and getent passwd might seem similar, getent is usually preferred. It returns data from other sources too, such as LDAP server or similar (compare their output on Rotunda machines, for example).

02/interactive_sum.sh (2 points)

Write an interactive shell script for summing numbers. It should print = SUM with the current sum of all numbers (initially 0), then prompt user with + sign to write a number, and repeat until the input is closed (by pressing ^D).

An example session:

= 0
+ 3
= 3
+ 10
= 13
+

02/find_wc.sh (2 points)

Write a shell script that counts bytes (-c), chars (-m), lines (-l), or words (-w) of the regular files satisfying given conditions.

It should take what to count as the first argument and the specification of files in the format of the find command as the remaining arguments.

Thus it is expected to be called in the following way:

./find_wc.sh (-c|-m|-l|-w) [find options to specify file list]

In addition to the counts for the individual files, the total amount should be printed too (that is the default behaviour when wc is executed with multiple files).

02/my_cat.py (4 points)

Write a Python program that would emulate the standard command cat. The following features must be supported. Without any arguments, the program copies standard input to standard output. When multiple arguments are provided, they are treated as filenames (see exceptions below) – their content is then printed to standard output. A special filename - (dash) means standard input (e.g. as in echo "my text" | cat header - footer).

Your program must recognize --help to print a short help and --version to print its version. When these options are present, other arguments are ignored.

Your program must support -- delimiter to allow reading from file names --help or --version.

Ostatní úlohy: 1, 2, 3, 4, 5, 6, 7.

Obecné požadavky

Úkoly odevzdávejte do Vašeho GitLabového repozitáře. Prosím, dodržujte přesné pojmenování souborů jak je uvedeno u názvu úkolu.

Prosím, dodržujte požadovaný jazyk jednotlivých úloh. Pro úlohy v Pythonu očekáváme použití Pythonu verze 3 (pokud doopravdy potřebujete verzi 2, nezapomeňte na správný shebang). Pro shellové skripty, očekáváme, že budete používat Bash. Nicméně, žádný z úkolů nevyžaduje použití Bashismu pro efektivní řešení.

Deadline pro tuto sadu úloh je 2020-04-09 KnZ, pro úspěšné splnění potřebujete získat alespoň 8 bodů.

Úlohy

02/last_mod.sh (1 bod)

Napište shellový skript, který vypíše 7 nejnovějších (ve smyslu data poslední změny) souborů z aktuálního adresáře. Pojmem soubor myslíme libovolný druh souboru (symbolické odkaz, adresář, obyčejný soubor, …). Skryté soubory je možné ignorovat.

02/smallest_bin.sh (1 bod)

Napište shellový skript který vypíše názvy 10 nejmenších soubor z /usr/bin které mají ve svém názvu písmeno a.

Ignorujte soubory v podadresářích.

02/lines_4_7.sh (1 bod)

Napište shellový skript, který vypíše řádky 4, 5, 6 a 7 z /etc/passwd.

02/group_sum.sh (1 bod)

Napište shellový skript který spočítá součet id skupin. Skupiny jsou definovány v /etc/group (nebo ještě lépe skrz getent group), jejich id je třetí sloupec.

02/is_prime.sh (1 bod)

Napište shellový skript který otestuje, je-li zadané číslo prvočíslem.

Skript očekává jediný argument: číslo k otestování. Skript nebude nic vypisovat, očekáváme, že skript bude používán v if podmínkách, např. jako v následující ukázce:

for i in $( seq 1 30 ); do
    if ./is_prime.sh "$i"; then
        echo "$i is prime."
    fi
done

Váš skript musí zvládnout rozumně nesprávné použití.

Nápověda: man 1 exit.

02/user_vars.sh (1 bod)

Napište shellový skript, který vypíše názvy proměnných prostředí, které obsahují uživatelské jméno právě přihlášeného uživatele (využijte whoami). Vypište pouze názvy proměnných, nikoliv jejich obsah.

Typicky byste měli obdržet následující výstup.

HOME
MAIL
OLDPWD
PWD
USER

02/rand_str.sh (1 bod)

Napište shellový skript, který vytiskne náhodný řetězec. Jako první argument bere délku řetězce, seznam dovolených znaků (ve stejném formátu jako pro tr) je pak druhý argument.

Příklad:

./rand_str.sh 10 a-zA-Z0-9

Všimněte si, že /dev/urandom vrací nekonečný seznam náhodných bajtů. Dále si všimněte, že porovnání znaků záleží na tom, jak máte nastavenu lokalizaci systému locales. Pro tuto úlohu použijte LC_COLLATE=C. Proměnnou můžete nastavit na začátku Vašeho skriptu. Na stroji unixadmin je tato proměnná takto nastavena.

02/circle.sh (2 body)

Napište shellový skript, který tiskne kruh na standardní výstup. Poloměr kruhu bude zadán jako první argument.

Skript může očekávat, že vstup (argument) bude korektní, na výstupu můžete předpokládat, že znaky na konzoli jsou čtvercové a chyby o plus/mínus 1 (kvůli zaokrouhlování apod.) nevadí. Příklad pro ./02/circle.sh 6:

      X
   XXXXXXX
  XXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
XXXXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
 XXXXXXXXXXX
  XXXXXXXXX
   XXXXXXX
      X

02/real_user_names.sh (3 body)

Napište shellový skript, který získá skutečná jména uživatelů a jejich přihlašovací jména (loginy) z příkazu getent passwd. Pak je vypište (jeden záznam na řádek) ve formátu Skutečné jméne:login na standardní výstup, abecedně seřazené podle loginu. Pokud budete používate dočasné soubory (např. kvůli prohození pořadí sloupců), nezapomeňte je odstranit.

Pokud nemá položka vyplněnné skutečné jméno, přeskočte ji (to se bude týkat hlavně systémových služeb).

Všimněte si, že cat /etc/passwd a getent passwd mohou vypadat podobně, obecně je lepší použít getent. Vrací totiž i data z jiných zdrojů, např. z LDAP serveru (například porovnejte jejich výstup na počítačích v Rotundě).

02/interactive_sum.sh (2 body)

Napište interaktivní shellový skript pro sčítání čísel. Skript má vypisovat = SOUCET se současným součtem (na počátku 0), pak si vyžádat vstup od uživatele pomocí +. Toto bude opakovat dokud uživatel vstup neukončí (stiskem ^D).

Příklad jednoho spouštění:

= 0
+ 3
= 3
+ 10
= 13
+

02/find_wc.sh (2 body)

Napište shellový skript, který spočte bajty (-c), znaky (-m), řádky (-l), nebo slova (-w) obyčejných souborů splňujících dané podmínky.

Prvním argumentem bude co počítat, ostatní argumenty budou ve formátu pro příkaz find a ovlivní, které soubory se budou brát v potaz.

Takže spuštění bude odpovídat tomuto formátu:

./find_wc.sh (-c|-m|-l|-w) [volby pro prikaz find]

Kromě počtů pro jednotlivé soubory vypište i součet pro všechny soubory dohromady (což je výchozí chování programu wc při spuštění nad více soubory).

02/my_cat.py (4 body)

Napište program v Pythonu, který bude emulovat standardní příkaz cat. Následující vlastnosti musí být podporovány. Bez argumentů, program bude kopírovat standardní vstup na standardní výstup. Pokud je zadáno více argumentů, jsou brány jako názvy souborů (kromě výjimek popsaných níže) – jejich obsah je pak vytištěn na standardní výstup. Speciální název soubor - (pomlčka) znamená standardní vstup (např. kvůli echo "muj text" | cat hlavicka - paticka).

Váš program musí rozpoznat --help aby vypsal krátkou nápovědu a --version aby vypsal svojí verzi. Pokud jsou přítomny tyto volby, ostatní argumenty jsou ignorovány.

Váš program musí podporovat oddělovač -- aby šlo číst i ze souborů, které se jmenují --help nebo --version.