Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Poprzednia wersja Nowa wersja | Poprzednia wersja | ||
so:shell_constructs [2023/05/15 15:04] jkonczak [Parametry pozycyjne] |
so:shell_constructs [2025/05/19 15:58] (aktualna) jkonczak [read] |
||
---|---|---|---|
Linia 39: | Linia 39: | ||
~~Zadanie.#~~ Wpisz do pliku ''//plik//'' kolejno: | ~~Zadanie.#~~ Wpisz do pliku ''//plik//'' kolejno: | ||
- | \\ • ''#!/bin/ls -la'' | + | <html><div style="margin-top:-1.4em"></div></html> |
- | \\ • ''#!/usr/bin/bat'' | + | * ''#!/bin/ls -la'' |
- | \\ • ''#!/usr/bin/env cowsay'' | + | * ''#!/usr/bin/bat'' |
- | \\ • ''#!/bin/rm'' | + | * ''#!/usr/bin/env cowsay'' |
- | \\ Nadaj uprawnienia wykonania dla ''//plik//''u i wykonaj go (z każdym kolejnym | + | * ''#!/bin/rm'' |
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
+ | Nadaj uprawnienia wykonania dla ''//plik//''u i wykonaj go (z każdym kolejnym | ||
shebangiem). | shebangiem). | ||
Linia 72: | Linia 74: | ||
===== Parametry pozycyjne (argumenty) i specjalne ===== | ===== Parametry pozycyjne (argumenty) i specjalne ===== | ||
- | [[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05|Parametry]] | + | [[https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_05|Parametry]] |
to (omawiane wcześniej) zmienne oraz parametry pozycyjne i specjalne. | to (omawiane wcześniej) zmienne oraz parametry pozycyjne i specjalne. | ||
\\ | \\ | ||
Linia 107: | Linia 109: | ||
++++ | ++++ | ||
- | Komendą **''[[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#shift|shift]]''** | + | Komendą **''[[https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#shift|shift]]''** |
można usunąć pierwszy parametr i zmniejszyć pozostałym numery o jeden. | można usunąć pierwszy parametr i zmniejszyć pozostałym numery o jeden. | ||
Linia 118: | Linia 120: | ||
Odnoszące się do parametry pozycyjnych: | Odnoszące się do parametry pozycyjnych: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
| **''$#''** | ilość parametrów pozycyjnych | | | **''$#''** | ilość parametrów pozycyjnych | | ||
| ''$*'' \\ ''$@'' | parametry pozycyjne poddane dzieleniu na tokeny | | | ''$*'' \\ ''$@'' | parametry pozycyjne poddane dzieleniu na tokeny | | ||
Linia 147: | Linia 150: | ||
Pozostałe: | Pozostałe: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
| **''$0''** | w skrypcie nazwa uruchamianego skryptu; w innym razie nazwa powłoki | | | **''$0''** | w skrypcie nazwa uruchamianego skryptu; w innym razie nazwa powłoki | | ||
| **''$$''** | identyfikator procesu powłoki | | | **''$$''** | identyfikator procesu powłoki | | ||
Linia 182: | Linia 186: | ||
~~Zadanie.#~~ | ~~Zadanie.#~~ | ||
Napisz skrypt który wyświetli w kolejnych liniach: | Napisz skrypt który wyświetli w kolejnych liniach: | ||
- | \\ • wartość parametru ''$0'', | + | <html><div style="margin-top:-1.4em"></div></html> |
- | \\ • swój PID, | + | * wartość parametru ''$0'', |
- | \\ • ilość argumentów, | + | * swój PID, |
- | \\ • listę argumentów. | + | * ilość argumentów, |
+ | * listę argumentów. | ||
~~Zadanie.#~~ | ~~Zadanie.#~~ | ||
Linia 205: | Linia 210: | ||
Instrukcja warunkowa ma składnię: | Instrukcja warunkowa ma składnię: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<html><pre style="margin:0"> | <html><pre style="margin:0"> | ||
<b>if</b> <i>polecenie1</i> | <b>if</b> <i>polecenie1</i> | ||
Linia 221: | Linia 227: | ||
Gałęzie ''elif'' i ''else'' są opcjonalne, ''elif'' może pojawiać się | Gałęzie ''elif'' i ''else'' są opcjonalne, ''elif'' może pojawiać się | ||
wielokrotnie. | wielokrotnie. | ||
+ | |||
+ | Żadna gałąź nie może zostać pusta; jeżeli potrzebna jest gałąź bez | ||
+ | instrukcji, można wstawić w nią komendę | ||
+ | **''[[https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_17|:]]''** | ||
+ | lub ''[[https://pubs.opengroup.org/onlinepubs/9799919799/utilities/true.html|true]]''. | ||
Przykład bez używania znaków nowej linii: | Przykład bez używania znaków nowej linii: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
if grep -q ^user: /etc/passwd; then echo "'user' present"; elif grep -q ^student: /etc/passwd; then echo "'user' absent, 'student' present"; else echo "neither present"; fi | if grep -q ^user: /etc/passwd; then echo "'user' present"; elif grep -q ^student: /etc/passwd; then echo "'user' absent, 'student' present"; else echo "neither present"; fi | ||
Linia 269: | Linia 281: | ||
|''[ "$X" -gt "$Y" ]''|liczba ''"$X"'' jest większa ''"$Y"''| | |''[ "$X" -gt "$Y" ]''|liczba ''"$X"'' jest większa ''"$Y"''| | ||
|''[ "$X" -ge "$Y" ]''|liczba ''"$X"'' jest większa bądź równa ''"$Y"''| | |''[ "$X" -ge "$Y" ]''|liczba ''"$X"'' jest większa bądź równa ''"$Y"''| | ||
+ | |||
+ | Uwaga: komenda ''test'' wykonująca porównanie arytmetyczne kończy się błędem | ||
+ | jeżeli którykolwiek z argumentów nie jest liczbą. \\ | ||
+ | <small> | ||
+ | Dlatego np. użycie do sprawdzenia argumentów | ||
+ | ''if [ "$1" -gt "$2" ]; then exit 1; fi'' da inny efekt niż | ||
+ | ''if ! [ "$1" -le "$2" ]; then exit 1; fi'' – dla argumentów będących liczbą obie | ||
+ | wersje działają tak samo, ale pierwsza przepuści też argumenty niebędące liczbą. | ||
+ | Zważ że ''!'' neguje komendę, a nie porównanie. | ||
+ | </small> | ||
=== Testy plików (wybór) === | === Testy plików (wybór) === | ||
Linia 290: | Linia 312: | ||
Przykład: | Przykład: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
test \( -z "$X" -o "$X" -le 4 \) -a ! -s "$Y" -a \( "$Z" -le 2 -o "$Z" -ge 12 \) | test \( -z "$X" -o "$X" -le 4 \) -a ! -s "$Y" -a \( "$Z" -le 2 -o "$Z" -ge 12 \) | ||
Linia 365: | Linia 388: | ||
Instrukcja wyboru ma składnię: | Instrukcja wyboru ma składnię: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<html><pre style="margin:0"> | <html><pre style="margin:0"> | ||
<b>case</b> <i>wartość</i> <b>in</b> | <b>case</b> <i>wartość</i> <b>in</b> | ||
Linia 383: | Linia 407: | ||
Przykład bez używania znaków nowej linii: | Przykład bez używania znaków nowej linii: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
case $(LANG= date "+%A") in Monday) echo "Ugh...";; S*day) tput bel; echo "Weekend!";; *) echo "a day.";; esac | case $(LANG= date "+%A") in Monday) echo "Ugh...";; S*day) tput bel; echo "Weekend!";; *) echo "a day.";; esac | ||
Linia 390: | Linia 415: | ||
Napisz skrypt który sprawdzi rozszerzenie pliku (podanego jako argument) i jeśli | Napisz skrypt który sprawdzi rozszerzenie pliku (podanego jako argument) i jeśli | ||
plik ma rozszerzenie: | plik ma rozszerzenie: | ||
- | \\ • ''pdf'' to wykona ''pdftotext //plik// -'', | + | <html><div style="margin-top:-1.4em"></div></html> |
- | \\ • ''zip'' to wykona ''unzip -l //plik//'', | + | * ''pdf'' to wykona ''pdftotext //plik// -'', |
- | \\ • jakiekolwiek inne, to wykona ''cat //plik//''. | + | * ''zip'' to wykona ''unzip -l //plik//'', |
+ | * jakiekolwiek inne, to wykona ''cat //plik//''. | ||
Linia 405: | Linia 431: | ||
Pętla ''for'' ma składnię: | Pętla ''for'' ma składnię: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<html><pre style="margin:0"> | <html><pre style="margin:0"> | ||
<b>for</b> <i>zmienna</i> <b>in</b> <i>wartość1</i> <i>wartość2</i> <i>…</i> | <b>for</b> <i>zmienna</i> <b>in</b> <i>wartość1</i> <i>wartość2</i> <i>…</i> | ||
Linia 422: | Linia 449: | ||
''for NUM in $(seq -w 001 3)'' → ''for NUM in 001 002 003'' \\ | ''for NUM in $(seq -w 001 3)'' → ''for NUM in 001 002 003'' \\ | ||
''for USERNAME in $(getent passwd | cut -f1 -d:)'' → ''for USERNAME in root student ...'' \\ | ''for USERNAME in $(getent passwd | cut -f1 -d:)'' → ''for USERNAME in root student ...'' \\ | ||
+ | ''for FILE in "$DIR"/*'' → ''for FILE in 'my dir/file 1' 'my dir/file 2' 'my dir/subdir%%'%%'' \\ | ||
''for FILE in $(grep -il 'ldap' /etc/*.conf 2>/dev/null)'' → ''for FILE in /etc/autofs.conf /etc/ldap.conf ...''((Uwaga na spacje w nazwach plików! Ta wersja nie jest na nie odporna.)) | ''for FILE in $(grep -il 'ldap' /etc/*.conf 2>/dev/null)'' → ''for FILE in /etc/autofs.conf /etc/ldap.conf ...''((Uwaga na spacje w nazwach plików! Ta wersja nie jest na nie odporna.)) | ||
Przykład bez używania znaków nowej linii: | Przykład bez używania znaków nowej linii: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
for X in {1..3}; do echo -n "Przebieg $X: "; date +%N; done | for X in {1..3}; do echo -n "Przebieg $X: "; date +%N; done | ||
Linia 441: | Linia 470: | ||
Bash wspiera też składnię ''for'' wyglądającą i działającą jak w C: | Bash wspiera też składnię ''for'' wyglądającą i działającą jak w C: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<html><pre style="margin:0"> | <html><pre style="margin:0"> | ||
<b>for ((</b><i>i=0</i><b>;</b> <i>i<5</i><b>;</b> </i>i++</i><b>))</b> | <b>for ((</b><i>i=0</i><b>;</b> <i>i<5</i><b>;</b> </i>i++</i><b>))</b> | ||
Linia 449: | Linia 479: | ||
Przykład bez używania znaków nowej linii: | Przykład bez używania znaków nowej linii: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
for ((i=3;i<=15;i+=3)); do for ((j=0;j<i;j++)); do echo -n '*'; done; echo; done | for ((i=3;i<=15;i+=3)); do for ((j=0;j<i;j++)); do echo -n '*'; done; echo; done | ||
Linia 474: | Linia 505: | ||
Przykład bez używania znaków nowej linii: | Przykład bez używania znaków nowej linii: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
X=7; until [ $X -eq 1 ]; do [ $((X%2)) -eq 1 ] && X=$((3*X+1)) || X=$((X/2)); echo $X; done | X=7; until [ $X -eq 1 ]; do [ $((X%2)) -eq 1 ] && X=$((3*X+1)) || X=$((X/2)); echo $X; done | ||
Linia 491: | Linia 523: | ||
Komenda | Komenda | ||
- | ''**[[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html|read]]** | + | ''**[[https://pubs.opengroup.org/onlinepubs/9799919799/utilities/read.html|read]]** |
[//zmienna//]...'' wczytuje jedną linię ze standardowego wejścia, a następnie: | [//zmienna//]...'' wczytuje jedną linię ze standardowego wejścia, a następnie: | ||
* (rozszerzenie Basha) jeżeli nie ma argumentów, ''read'' wpisuje linię do zmiennej REPLY, | * (rozszerzenie Basha) jeżeli nie ma argumentów, ''read'' wpisuje linię do zmiennej REPLY, | ||
Linia 529: | Linia 561: | ||
... | ... | ||
done | done | ||
- | </code> 1. ''polecenie'' jest wykonywane współbieżnie z pętlą \\ 2. wyniki polecenia mogą mieć spacje w linii |<code bash> | + | </code> 1. ''polecenie'' jest wykonywane współbieżnie z pętlą \\ 2. wyniki polecenia mogą mieć spacje w linii \\ <html><small>Uwaga: tylko jedna z komend z potoku (domyślnie pierwsza) działa <br> pierwszoplanowo, przez co przypisania zmiennych wewnątrz pętli <br> (działającej w tle) nie będą widoczne dalej w skrypcie</small><div style="margin-top: -1.4em"></div></html>|<code bash> |
while read X Y | while read X Y | ||
do | do | ||
Linia 550: | Linia 582: | ||
wczytanych liczb. | wczytanych liczb. | ||
+ | ~~Zadanie.#~~ | ||
+ | Napisz skrypt który odczytuje ze standardowego wejścia linie złożone z dwóch | ||
+ | liczb i po przeczytaniu każdej linii wypisuje iloczyn liczb z tej linii. | ||
+ | Skrypt ma działać do czasu aż odczytywanie z wejścia nie napotka końca pliku. | ||
==== select – rozszerzenie Basha ==== | ==== select – rozszerzenie Basha ==== | ||
__Pętla__ ''[[https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html#index-select|select]]'' ma składnię identyczną jak pętla for: | __Pętla__ ''[[https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html#index-select|select]]'' ma składnię identyczną jak pętla for: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<html><pre> | <html><pre> | ||
<b>select</b> <i>ZMIENNA</i> <b>in</b> <i>wartość1</i> <i>wartość2</i> <i>…</i> | <b>select</b> <i>ZMIENNA</i> <b>in</b> <i>wartość1</i> <i>wartość2</i> <i>…</i> | ||
Linia 560: | Linia 597: | ||
</pre></html> | </pre></html> | ||
Ta pętla: | Ta pętla: | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
- wyświetla numerowaną listę wartości, | - wyświetla numerowaną listę wartości, | ||
- czeka na wpisanie linii wejścia przez użytkownika, | - czeka na wpisanie linii wejścia przez użytkownika, | ||
Linia 569: | Linia 607: | ||
~~Zadanie.#~~ | ~~Zadanie.#~~ | ||
Przeanalizuj i przetestuj poniższy kod. Zmień go tak, by dopiero wpisanie ''q'' przerywało pętlę. | Przeanalizuj i przetestuj poniższy kod. Zmień go tak, by dopiero wpisanie ''q'' przerywało pętlę. | ||
+ | <html><div style="margin-top:-1.4em"></div></html> | ||
<code bash> | <code bash> | ||
select FILE in /etc/logrotate.d/* | select FILE in /etc/logrotate.d/* |