GNU/Linux >> Znalost Linux >  >> Linux

Jaký je rozdíl mezi #!/usr/bin/env bash a #!/usr/bin/bash?

Pokud skripty shellu začínají 04 , budou vždy spuštěny s 17 od 29 . Pokud však začínají 36 , budou hledat 46 v 53 a pak začnou s prvním, který najdou.

Proč by to bylo užitečné? Předpokládejme, že chcete spustit 61 skripty, které vyžadují bash 4.x nebo novější, ale váš systém má pouze 76 3.x nainstalována a vaše distribuce aktuálně nenabízí novější verzi nebo nejste správce a nemůžete změnit, co je na tomto systému nainstalováno.

Samozřejmě si můžete stáhnout zdrojový kód bash a vytvořit si vlastní bash od nuly a umístit jej do 80 například. A můžete také upravit svůj 92 proměnná ve vašem 105 soubor obsahovat 112 jako první záznam (125 jako 132 nerozbalí se v 143 ). Pokud nyní zavoláte na 158 , shell jej nejprve vyhledá v 166 v pořadí, takže začíná 175 , kde najde váš 184 . Totéž se stane, pokud skripty hledají 198 pomocí 207 , takže tyto skripty by nyní fungovaly ve vašem systému pomocí vašeho vlastního 211 stavět.

Jednou nevýhodou je, že to může vést k neočekávanému chování, např. stejný skript na stejném počítači může běžet s různými interprety pro různá prostředí nebo uživateli s různými cestami hledání, což způsobuje nejrůznější bolesti hlavy.

Největší nevýhodou 226 je, že některé systémy povolí pouze jeden argument, takže to nemůžete udělat 230 , protože systémy uvidí 242 jako jeden argument (budou s ním zacházet, jako by byl výraz citován) a tedy 251 vyhledá interpret s názvem 263 . Upozorňujeme, že toto není problém 274 samotný příkaz, který vždy umožňoval předávání více parametrů, ale s analyzátorem shebang systému, který analyzuje tento řádek ještě před voláním 286 . Mezitím to bylo opraveno na většině systémů, ale pokud chce být váš skript ultra přenosný, nemůžete se spolehnout, že to bylo opraveno v systému, který budete používat.

Může mít dokonce bezpečnostní dopady, např. pokud 291 nebyl nakonfigurován na čisté prostředí nebo 301 byl z úklidu vyloučen. Dovolte mi to demonstrovat:

Obvykle 313 je dobře chráněné místo, pouze 325 je schopen tam cokoliv změnit. Váš domovský adresář však není, žádný spuštěný program v něm nemůže provádět změny. To znamená, že škodlivý kód by mohl umístit falešný kód 334 do nějakého skrytého adresáře, upravte svůj 349 zahrnout tento adresář do vašeho 352 , takže všechny skripty používající 366 skončí s tím falešným 370 . Pokud 383 zachovává 392 , máte velký problém.

Např. zvážit nástroj vytvoří soubor 400 s následujícím obsahem:

#!/bin/bash

if [ $EUID -eq 0 ]; then
  echo "All your base are belong to us..."
  # We are root - do whatever you want to do
fi

/bin/bash "[email protected]"

Vytvoříme jednoduchý skript 416 :

#!/usr/bin/env bash

echo "Hello World"

Proof of concept (v systému, kde 428 zachovává 438 ):

$ ./sample.sh
Hello World

$ sudo ./sample.sh
Hello World

$ export PATH="$HOME/.evil:$PATH"

$ ./sample.sh
Hello World

$ sudo ./sample.sh
All your base are belong to us...
Hello World

Obvykle by všechny klasické shelly měly být umístěny v 448 a pokud je tam z jakéhokoli důvodu nechcete umístit, opravdu není problém umístit symbolický odkaz do 459 která ukazuje na jejich skutečné umístění (nebo možná 466 sám o sobě je symbolický odkaz), takže bych vždy volil 475 a 486 . Je toho příliš mnoho, co by se rozbilo, kdyby tyto už nefungovaly. Není to tak, že by POSIX vyžadoval tyto pozice (POSIX nestandardizuje názvy cest, a tudíž ani nestandardizuje funkci shebang vůbec), ale jsou tak běžné, že i když by systém nenabízel 492 , pravděpodobně by stále rozumělo 504 a vědět, co s tím dělat, a může to být pouze kvůli kompatibilitě s existujícím kódem.

Ale pro modernější, nestandardní, volitelné interprety, jako je Perl, PHP, Python nebo Ruby, není ve skutečnosti nikde specifikováno, kde by měly být umístěny. Mohou být v 514 ale mohou být také v 527 nebo ve zcela jiné větvi hierarchie (538 , 549 , atd.). To je důvod, proč tyto často používají 557 syntaxe shebang.


Pomocí 562 způsobí, že shell hledá první shodu NAME v proměnné prostředí $PATH. Může být užitečné, pokud si nejste vědomi absolutní cesty nebo ji nechcete hledat.


Spuštění příkazu přes 575 má tu výhodu, že hledá jakoukoli výchozí verzi programu ve vašem aktuálním env žehlení.

Tímto způsobem jej nemusíte hledat na konkrétním místě v systému, protože tyto cesty mohou být na různých místech v různých systémech. Dokud je ve vaší cestě, najde si to.

Jednou nevýhodou je, že nebudete moci předat více než jeden argument (např. nebudete moci napsat 583 ), pokud chcete podporovat Linux, protože POSIX je vágní v tom, jak má být řádek interpretován, a Linux interpretuje vše za první mezerou, aby označoval jediný argument. Můžete použít 590 na některých verzích 607 abyste to obešli, ale skript se pak stane ještě méně přenosným a přestane fungovat na poměrně nedávných systémech (např. i Ubuntu 16.04, pokud ne později).

Další nevýhodou je, že protože nevoláte explicitní spustitelný soubor, může to způsobit chyby a na víceuživatelských systémech bezpečnostní problémy (pokud se někomu podařilo získat jeho spustitelný soubor s názvem 617 například ve vaší cestě).

#!/usr/bin/env bash #lends you some flexibility on different systems
#!/usr/bin/bash     #gives you explicit control on a given system of what executable is called

V některých situacích může být preferován první (jako je spouštění pythonových skriptů s více verzemi pythonu, aniž byste museli přepracovávat spustitelný řádek). Ale v situacích, kdy se zaměřujeme na zabezpečení, by bylo preferováno to druhé, protože to omezuje možnosti vkládání kódu.


Linux
  1. Jak Linux zpracovává více po sobě jdoucích oddělovačů cest (/home////username///soubor)?

  2. Bash =~ Regex A Https://regex101.com/?

  3. Jaký je rozdíl mezi /sbin/nologin a /bin/false?

  1. Proč /bin/sh ukazuje na /bin/dash a ne /bin/bash?

  2. Jaké jsou významy /usr/sbin, /usr/local/sbin a /usr/local/bin?

  3. Kdy musím použít #!/bin/bash a kdy #!/bin/sh?

  1. Rozdíl mezi /bin a /usr/bin

  2. Přesunutý obsah /bin do /usr/bin, je možné vrátit zpět?

  3. Co je /usr/bin/[?