[linux-l] Datum in Script verwenden

Frank Reker frank at reker.net
So Apr 8 05:17:17 CEST 2007


Am Sat 07. Apr 2007 21:13 +0200 schrieb Boris Kirkorowicz:

>Hallo,
>
>Am 07.04.2007 12:37 schrieb Nico Golde:
>>>     #!/bin/bash
>>> oder auch:
>>>     #!/usr/bin/env bash
>
>was ist denn der Unterschied zwischen den beiden Schreibweisen? Es wird
>ja mehr als nur ein Stilelement sein, oder?
>
>
>> Wenn man Shellprogrammierung lernt, lernt man in der Regel 
>> keine Bash-Programmierung, falls doch, schreibt man da 
>> #!/bin/bash rein, falls nicht lässt man es.
>
>Wofür ist die Zeile überheupt genau da, bzw. was passiert oder kann
>passieren, wenn man sie weglässt?


um ein prog auszufuehren muss der kernel wissen wie, dafuer schaut
er sich die magic-numbers an. dadurch weiss er, ob es sich um ein
elf-, aout-, ... executable handelt. findet er in den ersten beiden
bytes ein #! weiss er, dass es sich um ein skript-executable handelt.
der script-interpreter folgt dan den beiden bytes (und ggfs einigen
leerzeichen). in diesem fall also /bin/bash. der kernel ruft dann
den interpreter auf und uebergibt ihm das script als parameter.
dem interpreter koennen auch noch andere parameter folgen, z.b.:
#!/bin/bash -x
dadurch wird die bash mit -x ausgefuehrt. das script selbst wird dann
als letzter parameter uebergeben. der interpreter (hier also die
bash) ist dann fuer die ausfuehrung des scriptes verantwortlich.

fehlt diese zeile, kann der kernel das script nicht ausfuehren,
er weiss naemlich dann nicht, dass es sich um ein script handelt.
du muesstest dann den script-interpreter explizit aufrufen; also
z.b.: bash myscript.
wenn du ein bash-script aus der bash aufrufst (bei einigen anderen
shells ist das aehnlich) wird es auch ohne die erste zeile
funktionieren, weil die bash so schlau ist, das script als solches
zu erkennen und dann direkt ausfuehrt, ohne sich auf den kernel
zu verlassen. das funktioniert dann aber nur, wenn du dein script
aus der bash aufrufst. wird es aus einem anderen programm heraus
aufgerufen funktioniert es nicht mehr.

da der kernel den interpreter nicht sucht, muss hier der komplette
pfad angegeben werden. ein
#!bash
tut es also nicht. das ist bei der bash kein problem, da sie eigentlich
(fast) immer unter /bin/bash erreichbar ist. bei anderen
script-interpretern wie z.b. perl ist das nicht immer gegeben.
perl kann sich je nach system z.b. in /usr/bin/perl oder auch
/usr/local/bin/perl oder ganz wo anders befinden.
damit das script dann auf allen system laeuft, gibt es
/bin/env (env macht eigentlich noch was anderes, kann aber dafuer
verwendet werden) welches in der lage ist an verschiedenen orten
nach perl (oder was auch immer) zu suchen.
der kernel wuerde dann also /bin/env als interpreter aufrufen
welches perl sucht und ausfuehrt.
ist bei der bash aber nicht noetig, da die eigentlich (fast) immer
unter /bin/bash erreichbar ist.
wenn env verwendet wird, sollte es aber in /bin und nicht in
/usr/bin liegen, da auf vielen systemen / und /usr zwei
verschiedene partitionen sind. beim boot oder im single-user-mode ist
dann /usr u.u. nicht verfuegbar, so dass env nicht ausgefuehrt
werden kann und das script nicht mehr laeuft. leider ist das aber
nicht auf allen system der fall, wodurch sich mit env das selbe problem
ergibt, dass es eigentlich loesen sollte.

da die eigentliche aufgabe von env aber ist die umgebungsvariablen zu
veraendern kann das auch bei shells interessant sein. z.b. wenn ein
script mit super-user-rechten laeuft (auf neueren linuxen (leider) nicht
mehr moeglich, auf anderen unixen aber sehr wohl), koennte ein user u.u.
durch manipulation der umgebungsvariablen sich root-rechte verschaffen.
ein:
#!/bin/env -i bash
wuerde da abhilfe schaffen.


-- 
Don't worry be happy ...
Ciao Frank
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : nicht verfügbar
Dateityp    : application/pgp-signature
Dateigröße  : 189 bytes
Beschreibung: nicht verfügbar
URL         : <https://mlists.in-berlin.de/pipermail/linux-l-mlists.in-berlin.de/attachments/20070408/6a9ba461/attachment.sig>


Mehr Informationen über die Mailingliste linux-l