GNU/Linux >> Znalost Linux >  >> Linux

Další hloupé Bashovy triky:Proměnné, hledání, deskriptory souborů a vzdálené operace

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. ]


Linux
  1. Najděte soubor pomocí příkazů Najít a najít v Linuxu

  2. Linux .htaccess tipy a triky

  3. Extrahujte základní název souboru bez cesty a přípony v bash

  1. Jak udělat `hlavu` a `ocas` na vstupu odděleném nulou v Bash?

  2. Rekurzivně měnit přípony souborů v Bash

  3. Provádění operací atomického zápisu do souboru v bash

  1. Provádění operací atomového zápisu v souboru v Bash?

  2. Bash:Bezpečné procedurální použití funkce Najít do výběru?

  3. Expanze závorky Bash a proměnné?