Potoki, przekierowania wejścia/wyjścia, komendy filtrujące

Linux używa następujących standardowych kanałów wej/wyj:

Kanał

Nazwa

Skrót

Urządzenie

Zastosowanie

0

standardowe wejście

stdin

klawiatura

dane wejściowe dla programów

1

standardowe wyjście

stdout

ekran

dane wyjściowe programów

2

standardowe wyjście błędów

stderr

ekran

komunkaty o błędach programu

Wszelkie programy korzystają z tego standardowego zestawu kanałów komunikacyjnych. Powłoka potrafi jednak dokonywać zmian w sposób niewidoczny dla programów. Np.

$ ls -la > lista-plikow-1
$ ls -la > lista-plikow-2
$ ls -la > lista-plikow-2

Jeśli wskazany plik istnieje, to zostanie nadpisany. Można tego uniknąć stosując komendę set -o noclobber.

Można także zmodyfikować standardowe wejście. Porównaj

$ wc -l
$ wc -l /etc/services
$ wc -l < /etc/services

Najczęściej w skryptach używa się podwójnego znaku mniejszości << do przekierowania na standardowe wejście grupy wierszy, np.

$ wc -l <<EOF
aaaaaaaaaaaaaa
bbbbbbbbbbbbbb
cccccccccccccc
EOF

Zob. man bash (Here documents), żeby wyjaśnić różnicę działania << i <<-. Jak działa <<<?

Przekierowania dotyczą także kanału odpowiedzialnego za standardowe wyjście błędów. Np.

$ ls l* > flist
ls: cannot access 'l*': No such file or directory
$ ls l* > flist 2>&1
$ ls 2>&1 l* > flist
ls: cannot access 'l*': No such file or directory

Przy zmianie przekierowań ważny jest ich porządek!

Uwaga! Wynik działania ls /etc i ls /etc > /tmp/ls.log nie jest identyczny: formatowanie zależy od typu urządzenia wyjściowego.

Można także tworzyć potoki łącząc standardowe wyjście jednego programu ze standardowym wejściem innego, np.

$ cat /etc/services /etc/passwd /etc/group | wc -w
$ cut -f1 -d: /etc/passwd |sort | tr 'a-z' 'A-Z'
$ iostat -d 1 | tee iostat.log

Oto szereg przykładów ilustrujących użyteczność komend filtrujących takich jak cat, cut, fmt, head, hexdump, nl, od, sort, tac, tail, tr, uniq, wc.

$ cat [-bn] /etc/hosts
$ tac  /etc/hosts
$ echo "a:b:c:d:" | tac -s:

$ head -n10 /etc/passwd | tail -1
$ iostat -c 1 > cpu.log &
$ tail -f cpu.log

$ head -n2 /etc/passwd | od -t a
$ head -n2 /etc/passwd | od -w20 -t a
$ head -n2 /etc/passwd | od -t c
$ head -n2 /etc/passwd | od -t o
$ head -n2 /etc/passwd | od -t o4
$ head -n2 /etc/passwd | od -t o2
$ head -n2 /etc/passwd | od -t o1
$ head -n2 /etc/passwd | od -t x1
$ head -n2 /etc/passwd | od -t xCz

$ echo abcd | tr 'a-z' 'A-Z'
$ echo abcd | tr '[:lower:]' '[:upper:]'
$ echo żółć | tr '[:lower:]' '[:upper:]'
$ cat /etc/group | tr [-s]  ':' ' '
$ cat /etc/group | tr [-s]  ':' '::'
$ cat /etc/group | tr [-s]  ':x' ':'
$ cat /etc/group | tr -d  ':'
$ tr -s '\n' < /etc/hosts