Programování v shellu
Úvod do příkazové řádky

Lukáš Bařinka

Náplň cvičení

Cílem cvičení je základní seznámení se s příkazovou řádkou a práce na vzdáleném počítači.

  • Spouštění příkazů, přepínače, argumenty
  • Pohyb po příkazové řádce
  • Pohyb po souborovém systému
  • Přesměrování výstupu příkazu a výpis souboru
  • Práce s proměnnou
  • Dokumentace příkazů
  • Sekvenční a asynchronní spouštění příkazů
  • Roury a primitivní filtry
  • Bezpečné vzdálené připojení (ssh)

Spouštění příkazů, přepínače, argumenty

  • Na velikosti písmen záleží
  • Zadávaný text se rozdělí na slova pomocí mezer a tabulátorů (případně jejich kombinací)
  • Příkazy se oddělují středníkem (;) nebo novým řádkem (⏎)

Jednoduché příkazy


							~id⏎
							uid=10001(barinkl) gid=1002(zam)
							~uname␣-a⏎
							SunOS fray1 5.11 11.3 sun4v sparc SUNW,SPARC-Enterprise-T5120
							~who⏎
							teterjak   pts/24       Dec 21 20:07    (cst-prg-109-206.cust.vodafone.cz)
							barinkl    pts/35       Sep 30 11:42    (users.fit.cvut.cz)
							~who␣am␣i⏎
							barinkl    pts/35       Sep 30 11:42    (users.fit.cvut.cz)
							~whoami⏎
							barinkl
							~tty⏎
							/dev/pts/35
						

Chyby při spouštění příkazů


							~ID
							bash: ID: command not found
							~cd/tmp
							bash: cd/tmp: No such file or directory
							~cd /TMP
							bash: cd: /TMP: No such file or directory
							~/etc/passwd
							bash: /etc/passwd: Permission denied
						

Struktura příkazu

Jméno příkazu [command name]
CO: určuje, který příkaz se vykoná
Přepínače/parametry/volby [options]
JAK: ovlivňují vykonání příkazu
Argumenty [arguments]
S ČÍM: specifikují data ke zpracování

Struktura příkazu - Příklad


							~ls -l -R /var/tmp /tmp
						
  • Vylistuj (ls = list)
  • Podrobně, rekurzivně
    (-l = long, -R = recursive)
  • Adresář /var/tmp a /tmp

Příkaz lze ukončit stiskem klávesy CTRL+C

Příkaz

  • Obvykle první slovo na řádce (po oddělovači příkazů)
  • Bez cesty - nemusí být jedinečné
  • S absolutní cestou - jednoznačné
  • S relativní cestou - záleží na aktuálním (pracovním) adresáři

							~date
							~declare -p PATH
							~type type
							~type date
							~/usr/bin/date
							~cd /usr; bin/date
						

Krátké přepínače

  • začínají -
  • obsahují jeden znak (obvykle písmeno)
  • je možné je psát dohromady
  • jejich argument lze oddělit mezerou nebo psát přímo

							~ls -l -d /tmp
							~ls -ld /tmp
							~cd /bin; ls ?????
							/binls -w 40 ?????
							/binls -w40 ?????
						

Dlouhé přepínače

  • začínají --
  • obsahují celé slovo
  • píšou se zvlášť
  • jejich argument lze oddělit mezerou nebo =

							/binls --width=40 ?????
							/binls --width 40 ?????
						

Pohyb po příkazové řádce

Pro efektivní pohyb na příkazové řádce je možné používat:

  • Šipky (pohyb po řádce a v historii příkazů)
  • Odeslání řádku ke zpracování z libovolného místa na řádce
  • Tabulátor pro doplňování názvů příkazů a jmen souborů
  • Levým tlačítkem myši lze text označit, prostředním vložit
  • Sekvence CTRL+ nebo ALT+

Pohyb v historii příkazů

  • ⇧ (CTRL+P) = předchozí příkaz
  • ⇩ (CTRL+N) = následující příkaz
  • CTRL+R text = vyhledávání textu v historii (od nejmladšího)

Výstup na terminál a ukončení programu

  • CTRL+S = pozastaví výstup na terminál
  • CTRL+Q = opětovně spustí výstup
  • CTRL+C = ukončí program

							~ls -lR /
							^S
							^Q
							^C
						

Pohyb po řádce

  • CTRL+⇦ (ALT+B) = pohyb po slovech doleva
  • CTRL+⇨ (ALT+F) = pohyb po slovech doprava
  • HOME (CTRL+A) = skok na začátek řádky
  • END (CTRL+E) = skok na konec řádky

Pohyb po souborovém systému

  • Souborový systém (filesystem) je strom
  • Počátek je v /
  • Každá položka má své jméno (v adresáři jedinečné)
  • Položky v cestě (jména adresářů a souborů) jsou odděleny /

Terminologie

Schéma souborového systému
  • Kořen: /
  • Adresář (složka), [obyčejný] soubor
  • Absolutní cesta: /tmp/a/d
  • Relativní cesta:
    d
    ./d
    ../b/../a/./d

Příklady pohybu ve filesystému

Schéma souborového systému

							/bincd            ~/a/ccd /etc
							~pwd              /etccd
							~mkdir -p a/c b   ~cd b
							~touch a/d b/e    ~/bcd ../a/c
							~cd a             ~/a/ccd ..
							~/als -a          ~/acd ..
							~/als -l ..       ~cd ..
							~/als -l ../b     /homecd .//././
							~/als -l ~/b/e    /homecd
							~/acd c           ~rm -r a b
						

Přesměrování výstupu příkazu a výpis souboru

  • Výstupy lze uložit do souboru pomocí
    >soubor
    >>soubor
  • Vypsat soubor lze pomocí „stránkovačů“ less nebo more

Zobrazení obsahu souboru příkazem less


							~less /etc/passwd
							/nologin
							n
							n
							N
							10G
							?root
							G
							q
						
  • q = ukončení programu
  • h = nápověda
  • ⇧/⇩ = pohyb po řádcích
  • /text = hledání textu dále
  • ?text = hledání textu zpět
  • n = skok na následující text
  • N = skok na předcházející text
  • 10G = skok na řádku 10

Příklady přesměrování


							~ls -la >list
							~less list
							~date >d; sleep 5; date >d; sleep 5; date >d
							~less d
							~date >d; sleep 5; date >>d; sleep 5; date >>d
							~less d
							~date >/dev/null
							~rm list d
						

Práce s proměnnou

  • Proměnné jsou v základu netypové
  • Není potřeba je předem deklarovat
  • Kolem = nesmí být mezery: prom=hodnota
  • Proměnná má platnost pouze v rámci aktuálního shellu
  • "$prom" je nahrazeno hodnotou proměnné

Deklarace a výpis proměnné


							~A=5
							~a=text
							~declare -p A a
							declare -- A="5"
							declare -- a="text"
							~B='Programovani v shellu 1'
							~declare -p B
							declare -- B="Programovani v shellu 1"
							~C=Programovani v shellu 1
							bash: v: command not found
							~declare -p C
							bash: declare: C: not found
						

Použití proměnné


							~date >"$a"
							~mkdir "$B"
							~ls -l
							~ls -ld $B
							~ls -ld "$B"
							~rm "$a"; rmdir "$B"
							~ls -l
							~oldPS1=$PS1
							~PS1='Zadej prikaz> '
							Zadej prikazPS1=$oldPS1
							~
						

Dokumentace k příkazům

  • Lokální dokumentace pomocí příkazů help, man a info
  • help - pro vestavěné příkazy shellu
  • man - pro externí příkazy
  • info - novější (hypertextová) dokumentace
  • Některé příkazy mají přepínač --help

Typy příkazů a jejich dokumentace


							~type uname
							uname is hashed (/usr/bin/uname)
							~man uname
							q
							~type printf
							printf is a shell builtin
							~help printf
							~man printf
							G
							q
							~man 3 printf
							q
						

Problémy dokumentace a jejich řešení


							~man pwd
							...
							--logical
							...
							~pwd --logical
							bash: pwd: --: invalid option
							pwd: usage: pwd [-LP]
							~type pwd
							pwd is a shell builtin
							~help pwd
						

Jednoduché příkazy, sekvenční a asynchronní spouštění příkazů

Každý příkaz končí novým řádkem nebo oddělovačem příkazů

p1 ; p2
ukončuje (odděluje) příkaz běžící na popředí
spouštěny postupně (sekvenčně), čeká se na dokončení
p3 & p4 &
ukončuje (odděluje) příkaz běžící na pozadí
spouštěny najednou (asynchronně), nečeká se na dokončení

Ukázka spouštění příkazů


							~date +%T ; sleep 5 ; date +%T
							12:00:00
							12:00:05
							~date +%T & sleep 5 & date +%T
							[1] 12345
							[2] 12346
							12:00:00
							12:00:00
							[1]-  Done                    date +%T
							~
							[2]+  Done                    sleep 5
						

Roury a primitivní filtry

Výstup jednoho příkazu může být vstupem dalšího příkazu.

p1 | p2
příkazy běží paralelně (synchronně)
předává se pouze standardní výstup (nikoli chybový)
při ukončení jednoho příkazu končí i ostatní

Příklady použití primitivních filtrů

Program, který čte data ze standarního vstupu a zapisuje na standardní výstup se nazývá filtr.


							~ls | wc -l
							počet položek v aktuálním adresáři
							~man ls | wc -l
							počet řádek manuálu příkazu ls
							~getent services | sort
							seznam služeb seřazený podle abecedy
							~getent services | sort | less
							seznam služeb seřazený podle abecedy stránkovaný příkazem less
						

							~getent passwd | fgrep /bin/bash | wc -l
							počet uživatelů, kteří používají /bin/bash
							~getent passwd | fgrep -v /bin/bash | wc -l
							počet uživatelů, kteří nepoužívají /bin/bash
							~ls | nl
							seznam souborů aktuálního adresáře s očíslovanými řádky
							~nl /etc/passwd
							očíslované řádky souboru /etc/passwd (zde není nl jako filtr)
						

Bezpečné vzdálené připojení (ssh)

  • Zajištěné protokolem SSH, pro uživatele slouží příkaz ssh
  • Je možné se autentizovat heslem nebo klíčem
  • Je možné spouštět vzdáleně příkazy a kopírovat soubory
  • Počítače fray používají tzv. systémové heslo

profile.fit.cvut.cz

Vzdálené příhlášení


							~ssh barinkl@fray1.fit.cvut.cz
							poprvé schválit otisk klíče serveru (yes)
							zadat heslo (při zadávání se nic nezobrazuje!)
							fray1:~uname -a
							SunOS fray1 5.11 11.3 sun4v sparc SUNW,SPARC-Enterprise-T5120
							fray1:~exit
							~uname -a
							Linux barinkl 4.18.0-1-amd64 #1 SMP Debian 4.18.6-1 (2018-09-06) x86_64 GNU/Linux
							~ssh fray1.fit.cvut.cz 'uname -a'
							SunOS fray1 5.11 11.3 sun4v sparc SUNW,SPARC-Enterprise-T5120
						

Vytvoření a použití klíče


							~ssh-keygen
							potvrdit cestu do ~/.ssh/id_rsa
							nezadávat heslo (pouze enter 2x)
							~less ~/.ssh/id_rsa
							Privátní klíč
							~less ~/.ssh/id_rsa.pub
							Veřejný klíč (jedna řádka)
							~ssh-copy-id barinkl@fray1.fit.cvut.cz
							zadat heslo (při zadávání se nic nezobrazuje!)
							~ssh fray1.fit.cvut.cz
							fray1:~ssh fray1.fit.cvut.cz
						

Kopírování souborů pomocí scp


							~uname -a >systems
							~scp systems barinkl@fray1.fit.cvut.cz:
							systems                             100%   82     3.1KB/s   00:00
							~ssh barinkl@fray1.fit.cvut.cz 'uname -a >>systems'
							~scp barinkl@fray1.fit.cvut.cz:systems .
							systems                             100%  144     2.6KB/s   00:00
							~less systems
						
SSH z pohledu souborů