Jaký je rozdíl mezi spuštěním “ bash script.sh ” a “ ./script .sh ”?

Pokud je soubor script.sh jen něco typického jako

#!/bin/bash echo "Hello World!" 

Existuje preferovaný způsob, jak spustit skript? Myslím, že to musíte nejdříve změnit, aby se stalo spustitelným?

Odpovědět

Pro váš konkrétní skript bude fungovat jakkoli, kromě že ./script.sh vyžaduje provedení a čitelné bity, zatímco bash script.sh vyžaduje pouze čitelný bit.


Důvod rozdíl v požadavcích na oprávnění spočívá v tom, jak je načten program, který interpretuje váš skript:

  • ./script.sh způsobí, že váš shell spustí soubor, jako by to byl běžný soubor spustitelný soubor.

Samotný shell se rozvětví a použije systémové volání (např. execve) k tomu, aby operační systém spustil soubor ve vidlicovém procesu. Operační systém zkontroluje oprávnění souboru (proto je třeba nastavit spouštěcí bit) a předá požadavek zavaděči programu , který se na soubor podívá a určuje, jak jej spustit. V Linuxu kompilované spustitelné soubory začínají ELF magickým číslem, zatímco skripty začínají #! ( hashbang ). Záhlaví hashbang znamená, že soubor je skript a musí být interpretován programem, který je zadán za hashbang. To umožňuje skript sám řekne systému, jak interpretovat skript.

Pomocí vašeho skriptu zavaděč programu provede /bin/bash a předá ./script.sh jako argument příkazového řádku.

  • bash script.sh způsobí spuštění vašeho shellu bash a předání script.sh jako argument příkazového řádku

Takže operační systém načte (ani při pohledu na script.sh, protože je to jen argument příkazového řádku). Vytvořený bash proces poté interpretuje script.sh, protože je předán jako argument příkazového řádku. Protože čte bash pouze jako běžný soubor, prováděcí bit není vyžadován.


Doporučuji použít ./script.sh, protože možná nevíte, kterého interpreta skript vyžaduje. Nechte to tedy načíst programovým zavaděčem.

Komentáře

  • Pokud spustitelný bit není nastaven, můžete skript spustit také provedením ". ./script.sh"
  • @Dog Máte pravdu. Tečka je zkratkou pro vestavěný příkaz ' source ' , který spouští skript v aktuálním procesu bash. Vyžaduje se tedy pouze čitelný bit.
  • @Dogeatcatworld, i když je to pravda, spuštění . ./script.sh není totéž věc jako (nebo ./script.sh. Zvažte skript #!/usr/bin/python -V < newline > print test.
  • Pozor, získávání skriptu by mohlo vést ke kontaminaci interaktivní relace. Například pokud skript změní proměnnou prostředí PATH, tato změna ovlivní příkazy spuštěné po zdroji. Tento přístup by měl být skutečně vyhrazen pro situace, kdy jste závislí na vedlejších účincích (skripty pro nastavení prostředí a podobně). V jiných situacích, kdy nelze ' t změnit oprávnění, je nejbezpečnějším přístupem spuštění příkazu v řádku shebang, následovaný názvem skriptu.
  • , pokud zdrojujete skript v aktuálním adresáři, nemusíte používat ./ ; stačí říct . script.sh. Souhlasím ale s lidmi, kteří odrazují od používání příkazu . ve skriptech, které tak neměly být vyvolávány. Překvapuje mě, že se nikdo nezmínil, že pokud skript obsahuje příkazy exit a vy jej zadáte, může vás odhlásit. Méně katastrofálním problémem by bylo, kdyby skript provedl cd, protože by to také ovlivnilo nadřazený (interaktivní) shell.

Odpověď

bash script.sh vyvolá skript přímo pomocí bash.
./script.sh používá shebang #!/bin/bash k určení způsobu provedení.

Pokud opravdu chcete vědět, který binární soubor se spustí, pokud provedete bash script.sh můžete zjistit pomocí which bash.

Takže ve vašem příkladu to není žádný rozdíl. Ano, musíte chmod +x script.sh být schopni jej spustit přímo prostřednictvím ./script.sh.

Komentáře

  • Nic to nezmění za předpokladu, že /bin/bash je první bash ve vaší $PATH.
  • Máte ' pravdu. A shebang #!/bin/bash funguje pouze v případě, že je na mém počítači /bin/bash
  • Bash (verze 4.2.37) systém spouští skripty i bez nastaveného prováděcího bitu. Proč říkáte, že je vyžadován prováděcí bit?
  • Ano, prováděcí bit je potřeba pouze vyvoláním pomocí ./script.sh.

Odpověď

Vytvořte soubor Delete_Self.sh takto:

 #!/bin/rm echo I am still here! 

Spustit toto skript jako sh Delete_Self.sh uvidíte „Jsem stále tady!“ ozvěna zpět.

Udělejte to spustitelným a spusťte jej jako ./Delete_Self.sh uvidíte, že se nic neodráží zpět, zatímco soubor Delete_Self.sh je pryč.

Rozdíl tedy spočívá v tom, že:

  • bash script.sh bude ignorovat #! řádek, protože bash je určen jako program pro spuštění script.sh.
  • ./script.sh přečte #! řádek k určení programu, který má být spuštěn script.sh.

Komentáře

  • +1 pro pěkný příklad

Odpověď

Kromě ostatních odpovědí je třeba znát rozdíl mezi spuštěním skriptu pomocí ./script.sh (i) a source ./script.sh (ii) jsou užitečné – verze (i) vytvoří nový shell, ve kterém bude spuštěn příkaz, vzhledem k tomu, že (ii) jej spouští v aktuálním prostředí – což může být povinné, pokud spustitelný soubor změní proměnné prostředí, které je třeba zachovat po ukončení spustitelného souboru. Například k aktivaci prostředí python conda je třeba použít následující:

source activate my_env 

N.B. Další alternativou k source, se kterou se můžete setkat, je . builtin, tj.

. activate my_env 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *