Uprawnienia do plików i katalogów
Systemy uniksopodobne wywodzą się z systemu Unix, którego głównym założeniem była możliwość współdzielenia zasobów przez użytkowników. Wymusiło to wprowadzenie mechanizmów ochrony dostępów do elementów takich jak pliki, katalogi, czy urządzenia.
Jednym z popularniejszych powiedzeń związanych z systemami uniksopodobnymi jest: wszystko jest plikiem. Konstrukcja systemu sprawia, że rzeczywiste pliki z danymi, katalogi, ale także urządzenia fizyczne, takie jak modemy, dyski, klawiatury czy drukarki, oraz wirtualne, takie jak konsole wirtualne, są dostępne w strukturze plików. Korzystanie z nich (np. zapis do pliku, pisanie przy użyciu klawiatury, wyświetlenie danych w konsoli, wydruk dokumentu) opiera się na przesłaniu strumienia bajtów do odpowiedniego pliku.
Od tej pory pod pojęciem pliku rozumieć będziemy element struktury plików, będący regularnym plikiem, katalogiem, ale też dowolnym innym elementem, do którego można się odwoływać jak do pliku. Jeśli wymagane będzie rozróżnienie, zostanie to wyraźnie zaznaczone.
Korzystanie z elementów struktury plików wymaga od użytkownika posiadania odpowiednich uprawnień. Spójrzmy na przykładowy efekt wywołania polecenia ls -l
:
total 36
-rw-rw---- 1 adam studenci 52 Jul 30 18:17 ges
lrw----rw- 1 tomasz studenci 11 Jul 30 18:17 kaczka
drwx-w---- 2 piotr doktorzy 4096 Jul 30 18:18 kon
drwx--x--x 2 adam magistrzy 4096 Jul 30 18:16 krowa
drwx--x--x 2 adam pracownicy 4096 Jul 30 18:16 malpa
drwx---r-- 2 tomasz doktorzy 4096 Jul 30 18:16 slon
drwx-wx-w- 2 tomasz magistrzy 4096 Jul 30 18:16 swinia
-rw----rwx 1 adam pracownicy 3893 Jul 30 18:17 zebra
-rw--w---- 1 stefan studenci 384 Jul 30 18:17 zyrafa
Opcja -l
polecenia ls
umożliwia nam uzyskanie dostępu do rozbudowanych informacji o plikach znajdujących się w katalogu, na którym operujemy, opisujących kolejno:
- uprawnienia do pliku,
- liczbę dowiązań stałych do pliku,
- nazwę właściciela,
- nazwę grupy,
- rozmiar pliku w bajtach,
- datę ostatniej modyfikacji pliku,
- nazwę pliku.
Jak czytać uprawniania?
W systemach uniksopodobnych wyróżniamy następujące typy plików:
- regularny plik, oznaczany symbolem
-
, - katalog, oznaczany symbolem
d
, - dowiązanie symboliczne, oznaczane symbolem
l
, - $\color{gray!40}{\bigstar}$ urządzenie znakowe, oznaczane symbolem
c
, - $\color{gray!40}{\bigstar}$ urządzenie blokowe, oznaczane symbolem
b
, - $\color{gray!40}{\bigstar}$ gniazdo, oznaczane symbolem
s
, - $\color{gray!40}{\bigstar}$ potok (ang. pipe), oznaczany symbolem
p
, - $\color{gray!40}{\bigstar}$ drzwi, oznaczane symbolem
D
.
Pierwszy znak opisu uprawnień określa rodzaj pliku. Pozostałych 9 znaków opisuje uprawnienia do pliku nadane, odpowiednio, właścicielowi pliku, członkom grupy związanej z plikiem i innym użytkownikom. Mogą oni, niezależnie od siebie, posiadać prawa do:
- odczytu (
r
), - zapisu (
w
), - wykonania (
x
),
pliku. Zbiór pełnych uprawnień do pliku opisujemy ciągiem rwx
, a jeśli któreś z uprawnień nie występuje, jego symbol zastąpiony jest znakiem -
. Tym samym możemy opisać zbiór uprawnień do pliku w jeden z następujących sposobów: ---
, r--
, -w-
, --x
, rw-
, r-x
, -wx
lub rwx
.
O ile w przypadku regularnych plików dość intuicyjnie można zrozumieć znaczenie poszczególnych uprawnień, o tyle w przypadku katalogów uprawnienia te należy interpretować następująco:
- prawo odczytu (
r
) daje możliwość odczytania katalogu, to znaczy wypisania zawartości tego katalogu, - prawo zapisu (
w
) daje możliwość tworzenia, modyfikacji i usuwania elementów wewnątrz tego katalogu, jeśli istnieje prawo wykonania (x
), inaczej nie ma znaczenia, - prawo wykonania (
x
) daje możliwość dostępu do katalogu i plików znajdujących się wewnątrz.
Spójrz raz jeszcze na efekt działania programu ls
:
total 36
-rw-rw---- 1 adam studenci 52 Jul 30 18:17 ges
-rw----rw- 1 tomasz studenci 11 Jul 30 18:17 kaczka
drwx-w---- 2 piotr doktorzy 4096 Jul 30 18:18 kon
drwx--x--x 2 adam magistrzy 4096 Jul 30 18:16 krowa
drwx--x--x 2 adam pracownicy 4096 Jul 30 18:16 malpa
drwx---r-- 2 tomasz doktorzy 4096 Jul 30 18:16 slon
drwx-wx-w- 2 tomasz magistrzy 4096 Jul 30 18:16 swinia
-rw----rwx 1 adam pracownicy 3893 Jul 30 18:17 zebra
-rw--w---- 1 stefan studenci 384 Jul 30 18:17 zyrafa
Określ, które elementy listy są katalogami, a które plikami. Następnie odpowiedz na pytanie, jakie uprawnienia do poszczególnych pozycji listy będzie miał:
- użytkownik
adam
, będący członkiem grupystudenci
, - użytkownik
tomasz
, będący członkiem grupdoktorzy
ipracownicy
, - użytkownik
piotr
, będący członkiem grupymagistrzy
, - użytkownik
stefan
, będący członkiem gruppracownicy
orazmagistrzy
,
Jakie musiały być uprawnienia do każdego z katalogów nadrzędnych, aby możliwe było uzyskanie zaprezentowanej listy?
Każdy z katalogów nadrzędnych musiał mieć prawo do wykonania, a katalog, którego zawartość odczytujemy, także prawo do odczytu. Jeśli katalog, którego zawartość odczytujemy nie ma praw do wykonania, a jedynie do odczytu, wówczas możemy wypisać listę elementów tego katalogu, ale nie uzyskamy dostępu do informacji innych niż nazwy elementów znajdujących się wewnątrz.
W momencie zalogowania się w konsoli wirtualnej lub przez interfejs pseudoterminala, zalogowanemu użytkownikowi nadawane są odpowiednie uprawnienia (w szczególności własność) do odpowiedniego pliku, reprezentującego to urządzenie.
Zaloguj się do serwera lts.wmi.amu.edu.pl
, korzystając z protokołu ssh
. Sprawdź nazwę swojego terminala (who
), a następnie zweryfikuj i zinterpretuj uprawnienia do plików w katalogu /dev/pts
.
Tak naprawdę uprawnienia do plików mogą być o wiele bardziej rozbudowane. Zaawansowane listy dostępu do plików można tworzyć i analizować przy użyciu programów setfacl
oraz getfacl
. Fakt, że takie listy obowiązują w przypadku wybranego pliku, można rozpoznać po dodatkowym symbolu +
, znajdującym się za opisem uprawnień do wybranego pliku.
Czasem zdarza się też, że zamiast symbolu x
, oznaczającego uprawnienia do wykonania pliku, obserwuje się symbol s
lub S
(w przypadku uprawnień właściciela i grupy) oraz t
lub T
(w przypadku innych użytkowników). Symbole te są związane ze specjalnymi uprawnieniami do plików i katalogów, w tym z tak zwanym sticky bit. Więcej informacji można znaleźć na stronach:
Zmiana uprawnień – polecenie chmod
Uprawnienia do plików można modyfikować przy użyciu polecenia chmod
, przy czym na taki przywilej może sobie pozwolić jedynie właściciel pliku i superużytkownik root
.
Utwórz w swoim katalogu domowym plik o nazwie sop.txt
oraz katalog o nazwie sop
. Wykonaj następujące polecenia i sprawdź uzyskane efekty:
$ chmod u-x sop
$ chmod g=rw,o+r sop sop.txt
$ chmod u+X sop sop.txt
$ chmod g=rwx sop.txt
$ chmod u+X sop sop.txt
$ chmod go-r sop sop.txt
Jak działa uprawnienie X
? Korzystając z przedstawionej wyżej notacji symbolicznej:
- odbierz grupie uprawnienia do wykonania pliku
sop.txt
, - wykonując jedno polecenie, dodaj grupie i innym użytkownikom prawo do odczytu pliku
sop.txt
oraz katalogusop
, - odbierz właścicielowi prawo wykonania pliku
sop.txt
.
Uprawnienie X
obejmuje tylko katalogi oraz pliki, które posiadają już jakiekolwiek prawo do wykonywania.
Sprawdź, czy polecenia cp
oraz mv
zachowują domyślnie uprawnienia do plików i katalogów. Jeśli nie, to jak sobie z tym poradzić?
Polecenie mv
zachowuje uprawnienia, a polecenie cp
nie. Aby to zmienić, należy wywołać polecenie cp
z opcją -p
.
Jak już zauważyliśmy, uprawnienia opisuje się oddzielnie dla właściciela (user
), grupy (group
) oraz innych użytkowników (other
). Jeśli rozpatrzyć uprawnienia jako trzybitowe liczby, moglibyśmy zauważyć następującą zależność:
Uprawnienia | Binarnie | Ósemkowo |
---|---|---|
--- | 000 | 0 |
--x | 001 | 1 |
-w- | 010 | 2 |
-wx | 011 | 3 |
r-- | 100 | 4 |
r-x | 101 | 5 |
rw- | 110 | 6 |
rwx | 111 | 7 |
Uprawnienia do pliku możemy więc zapisać w postaci ciągu trzech cyfr ósemkowych (lub po prostu trzycyfrowej liczby ósemkowej).
Zapisz uprawnienia do plików z listingu
total 36
-rw-rw---- 1 adam studenci 52 Jul 30 18:17 ges
-rw----rw- 1 tomasz studenci 11 Jul 30 18:17 kaczka
drwx-w---- 2 piotr doktorzy 4096 Jul 30 18:18 kon
drwx--x--x 2 adam magistrzy 4096 Jul 30 18:16 krowa
drwx--x--x 2 adam pracownicy 4096 Jul 30 18:16 malpa
drwx---r-- 2 tomasz doktorzy 4096 Jul 30 18:16 slon
drwx-wx-w- 2 tomasz magistrzy 4096 Jul 30 18:16 swinia
-rw----rwx 1 adam pracownicy 3893 Jul 30 18:17 zebra
-rw--w---- 1 stefan studenci 384 Jul 30 18:17 zyrafa
w postaci ciągu ósemkowej. Przykładowo, rw-rw----
można zapisać równoważnie jako 660
.
Korzystając z notacji liczbowej, nadaj uprawnienia rw-r----
do pliku tekstowego sop.txt
. W tym celu wykonaj polecenie
$ chmod 640 sop.txt
Analogicznie, nadaj:
- uprawnienia
rwxrwxr--
do plikusop.txt
, - uprawnienia
r-x-wx-wx
do plikusop.txt
, - uprawnienia
-w---x---
do plikusop.txt
, - uprawnienia
r-x------
do katalogusop
,
Utwórz w katalogu sop
pliki a
i b
oraz katalog c
, wewnątrz którego utwórz plik d
. W tym celu nadaj sobie odpowiednie uprawnienia do katalogu sop
. Wykonując jednokrotnie polecenie chmod
, nadaj innym użytkownikom (other
) prawo odczytu wszystkich elementów tej struktury oraz prawo wykonania tylko do katalogów w tej strukturze. Skorzystaj z opcji -R
polecenia chmod
.
$ chmod -R o=rX sop
W wyniku działania pewnego polecenia otrzymano na wyjściu następujący ciąg znaków:
drwx------ 6 adam ludzie 4096 Oct 8 16:11 muchomorek/
- Podaj pełną treść polecenia, które mogło zwrócić taki wynik. Załóż, że element o nazwie
muchomorek
znajduje się w bieżącym katalogu roboczym. - Jakie polecenie należy wykonać, aby dodać członkom grupy
ludzie
prawo do odczytu i wykonania elementumuchomorek
, a pozostałym użytkownikom prawo do jego odczytu? Zaproponuj co najmniej dwa rozwiązania wykorzystujące notację liczbową i symboliczną.
Zmiana właściciela – polecenia chown
i chgrp
Każdy użytkownik systemu posiada swoją unikalną nazwę (login) oraz jedną grupę (group), z którą jest związany. Ponadto, każdy użytkownik może być przypisany do dowolnej liczby innych grup i traktowany jak ich członek.
Korzystając z polecenia id
dowiedz się, jakich grup jesteś członkiem.
Gdy plik jest tworzony, system nadaje status właściciela temu kontu, które go utworzyło. Przypisuje też do pliku główną grupę związaną z właścicielem. Użytkownik posiadający uprawnienia superużytkownika (root
) może zmienić właściciela dowolnego pliku przy użyciu polecenia chown
oraz grupę związaną z plikiem przy użyciu polecenia chgrp
. W nowszych systemach program chown
pozwala na jednoczesną zmianę właściciela i grupy.
Dlaczego tylko użytkownik root
może zmienić właściciela pliku?
Zapoznaj się z konstrukcją poleceń chown
oraz chgrp
. Jeśli masz dostęp do komputera, na którym możesz uzyskać uprawnienia użytkownika root
, przetestuj działanie tych poleceń.
Wiemy już, że użytkownik może być członkiem wielu grup, a uprawnienia do plików mogą być związane z członkostwem w grupie przypisanej do nich. Nic nie stoi więc na przeszkodzie, aby utworzyć w systemie wiele grup i, operując uprawnieniami, uzależnić dostęp do pewnych zasobów systemowych (np. drukarek, urządzeń audio itp.) od członkostwa w danej grupie. To dosyć częste podejście.
Domyślne uprawnienia – umask
Kiedy tworzony jest katalog, domyślnie przypisywane są do niego uprawnienia 777
. W przypadku plików jest to 666
, ponieważ uprawnienia do wykonywania plików powinny być zawsze nadawane ręcznie. Polecenie umask
pozwala na ustawienie maski dopełnień mmm
, dzięki której domyślne uprawnienia będą równe 777 & ~mmm
dla katalogów i 666 & ~mmm
dla pozostałych plików.
Wykonując polecenie
$ umask
określ, jaka maska dopełnień jest stosowana dla katalogów i plików tworzonych przez Ciebie.
Jeśli maska dopełnień jest równa 014
, to uprawnienia do nowo tworzonych katalogów będą równe
777 & ~014 = 111111111 & ~000001100
= 111111111 & 111110011
= 111110011
= 763
a do plików
666 & ~014 = 110110110 & ~000001100
= 110110110 & 111110011
= 110110010
= 662
Określ, jakie będą uprawnienia do nowo utworzonych plików i katalogów, jeśli maska dopełnień jest równa: 000
, 022
, 777
lub 002
.
Wykonując polecenie
$ umask 002
zmień stosowaną maskę dopełnień na 002
. Sprawdź, w jaki sposób wpływa to na uprawnienia do tworzonych plików i katalogów.
Sprawdź, co się stanie, jeśli wykonasz polecenia
$ umask u=,go=wx
$ umask u+r
Jaka maska będzie stosowana po pierwszym, a jaka po drugim wywołaniu? Jakie wnioski można z tego wynieść?
W ramach eksperymentu utworzono katalog zwirek
. Okazało się, że domyślne uprawnienia do niego są równe r-xrw---x
.
- Jaki będzie efekt wywołania polecenia
umask
? - Jakie polecenie należy wykonać, aby domyślne uprawnienia do nowo tworzonych katalogów były równe
rwxr-xr--
?
Dowiązania
Do każdego elementu, w momencie tworzenia go w danym systemie plików, przypisuje się rekord zwany inode (ang. index node, i-węzeł). Rekord ten zawiera informacje o pliku, w tym te zwiazane z jego położeniem na fizycznym nośniku, takim jak partycja dysku twardego. Poszczególne i-węzły są związane z jednoznacznie identyfikującą je liczbą, zwaną numerem i-węzła. Katalog jest plikiem (bo wszystko jest plikiem...) zawierającym listę elementów w postaci <nazwa, numer i-węzła>
. Nazwa pliku lub katalogu odnosi się więc do określonego węzła w określonym systemie plików.
I-węzeł zawiera wiele informacji o pliku – najkrócej można powiedzieć, że wszystkie, poza jego nazwą i zawartością. Szczegółowe omówienie tych zagadnień jednak znacząco wykracza poza materiał tego przedmiotu.[1]
Korzystając z opcji -i
polecenia ls
, poznaj numery i-węzłów, do których odwołują się pliki w Twoim katalogu domowym.
[1] Osoby zainteresowane mogą przeczytać więcej na temat struktury i-węzła na stronie https://pl.wikipedia.org/wiki/I-węzeł.
Dowiązania stałe
Jako że element katalogu jest uporzadkowanym zbiorem elementów postaci <nazwa, numer i-węzła>
, nic nie stoi na przeszkodzie, aby z dwóch miejsc wewnątrz danego systemu plików odwoływać się do tego samego i-węzła. Takie odwołanie nazywamy dowiązaniem stałym (ang. hard link). Właściciel pliku (lub superużytkownik) może je utworzyć przy pomocy polecenia ln
.
Zapoznaj się z dokumentacją polecenia ln
. Następnie utwórz w swoim katalogu domowym plik a.txt
oraz dowiązanie stałe do związanego z nim i-węzła – nazwij je b.txt
. Sprawdź, jak zmieniła się liczba dowiązań stałych wyświetlana przy obu plikach po wywołaniu polecenia ls -l
.
Sprawdź, jak zmieni się zawartość:
- pliku
a.txt
, jeśli zmienisz zawartość plikub.txt
, - pliku
b.txt
, jeśli zmienisz zawartość plikua.txt
.
Dlaczego tak jest?
Sprawdź, jak zmienią się uprawnienia:
- do pliku
a.txt
, jeśli zmienisz uprawnienia do plikub.txt
, - do pliku
b.txt
, jeśli zmienisz uprawnienia do plikua.txt
.
Dlaczego tak jest?
Usuwanie pliku w systemie plików opartym na i-węzłach to nic innego jak usunięcie dowiązania stałego do pliku (stąd usuwanie plików określa się niekiedy pojęciem unlink).
Utwórz w swoim katalogu domowym dowolny katalog. Dlaczego są do niego dwa dowiązania stałe? Jak zmieni się liczba dowiązań stałych do katalogu, jeśli w jego wnętrzu utworzysz: (a) plik, (b) katalog? Dlaczego tak jest?
Spróbuj utworzyć dowiazanie stałe do wybranego katalogu. Czy jest to możliwe? Sprawdź w dokumentacji programu ln
, jak to zrobić i kto może wykonać taką operację.
Dowiązania symboliczne
Użytkownicy systemów z rodziny Windows przyzwyczajeni są do skrótów, które odwołują się do elementów zlokalizowanych w dowolnym miejscu struktury plików. W systemach uniksopodobnych rolę skrótów przejmują dowiązania symboliczne. Dowiązanie takie jest plikiem zawierającym ścieżkę do elementu docelowego.
Korzystając z opcji -s
polecenia ln
utwórz w swoim katalogu domowym dowiązanie symboliczne do pliku /etc/passwd
i nazwij je dowiazanie
. Czy możesz utworzyć dowiązanie stałe do tego samego pliku? Dlaczego?
Po wyświetleniu szczegółowej listy plików w katalogu domowym okaże się, że plik dowiazanie
ma rozmiar 11 bajtów. Od czego zależy ten rozmiar? Utwórz kilka dowiązań symbolicznych (z wykorzystaniem ścieżek względnych i bezwzględnych) i porównaj otrzymane wyniki.
Utwórz dowiązanie symboliczne do dowolnego katalogu. Spróbuj zmienić nań katalog roboczy wykorzystując polecenie cd
. W jaki sposób zachowuje się powłoka?
Powłoka traktuje dowiązanie symboliczne tak jak element istniejący w systemie plików.
Sprawdź, jakie uprawnienia posiadasz do utworzonych dowiązań symbolicznych. Jak zinterpretować te uprawnienia? Jak się do tego ma maska ustawiona przy użyciu polecenia umask
?
Uprawnienia do utworzonych dowiązań symbolicznych są równe 777
, aby pokryć wszelkie potencjalne uprawnienia elementu docelowego. Odwołanie się do dowiązania symbolicznego, do którego nie mamy prawa odczytu, zakończy się niepowodzeniem, nawet jeśli posiadamy odpowiednie uprawnienia do elementu docelowego.
Spróbuj utworzyć dowiązanie symboliczne do elementu, który nie istnieje. Czy jest to możliwe?
Tak, chociaż powłoka może zwrócić na to uwagę, np. kolorując na czerwono nazwę tego dowiązania na szczegółowej liście elementów zawartych w katalogu.
Wejście i wyjście
Kiedy w systemie uniksopodobnym uruchamiany jest program, tworzone są trzy kanały komunikacji pomiędzy tym programem a środowiskiem, w którym jest on uruchamiany (zwykle terminalem). Kanały te to:
- standardowy strumień wejścia (ang. standard input,
stdin
), - standardowy strumień wyjścia (ang. standard output,
stdout
), - standardowy strumień błędów (ang. standard error,
stderr
).
Relacja pomiędzy programem a powyższymi strumieniami zaprezentowana została na poniższym rysunku.
Gdy program uruchamia się, otwierany jest kanał komunikacji pomiędzy nim a standardowymi strumieniami. Program odwołuje się do nich przez unikalny identyfikator, będący liczbą całkowitą. Identyfikator ten nazywamy deskryptorem pliku. Po uruchomieniu programu zdefiniowane są trzy deskryptory plików:
- 0, dla strumienia
stdin
, - 1, dla strumienia
stdout
, - 2, dla strumienia
stderr
.
Sprawdź, do czego odwołują się pliki urządzeń: /dev/stdin
, /dev/stdout
oraz /dev/stderr
.
Sprawdź, jak działają funkcje systemowe języka C: open
, read
oraz write
. Co zwraca funkcja open
? W jaki sposób deskryptor pliku wiąże się z funkcjami read
oraz write
?
Domyślnie, zarówno standardowe wejście, jak i oba wyjścia związane są z terminalem (konsolą lub wirtualną konsolą). W praktyce oznacza to, że do strumienia standardowego wejścia trafią wszystkie znaki wprowadzane za pomocą klawiatury,* a każdy znak przesłany przez program do standardowego strumienia wyjścia lub strumienia błędów zostanie wyświetlony w terminalu.
* Zaawansowani użytkownicy zdają sobie pewnie sprawę z tego, że to stwierdzenie nie jest do końca poprawne. W rzeczywistości większość programów powłoki buforuje dane przed przesłaniem ich do standardowego wejścia, czekając na znak końca linii lub końca pliku.
Potoki i polecenie tee
Czasem zachodzi potrzeba, aby standardowe wyjście jednego z programów było traktowane jako standardowe wejście drugiego. Idea ta została zwizualizowana na poniższym rysunku. Taki przepływ danych nazywamy potokiem.
W powłoce Bash potok wprowadza się przy użyciu symbolu |
.
Korzystając z mechanizmu potokowania, wyświetl przy pomocy programu less
(poznanego przy okazji eksplorowania podręczników programów) szczegółową listę elementów znajdujących się w katalogu /etc
. W tym celu wykonaj polecenie:
$ ls -l /etc | less
Mechanizm potokowania nie czeka na zakończenie działania jednego programu przed uruchomieniem drugiego. Tak naprawdę przepływ danych pomiędzy odpowiednimi strumieniami stdout
oraz stdin
odbywa się w czasie rzeczywistym (buforowanym linia po linii, podobnie jak w przypadku standardowego wejścia z klawiatury). Łatwo to zweryfikować wykonując polecenie:
$ for I in {1..50}; do echo $I; sleep 0.2; done | less
Wśród ciekawych programów związanych z obsługą potoków warto wymienić program o nazwie tee
. Jego działanie jest następujące: dane ze standardowego wejścia przesyła on do standardowego wyjścia, zapisując je po drodze we wskazanym pliku.
Zmodyfikuj polecenie z poprzedniego ćwiczenia tak, aby lista elementów z katalogu /etc
została dodatkowo zapisana w pliku lista-etc
w Twoim katalogu domowym.
$ ls -l /etc | tee lista-etc | less
Łączenie plików – polecenia cat
i tac
Polecenie cat
wypisuje przez standardowy strumień wyjścia, bajt po bajcie, zawartość plików, których nazwy przekazane są do niego jako argumenty. Jeśli polecenie cat
zostanie wywołane bez argumentów, wypisuje przez standardowy strumień wyjścia dane ze standardowego strumienia wejścia.
Wykonaj polecenie:
$ cat ~/lista-etc /etc/passwd
Zweryfikuj otrzymane efekty.
Wywołaj polecenie cat
bez argumentów. Wprowadź kilka wierszy tekstu – każdy z nich zakończ wciśnięciem klawisza Enter. Wprowadzanie danych zakończ kombinacją klawiszy Ctrl + D (znak końca pliku). W jaki sposób zachowuje się program cat
?
Polecenie tac
ma działanie zbliżone do cat
z tą różnicą, że wiersze plików, których nazwy przekazane są jako argumenty, wypisuje w odwrotnej kolejności (a więc od ostatniego do pierwszego). Jeśli polecenie tac
zostanie wywołane bez argumentów, wypisze ono dane ze standardowego wejścia począwszy od ostatniego wiersza.
Wykonaj polecenie:
$ tac ~/lista-etc /etc/passwd
Zweryfikuj otrzymane efekty.
Wywołaj polecenie tac
bez argumentów. Wprowadź kilka wierszy tekstu – każdy z nich zakończ wciśnięciem klawisza Enter. Wprowadzanie danych zakończ kombinacją klawiszy Ctrl + D (znak końca pliku). W jaki sposób zachowuje się program tac
? Dlaczego, w przeciwieństwie do programu cat
, dane są wysyłane do standardowego wyjścia dopiero po natrafieniu przez program tac
na znak końca pliku?
Czy istnieje istotna różnica pomiędzy wywołaniami poniższych poleceń?
$ cat /etc/passwd | tac
$ tac /etc/passwd | cat
$ tac /etc/passwd
Polecenia head
, tail
, sort
, grep
w potokach
Istnieje cała gama programów, które wypisują na standardowym wyjściu przetworzoną lub przefiltrowaną zawartość wskazanych plików lub danych ze standardowego wejścia (takie programy nazywamy filtrami). Ta ostatnia własność ma dość praktyczne znaczenie w połączeniu z mechanizmem potoków.
O zachowaniu wymienionych dalej programów będziemy mówić w kontekście operowania na danych pochodzących ze standardowego wejścia. Każdy z nich radzi sobie jednak równie dobrze z plikami – wystarczy podać ich nazwy jako argumenty.
Program head
wypisuje 10 pierwszych linii ze standardowego wejścia. Przydatne opcje:
-c XX | wypisz XX pierwszych bajtów |
-n XX | wypisz XX pierwszych linii |
-c -XX | wypisz wszystkie poza ostatnimi XX bajtami |
-n -XX | wypisz wszystkie poza ostatnimi XX liniami |
Czy istnieje istotna różnica pomiędzy wywołaniami poniższych poleceń?
$ cat ~/lista-etc | head -n 5
$ head -n 5 ~/lista-etc
$ head ~/lista-etc -n 5
Wypisz:
- cztery pierwsze linie pliku
~/.bash_history
, - pierwszych 13 bajtów pliku
~/lista-etc
, - wszystkie poza ostatnimi dwoma liniami pliku
/etc/passwd
.
Program tail
wypisuje 10 ostatnich linii ze standardowego wejścia. Przydatne opcje:
-c XX | wypisz XX ostatnich bajtów |
-n XX | wypisz XX ostatnich linii |
-c -XX | wypisz wszystkie poza pierwszymi XX bajtami |
-n -XX | wypisz wszystkie poza pierwszymi XX liniami |
-c +XX | wypisz wszystkie bajty, począwszy od XX -tego |
-n +XX | wypisz wszystkie linie, począwszy od XX -tej |
-f | aktualizuj wynik w miarę jak dane spływają do standardowego wejścia |
Wypisz czwartą i piątą linię pliku ~/lista-etc
. Zaproponuj kilka dróg do otrzymania pożądanego efektu.
$ cat lista-etc | head -n 5 | tail -n 2
$ head -n 5 lista-etc | tail -n 2
Jaki będzie efekt wywołania polecenia
$ head -n -2 plik | tail -n +3
gdzie plik
jest dowolnym plikiem?
Czy istnieje istotna różnica pomiędzy wywołaniami poniższych poleceń?
$ tail -n 5 -f ~/lista-etc
$ tail --lines=5 --follow ~/lista-etc
$ tail --lines=5 -f ~/lista-etc
Program sort
sortuje alfabetycznie (w kolejności rosnącej) linie tekstu ze standardowego wejścia. Przydatne opcje:
-f | traktuj małe i wielkie litery równoważnie |
-n | traktuj linie jak liczby |
-R | posortuj linie losowo |
-r | sortuj malejąco |
-k X | przy sortowaniu uwzględniaj dane od X -tej kolumny |
-k X,Y | przy sortowaniu uwzględniaj dane z kolumn o indeksach od X do Y |
-t X | traktuj X jako separator kolumn |
Wypisz informacje o ośmiu największych elementach, znajdujących się bezpośrednio w Twoim katalogu domowym.
$ ls -l ~ | tail -n +2 | sort -k 5 -nr | head -n 8
Jaki będzie efekt wywołania polecenia
$ ls -l | tail -n +2 | sort -k 2 -n -r | head -n 3
w dowolnym katalogu?
Program grep
wypisuje na wyjściu tylko te linie ze standardowego wejścia, które odpowiadają zadanemu wyrażeniu regularnemu. Przydatne opcje:
-i | traktuj małe i wielkie litery równoważnie |
-v | wypisuj na wyjściu tylko te linie, które nie spełniają zadanego wyrażenia regularnego |
-w | wypisuj na wyjściu tylko te linie, które zawierają słowo spełniające zadane wyrażenie regularne |
-c | wypisz na wyjściu liczbę linii spełniających wyrażenie |
-q | nic nie wypisuj i zwróć 0 w chwili znalezienia dopasowania |
Zasady konstrukcji wyrażeń regularnych:
. | dowolny znak, poza znakiem nowej linii |
^ | początek linii |
$ | koniec linii |
[abc] | dowolny z wyliczonych znaków |
[a-z] | dowolny znak ze zbioru |
[^0-9] | dowolny znak z dopełnienia zbioru |
[abc]* | ciąg znaków a, b i c dowolnej długości (również pusty) |
[abc]+ | ciąg znaków a, b i c dowolnej niezerowej długości |
[abc]? | maksymalnie jednokrotne wystąpienie elementu a, b lub c |
[abc]\{n\} | ciąg znaków a, b i c długości n |
[abc]\{n,\} | ciąg znaków a, b i c długości co najmniej n |
[abc]\{,m\} | ciąg znaków a, b i c długości co najwyżej m |
[abc]\{n,m\} | ciąg znaków a, b i c długości od n do m |
\| | alternatywa |
\( \) | nawiasy grupujące |
Jaki będzie efekt działania poniższego polecenia?
$ ls -l ~ | grep '^drwx\(r..\)\{2\}.*[a-zA-Z]\{5\}\(ry\|op\)$'
Wykonaj poniższe zadania. Posłuż się poznanymi dotąd poleceniami i metodami.
- Odpowiedz, ile elementów znajdujących się w katalogu
/dev
jest dowiązaniami symbolicznymi? - Plik
~/.bash_history
zawiera historię wykonywanych poleceń w kolejności od najdawniej wykonanego. Wypisz, począwszy od najświeższego, 3 wykonane ostatnio polecenia rozpoczynające się od słowacat
lubls
.
Uwaga: zawartość pliku~/.bash_history
jest aktualizowana w momencie zakończenia sesji konsoli. Można to jednak zrobić ręcznie, wykonując poleceniehistory -a
. - Wyświetl, posortowaną malejąco według nazw, szczegółową listę ośmiu największych elementów znajdujących się w katalogu
/bin
. - Posortuj szczegółową listę elementów z katalogu
/etc
malejąco według liczby dowiązań stałych. Jeśli dwa lub więcej elementów ma taką samą liczbę dowiązań stałych, powinny być posortowane według rozmiaru malejąco. Uwzględnij tylko te elementy, które mogą być odczytane przez osoby inne niż właściciel i członkowie wskazanej grupy.
$ ls -l /dev | tail -n +2 | grep '^l' | wc -l
$ tac .bash_history | grep '^\(cat\|ls\)' | head -n 3
$ ls -l /bin | tail -n +2 | sort -k5 -rn | head -n8 | sort -k9 -r
$ ls -l /etc | tail -n +2 | sort -rn -k2 -k5 | grep '^.\{7\}r'
Przeadresowywanie wejścia/wyjścia
Jak już wiemy, w momencie uruchamiania programu tworzone są trzy kanały komunikacyjne pomiędzy nim a środowiskiem, w którym jest wykonywany. Są to stdin
(o numerze 0), stdout
(o numerze 1) oraz stderr
(o numerze 2). I choć domyślnie każdy z tych kanałów prowadzi do pliku urządzenia terminala, możemy – korzystając z funkcjonalności powłoki – przekierować (przeadresować) wejście/wyjście, wskazując inny plik. Służą do tego metasymbole powłoki: >
, >>
, <
oraz <<
. Pierwsze dwa służą do przekierowywania wyjścia, kolejne zaś do przeadresowywania wejścia.
Konstrukcja N>
pozwala przekierować dane wyjściowe związane z deskryptorem pliku o numerze N
do dowolnego innego pliku w systemie. Jeśli N
nie jest określone, przyjmuje się, że wynosi 1 (a więc jest związane z stdout
). Jeśli plik docelowy nie istnieje, zostanie utworzony, jeśli zaś istnieje, zostanie nadpisany.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ ls -la 1> wynik.txt
$ ls -l > wynik.txt
Skomentuj efekty.
Wykonaj w swoim katalogu domowym następujące polecenie:
$ ls -l | sort -k 5 -n | head -n 5 > wynik.txt
Skomentuj efekty.
Korzystając z polecenia cat
i przeadresowania wyjścia, utwórz w swoim katalogu domowym plik o dowolnej treści.
Łatwo się domyślić, że przekierowania danych przesyłanych do pliku określonego deskryptorem o numerze 2 (a więc stderr
) można dokonać korzystając z konstrukcji 2>
.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ cat /etc/shadow > wynik.txt
$ cat /etc/shadow > wynik.txt > wynikb.txt
$ cat /etc/shadow 2> wynik.txt
$ cat /etc/shadow /etc/passwd > wynik.txt 2> wynik.err
$ cat /etc/shadow /etc/passwd 1> wynik.txt 2> wynik.err
$ cat /etc/shadow /etc/passwd 2> wynik.err 1> wynik.txt
Skomentuj efekty.
Aby przekierować jednocześnie wszystkie dane wychodzące z programu, niezależnie od tego, z którym deskryptorem pliku są związane, można skorzystać z konstrukcji &>
.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ cat /etc/shadow /etc/passwd 1> wynik.txt 2> wynik.err
$ cat /etc/shadow /etc/passwd &> wynik.txt
Skomentuj efekty.
Przesyłać dane można też pomiędzy plikami związanymi z różnymi deskryptorami. Wymaga to jednak poprzedzenia numeru deskryptora docelowego znakiem &
.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ cat /etc/shadow /etc/passwd 2>1
$ cat /etc/shadow /etc/passwd 2>&1
$ cat /etc/shadow /etc/passwd 2>&1 > wynik.txt
$ cat /etc/shadow /etc/passwd 2>&1 1> wynik.txt
$ cat /etc/shadow /etc/passwd 1> wynik.txt 2>&1
Skomentuj efekty.
Polecenie cat /etc/shadow /etc/passwd 2>&1 > wynik.txt
wypisuje na ekranie błąd, podczas gdy cat /etc/shadow /etc/passwd 1> wynik.txt 2>&1
przekierowuje wyjście zgodnie z oczekiwaniami.
Korzystając z metasymbolu powłoki <
możemy przekierować dane z dowolnego pliku do wejścia programu.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ cat < /etc/passwd
$ cat 0< /etc/passwd
$ cat < /etc/shadow
$ cat < /etc/shadow 2> wynik.err
$ cat 2> wynik.err < /etc/shadow
Skomentuj efekty. Co, według Twojej intuicji, oznacza konstrukcja 0<
?
Zastosowanie konstrukcji N>
do przeadresowania wyjścia związanego z deskryptorem o numerze N
powodowało, że plik docelowy był nadpisywany. Zastosowanie w całości analogicznej konstrukcji N>>
powoduje, że dane wyjściowe zostaną dopisane na końcu wskazanego pliku, chyba że ten nie istnieje – wówczas zostanie utworzony.
Wykonaj w swoim katalogu domowym następujące polecenia:
$ ls ~ > lista.txt
$ ls /home >> lista.txt
Skomentuj efekty.
Wynik działania polecenia ls
będzie się różnił w zależności od tego, czy dane będą wypisywane w terminalu, czy przekierowane do pliku (lub innego programu przez mechanizm potokowania). Wynika to z faktu, że mechanizm przekierowania wejścia/wyjścia modyfikuje docelowe pliki związane z danymi deskryptorami. Tym samym program może weryfikować, czy dany deskryptor odwołuje się do pliku terminala.
W przypadku mechanizmu potokowania, dane wyjściowe przesyłane są do kolejnego programu w potoku za pośrednictwem pliku tymczasowego typu gniazdowego (ang. socket), a nie terminala. Dlatego też polecenia
$ ls
$ ls | cat
dadzą inne rezultaty.
Konstrukcja <<
nie działa tak, jak można by się spodziewać. Dowiedz się, jakie znaczenie ma ten metasymbol i przetestuj jego działanie.
Podpowiedź: https://en.wikipedia.org/wiki/Here_document.
Dowiedz się, jakie znaczenie ma metasymbol <<<
i przetestuj jego działanie.
Metasymbol <<<
pozwala traktować przekazany ciąg znaków jako standardowe wejście.
Mechanizm przeadresowywania wyjścia pozwala także na przekazywanie wyjścia do innego terminala (bo terminal też jest plikiem).
Zaloguj się do dwóch terminali i odnajdź związane z nimi pliki w katalogu /dev
. W jednej z konsol uruchom program cat
, w drugiej wykonaj dowolne polecenie, a wynik przekieruj do pierwszej z konsol. Czy istnieje różnica pomiędzy zastosowaniem przekierowania z użyciem metasymbolu >>
a >
?
Kilka przypatnych poleceń
Program bc
to proste narzędzie do wykonywania operacji arytmetycznych. Obsługuje wiele operatorów matematycznych, w tym operatory arytmetyczne i logiczne, funkcji matematycznych, instrukcji warunkowych i pętli. Konstrukcja wyrażeń jest zbliżona do tej znanej z języka C.
Korzystając z programu bc
z opcją -l
(dołącza biblioteki matematyczne), oblicz (z dokładnością do 10 miejsc po przecinku) wartość wyrażenia $e^{\sqrt{7}-1}+5e$.
scale=10; e(sqrt(7)-1)+5*e(1)
Korzystając z programu bc
z opcją -l
, oblicz wartość liczby $\pi$ z dokładnością do 1000 miejsc po przecinku. Wykorzystaj fakt, że $\frac{\pi}{4} = \arctan(1)$.
scale=1000; a(1)*4
Program cal
pozwala na wyświetlenie kalendarza w formie tekstowej.
Zapoznaj się z podręcznikiem programu cal
. Następnie wyświetl:
- kalendarz na rok 2016,
- kalendarz trójdzielny dla miesiąca grudnia (listopad 2015, grudzień 2015 i styczeń 2016),
- kalendarz dla bieżącego miesiąca i trzech poprzednich oraz pięciu kolejnych miesięcy.
(a) $ cal -y 2016
, (b) $ cal -3 -d 2015-11
, (c) $ cal -A 5 -B 3
.
Program clear
pozwala na oczyszczenie ekranu.
Przetestuj działanie programu clear
.
Dowiedz się, jak działa program clear
. W tym celu możesz sprawdzić, przekierowując potokiem do programu hexdump
dane ze standardowego wyjścia programu clear
, jakie znaki specjalne wypisuje on na wyjściu.
Program date
pozwala wyświetlić lub ustawić datę systemową. Przydatne opcje:
-d "X" | nadpisz bieżącą datę datą X |
-s "X" | ustaw bieżący czas na X |
-u | używaj czasu UTC |
Program obsługuje też wiele możliwości formatowania wyjścia, z którymi można się zapoznać w jego dokumentacji.
Wykonaj następujące polecenia:
$ date
$ date -d '2 Nov'
$ date -d '2 Nove'
$ date -d '2 Nov 2013'
$ date -d 'Nov 2 2014'
$ date -d '2 Jan 2017 10:54'
$ date -d 'Jan 2 2017 10:54:12'
Zastanów się nad efektami.
Korzystając z formatowania wyjścia, wyświetl datę zgodnie ze wzorami
Dzisiaj jest 215. dzien roku.
20150803152847
Biezacy rok to 20 stuleci i 15 lat.
$ date +"Dzisiaj jest %j. dzien roku."
$ date +"%Y%m%d%H%M%S"
$ date +"Biezacy rok to %C stuleci i %y lat."
Ile sekund minęło od 12 stycznia 2013 r., godz. 10:23:17, do 10 września 2014 r., godz. 11:12:43?
52357766
$ echo `date -d "2014-09-10 11:12:43" +"%s"` - \
`date -d "2013-01-12 10:23:17" +"%s"` | bc
Procesy
Na początku poprzednich ćwiczeń dowiedzieliśmy się już, co się dzieje, zanim rozpocznie się sesja powłoki i że w momencie poprawnego zalogowania uruchamiany jest program powłoki (np. bash
). W systemach uniksopodobnych panuje hierarchiczna struktura procesów. Oznacza to, że każdy proces (program) ma dokładnie jednego rodzica (proces, który go wywołał), a procesem-korzeniem całej struktury jest init
.
W praktyce oznacza to, że każdy program uruchamiany z poziomu powłoki staje się jej podprocesem, a jeśli ten uruchamia kolejne procesy, drzewo procesów się rozrasta.
Użytkownik systemu może dotrzeć do listy procesów uruchomionych aktualnie w systemie. W zależności od jego konfiguracji, może się okazać, że lista ta jest ograniczona jedynie do procesów, których właścicielem jest zalogowany użytkownik. Tak jest, procesy – podobnie jak pliki – mają właścicieli.
Polecenia ps
i pstree
Program ps
służy do wyświetlania listy aktualnie uruchomionych procesów. Obsługuje ono zarówno uniksowy (ze znakiem -
), jak i pochodzący z BSD (bez znaku -
) sposób przekazywania opcji. W przypadku tego programu stosuje się powszechnie styl BSD. Wynika to z faktu, że program ps
nie przyjmuje argumentów innych niż opcje. Ważniejsze z nich to:
a | wyświetla tylko procesy związane z jakimś terminalem lub wszystkie procesy, jeśli połączone z opcją x |
x | wyświetla tylko procesy bieżącego użytkownika lub wszystkie procesy, jeśli połączone z opcją a |
u | wyświetl listę procesów w sposób szczegółowy |
Serwer lts.wmi.amu.edu.pl
nie pozwala uzyskać dostępu do informacji o procesach innych użytkowników. Należy więc obejść się smakiem.
Korzystając z dokumentacji programu ps
dowiedz się, na czym polega notacja uniksowa, BSD i GNU związana z przekazywaniem opcji do programu. Gdzie spotkaliśmy się wcześniej z tym podziałem?
Rozpocznij kilka sesji powłoki na lokalnym komputerze lub za pośrednictwem protokołu ssh
. Uruchom jakieś programy (np. less
lub sleep
), a następnie sprawdź działanie przedstawionych wyżej opcji programu ps
wykonując polecenia:
$ ps
$ ps a
$ ps au
$ ps aux
Korzystając z polecenia pstree
można obejrzeć drzewo procesów, a więc zależności pomiędzy poszczególnymi procesami aktualnie uruchomionymi w systemie.
Zapoznaj się z poleceniem pstree
. Przetestuj jego działanie. Wybierz samodzielnie, korzystając z dokumentacji programu, kilka opcji i sprawdź ich działanie w praktyce.
Sygnały, procesy w tle i na pierwszym planie
Każdy program uruchomiony w powłoce wykonuje się w tej powłoce na pierwszym planie (to znaczy absorbuje powłokę). Kiedy uruchamiamy program cat
, wchodzi on z nami w interakcję na poziomie powłoki. Dopóki nie zakończy się jego działanie, nie możemy wykorzystać powłoki w inny sposób, np. aby uruchomić inny program.
W rzeczywistości zdecydowana większość programów obsługuje poprawnie tak zwane sygnały, które wpływają na zachowanie programu. Szczegóły dotyczące tej tematyki będą poruszane na wykładzie, nas jednak interesuje to, że z poziomu powłoki możemy takie sygnały wysłać.
Gdy program się wykonuje w powłoce, możemy wysłać do niego sygnał SIGINT
(interrupt), korzystając z kombinacji klawiszy Ctrl + C (oznaczanej jako ^C
). Sygnał ten oznacza, że program powinien przerwać wykonywane zadanie i zakończyć się niezwłocznie. Podobnie, korzystając z kombinacji klawiszy Ctrl + Z (^Z
), możemy wysłać do programu sygnał SIGSTP
(stop), który powoduje wstrzymanie programu i powrót do powłoki. Proces taki nie kończy się jednak.
Uruchom dowolny program (np. cat
), a następnie wciśnij kombinację klawiszy Ctrl + C. Sprawdź, jaki będzie efekt wywołania polecenia ps
. Podobny eksperyment wykonaj dla kombinacji klawiszy Ctrl + Z. Zinterpretuj wyniki.
Można kontynuować wykonywanie wstrzymanego procesu. Polecenie fg
powoduje, że ostatni wstrzymany proces powróci do powłoki i będzie w niej kontynuowany. Polecenie bg
powoduje zaś, że ostatni wstrzymany proces zostanie przywrócony w tle. Polecenie jobs
pozwala zobaczyć listę aktualnie wykonywanych programów wraz z ich statusami.
Wykonaj następujące czynności i zaobserwuj efekty:
$ sleep 100
^Z
$ sleep 90
^Z
$ sleep 80
^Z
$ jobs
$ bg
$ jobs
$ fg %1
^C
$ jobs
$ fg
^C
Co oznacza polecenie fg %1
? Wywołaj polecenie jobs
, gdy wykonywanie polecenia sleep 80
zakończy się. Wywołaj je ponownie. Co się stało?
Przy pierwszym wywołaniu polecenia jobs
po zakończeniu procesu z listy, wyświetli się informacja o jego zakończeniu (Done
).
Proces można od razu uruchomić w tle. Wystarczy zakończyć jego wywołanie znakiem &
.
Uruchom w tle program sleep
z argumentem 240
. W tym celu wykonal polecenie
$ sleep 240 &
Sprawdź, co się stało, korzystając z poleceń ps
, pstree
oraz jobs
. Przenieś uruchomiony program na pierwszy plan i zakończ, wysyłając sygnał SIGINT
.
Zabijanie procesów – polecenia kill
i killall
Każdy proces w momencie uruchomienia otrzymuje nazwę oraz swój indywidualny i niepowtarzalny numer. Numer ten nazywamy identyfikatorem procesu i oznaczamy skrótem PID
.
Korzystając z programu ps
dowiedz się, jakie identyfikatory mają aktualnie uruchomione programy.
Program kill
pozwala wysłać sygnał do programów o wskazanych identyfikatorach. Domyślnie jest to sygnał SIGTERM
.
Dowiedz się, jakie inne sygnały można przesłać do programu za pomocą programu kill
i jak to zrobić.
<pid> [...]
Send signal to every <pid> listed.
-<signal>
-s <signal>
Uruchom w tle program sleep
z argumentem 240
. Dowiedz się, jaki identyfikator ma utworzony proces, a następnie zakończ go używając polecenia kill
.
Polecenie killall
pozwala na zakończenie procesu o określonej nazwie, przekazanej jako argument.
Uruchom w tle program sleep
z argumentem 240
. Wykonaj następujące polecenia:
$ killall sle
$ killall sleep
Zaobserwuj efekty. Czy polecenie $ killall sle*
zadziała tak, jak można się spodziewać?
Polecenie time
Program time
pozwala zmierzyć czas wykonywania polecenia.
Korzystając z programu time
dowiedz się, jak wiele czasu potrzebuje komputer na wykonanie polecenia
$ ls -la /etc
Zinterpretuj wartości real
, user
oraz sys
.
Czas sys
okresla czas procesora związany z wykonywaniem operacji na poziomie jądra, user
ten związany z wykonywaniem operacji poza jądrem, a real
rzeczywisty czas od rozpoczęcia do zakończenia wykonywania programu.
W oparciu o rozwiązanie poprzedniego ćwiczenia, skonstruuj polecenie, które na standardowym wyjściu wypisuje wyłącznie rzeczywisty czas wykonania badanego polecenia w sekundach, na przykład:
0.015
Upewnij się, że polecenie będzie działać poprawnie również gdy badane polecenie będzie się wykonywać ponad minutę.
$ TIMEFORMAT='%E'
$ time "ls" &> /dev/null