Als script.sh gewoon iets typischs is, zoals
#!/bin/bash echo "Hello World!"
Is er een voorkeur manier om het script uit te voeren? Ik denk dat je het eerst moet chmod zodat het uitvoerbaar wordt?
Answer
Voor je specifieke script zal beide manieren werken, behalve dat ./script.sh
uitvoering en leesbare bits vereist, terwijl bash script.sh
alleen leesbare bits nodig hebben.
De reden van het verschil in toestemmingsvereisten ligt in de manier waarop het programma dat uw script interpreteert, wordt geladen:
-
./script.sh
zorgt ervoor dat uw shell het bestand uitvoert alsof het een normaal uitvoerbaar.
De shell splitst zichzelf en gebruikt een systeemaanroep (bijv. execve
) om het besturingssysteem het bestand te laten uitvoeren in het gevorkte proces. Het besturingssysteem controleert de machtigingen van het bestand (vandaar dat de uitvoeringsbit moet worden ingesteld) en stuurt het verzoek door naar de programma-loader , die naar het bestand kijkt en bepaalt hoe het moet worden uitgevoerd. In Linux beginnen gecompileerde uitvoerbare bestanden met een ELF magisch getal, terwijl scripts beginnen met een #!
( hashbang ). Een hashbang-header betekent dat het bestand een script is en moet worden geïnterpreteerd door het programma dat is gespecificeerd na de hashbang. Dit staat een script toe zichzelf om het systeem te vertellen hoe het script moet worden geïnterpreteerd.
Met uw script zal de programma-loader /bin/bash
uitvoeren en ./script.sh
als het opdrachtregelargument.
-
bash script.sh
laat je shellbash
draaien en doorgevenscript.sh
als het opdrachtregelargument
Dus het besturingssysteem laadt (zelfs niet kijken naar script.sh
, omdat het slechts een opdrachtregelargument is). Het gemaakte bash
-proces interpreteert het script.sh
omdat het is doorgegeven als het opdrachtregelargument. Omdat script.sh
wordt alleen gelezen door bash
als een gewoon bestand, de uitvoeringsbit is niet vereist.
Ik raad aan ./script.sh
echter, omdat je misschien niet weet welke interpreter het script nodig heeft. Dus laat de programma-loader dat voor je bepalen.
Opmerkingen
- Als het uitvoerbare bit niet is ingesteld, kunt u het script ook uitvoeren door ". ./script.sh"
- @Dog Je hebt gelijk. De punt is een snelkoppeling voor het ingebouwde commando ' source ' , die het script in het huidige bash-proces uitvoert. Dus alleen het leesbare bit is vereist.
- @Dogeatcatworld terwijl dat waar is, is het uitvoeren van
. ./script.sh
niet hetzelfde ding als (of./script.sh
. Beschouw het script#!/usr/bin/python -V
< newline >print test
. - Pas op dat het zoeken naar een script kan leiden tot besmetting van de interactieve sessie. Als een script bijvoorbeeld de omgevingsvariabele PATH wijzigt, heeft deze wijziging invloed op opdrachten die na de bron worden uitgevoerd. Deze benadering moet eigenlijk worden gereserveerd voor situaties waarin u afhankelijk bent van de bijwerkingen (scripts voor het instellen van de omgeving en dergelijke). Voor andere situaties waarin u ' de rechten niet kunt wijzigen, is het uitvoeren van het commando in de shebang-regel, gevolgd door de scriptnaam de veiligste benadering.
- Merk op dat , als u een script in de huidige directory plaatst, hoeft u ./ niet te gebruiken; zeg gewoon
. script.sh
. Maar ik ben het eens met de mensen die het gebruik van het.
commando ontmoedigen voor scripts die niet bedoeld waren om op die manier te worden aangeroepen. Het verbaast me dat niemand heeft gezegd dat als het scriptexit
-opdrachten bevat en je het broncode, het je kan uitloggen. Een minder nijpend probleem zou zijn als het script eencd
doet, aangezien dat ook de bovenliggende (interactieve) shell zou beïnvloeden.
Answer
bash script.sh
roept het script rechtstreeks aan met de bash.
./script.sh
gebruikt de shebang #!/bin/bash
om te bepalen hoe het moet worden uitgevoerd.
Als je echt wilt weten, welk binair bestand wordt uitgevoerd als je een bash script.sh
zou je kunnen achterhalen met which bash
.
Dus in jouw voorbeeld maakt het geen verschil. Ja, u moet chmod +x script.sh
zijn om het rechtstreeks uit te voeren via ./script.sh
.
Opmerkingen
Antwoord
Maak een bestand Delete_Self.sh als volgt:
#!/bin/rm echo I am still here!
Voer dit uit script als sh Delete_Self.sh
zul je zien “Ik ben er nog steeds!” teruggekaatst.
Maak het uitvoerbaar en voer het uit als ./Delete_Self.sh
je zult zien dat er niets wordt teruggekaatst, terwijl het bestand Delete_Self.sh
zelf is verdwenen.
Het verschil is dus dat:
-
bash script.sh
de #! regel, omdat bash is gespecificeerd als het programma om script.sh uit te voeren. -
./script.sh
zal de #! regel om te bepalen welk programma moet worden uitgevoerdscript.sh
.
Reacties
- +1 voor het mooie voorbeeld
Answer
Naast de andere antwoorden, het verschil kennen tussen het uitvoeren van een script via ./script.sh
(i) en source ./script.sh
(ii) is handig – De (i) versie maakt een nieuwe shell om het commando uit te voeren, terwijl (ii) het in de huidige shell uitvoert – wat verplicht kan zijn als het uitvoerbare bestand omgevingsvariabelen verandert die moeten worden bewaard nadat het uitvoerbare bestand is afgesloten. Om bijvoorbeeld een python conda-omgeving te activeren, moet het volgende worden gebruikt:
source activate my_env
N.B. Een ander alternatief voor source
dat u kunt tegenkomen is de .
ingebouwde, dwz
. activate my_env
/bin/bash
de eerstebash
in uw$PATH
.#!/bin/bash
werkt alleen als er een/bin/bash
./script.sh
.