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.