14Kapitola

Bash 14: Interaktivní skripty: read

Možná máte ze skriptů prezentovaných v tomto seriálu divný pocit, jako by to nebyly plnohodnotné programy, jako by jim něco chybělo. Abstrahujeme-li od grafického rozhraní, zjistíme, že schází jakákoli komunikace s uživatelem. Ano, všechny zde dosud prezentované skripty byly neinteraktivní. Dnes tento nedostatek odstraníme seznámením se s příkazem read. Bohdan Milar .

Řádky a slova

Nejprve si prosvištíme trochu teorie. Řádek je v podání Bashe sekvence znaků zakončená znakem (klávesou) [Return] ([Enter]). Slova jsou části řádku oddělené speciálními znaky. Tyto znaky se nazývají vstupní oddělovače polí (Input Field Separator - IFS) a jejich seznam je uchováván v proměnné IFS.

Pokud si ovšem zkusíte vypsat její obsah (echo $IFS), pravděpodobně nic neuvidíte. To proto, že výchozím oddělovačem slov je mezera a její vypsání na prázdný řádek budí stále dojem prázdného řádku. Zkuste ji tedy obklíčit třeba písmeny a (echo a${IFS}a).

Příkaz read

Úkolem read je číst standardní vstup a takto získanými daty naplňovat zadané proměnné. Přesněji řečeno přečte vždy jeden řádek vstupu, rozdělí jej na slova a ta postupně přiřadí zadaným proměnným.

Nejjednodušším zápisem je samotný příkaz read. V tomto případě je celý řádek načten do proměnné REPLY. Pokud chceme vstupem naplňovat konkrétní proměnnou, zadáme jednoduše její jméno za read, např. read login naplní proměnnou login zadaným řetězcem. Pro naplnění dvou proměnných by vypadal zápis takto: read jmeno prijmeni.

Pokud je na vstupu zadáno více slov, než je počet proměnných, dosadí se do poslední z nich všechna zbývající slova včetně oddělovačů. Pokud je naopak v řádku slov méně, jsou zbývající proměnné naplněny prázdným řetězcem. Read přichází také s několika přepínači. Vybíráme z nich:

-a pole - místo do proměnných ukládá read načtené hodnoty do pole zadaného jména (počínaje hodnotou [0]) - viz 5. díl;

-n x - nečte řádek, ale jen x znaků, což se hodí pro zadávání hodnot přesně dané délky nebo prostě pro čekání na stisk klávesy (read -n 1);

-s - způsobí, že zadávané znaky nebudou zobrazovány, čehož lze využít např. při zadávání hesla nebo jiných důvěrných údajů;

-t sekundy - read bude čekat na vstup z klávesnice jen stanovený počet sekund.

 

Použití ve skriptech

Čekání na stisk klávesy:

while true; do
echo "Stiskněte klávesu"
read -n 1
echo -n "Právě je "; date
done

Zadávání jména a hesla:

echo -n "Jméno: "; read jmeno
echo -n "Heslo: "; read -s heslo
echo "Heslo pro $jmeno zadáno."

Příkaz read může pracovat i s jinými vstupy než klávesnice. Za upozornění však stojí, že při použití konstrukce roura nepracuje tak, jak většina uživatelů očekává (viz 6. díl).

Místo

echo "aa bb" | read a b ; echo $a $b

je třeba použít

echo "aa bb" | ( read a b ; echo $a $b )

Častější je však použití pro načítání víceřádkových souborů. Ukažme si, jak ze souboru /etc/fstab (seznam přípojných bodů) vybrat jen údaje o discích a přípojných bodech:

grep -v "^#" /etc/fstab | while read disk bod zbytek
do echo "$disk na $bod"
done

V prvním řádku jsme odfiltrovali řádky začínající křížkem a výsledek jsme předali smyčce while, která bude probíhat tak dlouho, dokud ji bude grep zásobovat vyhovujícími řádky z /etc/fstab. V každém průběhu smyčkou uloží read první pole zpracovávaného řádku do proměnné disk, druhé do bod a zbytek řádku do zbytek. Zbytek smyčky je triviální.

Závěr

Takže konečně máme nástroj, kterým můžeme zapojit uživatele do hry, tedy přesněji řečeno do práce s našimi skripty. Prakticky si to předvedeme hned příště s příkazem case.