Tento blogový příspěvek je druhým ze dvou obsahujících několik praktických tipů a triků, jak co nejlépe využít prostředí Bash. V první části jsem pokryl historii, poslední argument, práci se soubory a adresáři, čtení souborů a funkce Bash. V tomto segmentu se zabývám proměnnými shellu, hledáním, deskriptory souborů a vzdálenými operacemi.
Použít proměnné shellu
Proměnné Bash jsou při vyvolání nastaveny shellem. Proč bych měl používat hostname
kdy mohu použít $HOSTNAME nebo proč bych měl používat whoami
kdy mohu použít $USER? Bash proměnné jsou velmi rychlé a nevyžadují externí aplikace.
Toto je několik často používaných proměnných:
$PATH
$HOME
$USER
$HOSTNAME
$PS1
..
$PS4
Použijte echo
příkaz k rozšíření proměnných. Například proměnnou shellu $PATH lze rozšířit spuštěním:
$> echo $PATH
[ Stáhnout nyní:Průvodce systémového administrátora skriptováním v Bash. ]
Použijte příkaz find
find
command je pravděpodobně jedním z nejpoužívanějších nástrojů v rámci operačního systému Linux. Je to velmi užitečné v interaktivních shellech. Používá se také ve skriptech. Pomocí find
Mohu vypsat soubory starší nebo novější než určité datum, odstranit je na základě tohoto data, změnit oprávnění souborů nebo adresářů a tak dále.
Pojďme se s tímto příkazem blíže seznámit.
Chcete-li zobrazit soubory starší než 30 dní, jednoduše spustím:
$> find /tmp -type f -mtime +30
Chcete-li odstranit soubory starší než 30 dní, spusťte:
$> find /tmp -type f -mtime +30 -exec rm -rf {} \;
nebo
$> find /tmp -type f -mtime +30 -exec rm -rf {} +
Zatímco výše uvedené příkazy smažou soubory starší než 30 dní, jak byly napsány, rozvětvují rm
příkaz pokaždé, když najdou soubor. Toto vyhledávání lze zapsat efektivněji pomocí xargs
:
$> find /tmp -name '*.tmp' -exec printf '%s\0' {} \; | xargs -0 rm
Mohu použít find
vypsat sha256sum
soubory pouze spuštěním:
$> find . -type f -exec sha256sum {} +
A nyní k hledání a odstraňování duplicitních souborů .jpg:
$> find . -type f -name '*.jpg' -exec sha256sum {} + | sort -uk1,1
Deskriptory referenčních souborů
V prostředí Bash jsou deskriptory souborů (FD) důležité při správě vstupu a výstupu příkazů. Mnoho lidí má problémy správně porozumět deskriptorům souborů. Každý proces má tři výchozí deskriptory souborů, konkrétně:
Kód | Význam | Umístění | Popis |
---|---|---|---|
0 | Standardní vstup | /dev/stdin | Klávesnice, soubor nebo nějaký stream |
1 | Standardní výstup | /dev/stdout | Monitor, terminál, displej |
2 | Standardní chyba | /dev/stderr | Nenulové výstupní kódy jsou obvykle>FD2, displej |
Nyní, když víte, co dělají výchozí FD, pojďme se na ně podívat v akci. Začnu vytvořením adresáře s názvem foo
, který obsahuje file1
.
$> ls foo/ bar/
ls: cannot access 'bar/': No such file or directory
foo/:
file1
Výstup Žádný takový soubor nebo adresář přejde na Standardní chybu (stderr) a zobrazí se také na obrazovce. Spustím stejný příkaz, ale tentokrát použiji 2>
vynechat stderr:
$> ls foo/ bar/ 2>/dev/null
foo/:
file1
Je možné odeslat výstup foo
na standardní výstup (stdout) a do souboru současně a ignorujte stderr. Například:
$> { ls foo bar | tee -a ls_out_file ;} 2>/dev/null
foo:
file1
Potom:
$> cat ls_out_file
foo:
file1
Následující příkaz odešle stdout do souboru a stderr do /dev/null
aby se chyba nezobrazila na obrazovce:
$> ls foo/ bar/ >to_stdout 2>/dev/null
$> cat to_stdout
foo/:
file1
Následující příkaz odešle stdout a stderr do stejného souboru:
$> ls foo/ bar/ >mixed_output 2>&1
$> cat mixed_output
ls: cannot access 'bar/': No such file or directory
foo/:
file1
Toto se stalo v posledním příkladu, kde byly stdout a stderr přesměrovány do stejného souboru:
ls foo/ bar/ >mixed_output 2>&1
| |
| Redirect stderr to where stdout is sent
|
stdout is sent to mixed_output
Další krátký trik (> Bash 4.4) k odeslání stdout i stderr do stejného souboru používá znak ampersand. Například:
$> ls foo/ bar/ &>mixed_output
Zde je složitější přesměrování:
exec 3>&1 >write_to_file; echo "Hello World"; exec 1>&3 3>&-
Toto se stane:
- exec 3>&1 Zkopírujte stdout do deskriptoru souboru 3
- > write_to_file Vytvořte FD 1 pro zápis do souboru
- echo "Hello World" Přejít na soubor, protože FD 1 nyní ukazuje na soubor
- exec 1>&3 Zkopírujte FD 3 zpět na 1 (swap)
- Tři>&- Zavřít deskriptor souboru tři (už ho nepotřebujeme)
Často je užitečné seskupit příkazy a poté odeslat standardní výstup do jednoho souboru. Například:
$> { ls non_existing_dir; non_existing_command; echo "Hello world"; } 2> to_stderr
Hello world
Jak vidíte, na obrazovce je vytištěno pouze „Ahoj světe“, ale výstup neúspěšných příkazů je zapsán do souboru to_stderr.
Provádění vzdálených operací
Používám Telnet, netcat, Nmap a další nástroje k testování, zda je vzdálená služba spuštěna a zda se k ní mohu připojit. Tyto nástroje jsou užitečné, ale nejsou standardně nainstalovány na všech systémech.
Naštěstí existuje jednoduchý způsob, jak otestovat připojení bez použití externích nástrojů. Chcete-li zjistit, zda na vzdáleném serveru běží web, databáze, SSH nebo jakákoli jiná služba, spusťte:
$> timeout 3 bash -c ‘</dev/tcp/remote_server/remote_port’ || echo “Failed to connect”
Chcete-li například zjistit, zda serverA je spuštěna služba MariaDB:
$> timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed to connect”
Pokud se připojení nezdaří, zobrazí se Připojení se nezdařilo na obrazovce se zobrazí zpráva.
Předpokládejme serverA je za firewallem/NAT. Chci zjistit, zda je brána firewall nakonfigurována tak, aby umožňovala připojení databáze k serverA , ale ještě jsem nenainstaloval databázový server. K emulaci databázového portu (nebo jakéhokoli jiného portu) mohu použít následující:
[serverA ~]# nc -l 3306
Na klientA , spustit:
[clientA ~]# timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed”
Když mluvím o vzdálených připojeních, co spouštění příkazů na vzdáleném serveru přes SSH? Mohu použít následující příkaz:
$> ssh remotehost <<EOF # Press the Enter key here
> ls /etc
EOF
Tento příkaz spustí ls /etc
na vzdáleném hostiteli.
Mohu také spustit místní skript na vzdáleném hostiteli, aniž bych musel kopírovat skript na vzdálený server. Jedním ze způsobů je zadat:
$> ssh remote_host 'bash -s' < local_script
Dalším příkladem je předání proměnných prostředí lokálně vzdálenému serveru a ukončení relace po spuštění.
$> exec ssh remote_host ARG1=FOO ARG2=BAR 'bash -s' <<'EOF'
> printf %s\\n "$ARG1" "$ARG2"
> EOF
Password:
FOO
BAR
Connection to remote_host closed.
Existuje mnoho dalších složitých akcí, které mohu provádět na vzdáleném hostiteli.
Sbalit
V Bashovi je toho určitě víc, než jsem dokázal pokrýt v tomto dvoudílném blogovém příspěvku. Sdílím to, co vím a čím se denně zabývám. Cílem je seznámit vás s několika technikami, díky kterým bude vaše práce méně náchylná k chybám a bude zábavnější.
[ Chcete si vyzkoušet své schopnosti správce systému? Proveďte hodnocení dovedností ještě dnes. ]