Hvad er forskellen mellem at køre “ bash script.sh ” og “ ./script .sh ”?

Hvis script.sh bare er noget som

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

Er der en foretrukken måde at køre scriptet på? Jeg tror, at du først skal chmod det, så det bliver eksekverbart?

Svar

For dit specifikke script fungerer begge måder, undtagen at ./script.sh kræver udførelse og læsbare bits, mens bash script.sh kun kræver læsbar bit.


Årsagen til forskellen om tilladelseskrav ligger i, hvordan programmet, der fortolker dit script, indlæses:

  • ./script.sh får din shell til at køre filen som om det var en regelmæssig eksekverbar.

Skallen gaffel sig selv og bruger et systemopkald (f.eks. execve) for at få operativsystemet til at udføre filen i den forkedede proces. Operativsystemet kontrollerer filens tilladelser (derfor skal eksekveringsbiten indstilles) og videresender anmodningen til programlæsseren , som ser på filen og bestemmer, hvordan den skal udføres. I Linux-kompilerede eksekverbare filer starter med et ELF magisk nummer, mens scripts starter med et #! ( hashbang ). En hashbang-overskrift betyder, at filen er et script og skal fortolkes af det program, der er angivet efter hashbang. Dette tillader et script sig selv for at fortælle systemet, hvordan man fortolker scriptet.

Med dit script udfører programlæsseren /bin/bash og videregiver ./script.sh som kommandolinjeargumentet.

  • bash script.sh får din shell til at køre bash script.sh som kommandolinjeargumentet

Så operativsystemet indlæser (ikke engang kigger på script.sh, fordi det bare er et kommandolinjeargument). Den oprettede bash -proces fortolker derefter script.sh, fordi den sendes som kommandolinjeargumentet. Fordi script.sh læses kun af bash som en almindelig fil, eksekveringsbiten er ikke påkrævet.


Jeg anbefaler at bruge ./script.sh, fordi du måske ikke ved, hvilken tolk scriptet kræver. Så lad programindlæser bestemme det for dig.

Kommentarer

  • Hvis den eksekverbare bit ikke er indstillet, kan du også køre scriptet ved at udføre " ./script.sh"
  • @Dog Du har ret. Prikken er en genvej til indbygget kommando ' kilde ' , der kører scriptet i den aktuelle bash-proces. Så kun den læsbare bit er påkrævet.
  • @Dogeatcatworld mens det er sandt, kører . ./script.sh er ikke det samme ting som (eller ./script.sh. Overvej scriptet #!/usr/bin/python -V < newline > print test.
  • Pas på, at sourcing af et script kan resultere i forurening af den interaktive session. Hvis et script f.eks. Ændrer PATH-miljøvariablen, påvirker denne ændring kommandoer, der køres efter kilden. Denne tilgang skal virkelig være forbeholdt situationer, hvor du er afhængig af bivirkningerne (miljøopsætningsskripter og lignende). I andre situationer, hvor du ikke kan ' t ændre tilladelserne, er det den sikreste tilgang at køre kommandoen i shebang-linjen efterfulgt af scriptnavnet.
  • , hvis du kilder et script i den aktuelle mappe, behøver du ikke bruge ./ ; sig bare . script.sh. Men jeg er enig med de mennesker, der afskrækker at bruge kommandoen . på scripts, der ikke var beregnet til at blive påberåbt på den måde. Jeg er overrasket over, at ingen nævnte, at hvis scriptet indeholder exit kommandoer, og du kilder det, kan det logge dig ud. Et mindre alvorligt problem ville være, hvis scriptet udfører en cd, da det også vil påvirke den overordnede (interaktive) shell.

Svar

bash script.sh påkalder scriptet direkte ved hjælp af bash.
./script.sh bruger shebang #!/bin/bash til at bestemme, hvordan man udfører.

Hvis du virkelig vil vide, hvilken binær der udføres, hvis du laver en bash script.sh du kunne finde ud af med which bash.

Så i dit eksempel gør det ingen forskel. Ja, du skal chmod +x script.sh for at kunne udføre det direkte via ./script.sh.

Kommentarer

  • Nå, det gør ingen forskel, forudsat at /bin/bash er den første bash i din $PATH.
  • Du ' har ret. Og shebang #!/bin/bash fungerer kun, hvis der er en /bin/bash
  • Bash (version 4.2.37) på min systemet udfører scripts selv uden eksekveringsbit-sæt. Hvorfor siger du, at eksekveringsbit er påkrævet?
  • Ja, eksekveringsbit er kun nødvendigt ved at påkalde via ./script.sh.

Svar

Opret en fil Delete_Self.sh sådan:

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

Kør dette script som sh Delete_Self.sh vil du se “Jeg er stadig her!” ekko tilbage.

Gør det eksekverbart, og kør det som ./Delete_Self.sh du vil se, at der ikke er noget, der gentages, mens filen Delete_Self.sh i sig selv er væk.

Så forskellen er, at:

  • bash script.sh ignorerer #! linje, fordi bash er angivet som programmet til at køre script.sh.
  • ./script.sh læser #! linje for at bestemme det program, der skal køres script.sh.

Kommentarer

  • +1 for det gode eksempel

Svar

Ud over de andre svar, at kende forskellen mellem at køre et script via ./script.sh (i) og kilde ./script.sh (ii) er nyttigt – versionen (i) opretter en ny skal, hvor kommandoen køres, hvorimod (ii) kører det i den aktuelle skal – hvilket kan være obligatorisk, hvis den eksekverbare ændrer miljøvariabler, der skal bevares, efter at den eksekverbare udgang. For eksempel skal følgende bruges for at aktivere et python-conda-miljø:

source activate my_env 

N.B. Et andet alternativ til source, som du muligvis støder på, er . indbygget, dvs.

. activate my_env 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *