Ich habe ein einfaches Skript geschrieben. Wenn ich laufe sh <myscriptname.sh>
, erhalte ich die richtige Ausgabe, aber wenn ich laufe ./<myscriptname.sh>
, erhalte ich eine Fehlermeldung.
Was ist der Unterschied zwischen wann sh
und ./
?
Ich habe ein einfaches Skript geschrieben. Wenn ich laufe sh <myscriptname.sh>
, erhalte ich die richtige Ausgabe, aber wenn ich laufe ./<myscriptname.sh>
, erhalte ich eine Fehlermeldung.
Was ist der Unterschied zwischen wann sh
und ./
?
Antworten:
Wenn Sie ein Skript ausführen, indem Sie den Dateinamen an das Skriptinterpreterprogramm übergeben, führen Sie das Interpreterprogramm mit dem Skript als übergebenen Argument aus. Dies würde beispielsweise so aussehen wie der Prozess 'sh' mit dem Argument 'filename.sh'. Der sh
Interpreter öffnet die Datei.
Wenn Sie andererseits das Skript selbst ausführen, ruft das System das angegebene Interpreterprogramm auf und gibt den Skriptinhalt ein. In diesem Fall sieht der Prozess wie 'filename.sh' ohne Argumente aus.
Sie sollten sicherstellen, dass Sie eine Knalllinie haben:
#!/bin/bash
# bash script here
Eine Bang-Zeile ist die allererste Zeile im Skript und beginnt mit denselben zwei Zeichen #!
. Diese werden vom System gelesen, wenn es versucht, das Skript auszuführen, und das System übergibt das Skript unmittelbar danach an das Programm. Beachten Sie, dass diese Zeile nichts mit bash zu tun hat und für Python und Perl genauso gut funktioniert, auch wenn sie sehr unterschiedliche Sprachen sind. Sie würden #!/usr/bin/python
zum Beispiel verwenden und dann mit Python-Code folgen.
Stellen Sie sicher, dass Sie die Ausführungsberechtigungen festgelegt haben, nachdem Sie Ihr Skript erstellt haben:
chmod a+x filename.sh
Dann können Sie das Skript als eigenen Prozess ausführen:
./filename.sh
Oder legen Sie die Datei an einem bekannten Ort mit einem schönen Programmnamen ab, /usr/sbin
und führen Sie sie von überall aus:
sudo cp filename.sh /usr/sbin/program-name
program-name
Und dies ist wirklich der praktische Vorteil der Verwendung der Bang-Line mit den richtigen Berechtigungen - es geht nur um die Bereitstellung . Es ist sehr schwierig, Benutzer zum Ausführen eines Skripts zu bewegen, wenn sie sich merken müssen, mit welchem Programm das Skript ausgeführt werden soll. Denken Sie daran, dem Skript bei jeder Ausführung einen vollständigen Pfad zuzuweisen. Wenn Sie es beispielsweise einfügen /usr/local/bin
und ausführbar machen, können Sie den Leuten, die versuchen, Ihr Skript zu verwenden, sehr viel Kummer ersparen. Diese Programme stehen dann allen Benutzern auf Ihrem Computer zur Verfügung.
Es ist auch gut für die Identifizierung. Wenn Sie in das gehen top
Programm, ohne den Knall Linie ein Skript ausführen , müssen Sie einfach den Namen des Interpreten dh bash
, perl
oder python
. Wenn jedoch ein Skript mit den richtigen Berechtigungen ausgeführt wird, wird der Name des Skripts angezeigt.
Hinweis: Wenn Sie ein Skript verteilen möchten, auf das jeder zugreifen kann, erstellen Sie bitte eine Manpage und ein Deb-Paket, um es zu installieren. Wir müssen die Anzahl der zufälligen Skripte online reduzieren und die Anzahl der Debs erhöhen, die deinstalliert werden können.
bash
nicht ist sh
.
PATH
.
/usr/local/bin
ist wahrscheinlich besser als /usr/sbin
- es zeigt an, dass das Programm lokal auf diesem Computer ist, anstatt Teil der Distribution zu sein.
Die kurze Version:
sh
ist der Befehlszeileninterpreter (Bindestrich).
Beim Ausführen sh my_script
interpretiert dash das Skript.
./
versucht anhand der ersten Zeile herauszufinden, welcher Interpreter verwendet werden soll. ZB #!/bin/bash
oder sogar #!/bin/ruby
(im Gegensatz zum Laufen ruby my_script
).
./
was etwas findet, es ist die Systemausführungsmethode, die die ersten zwei Bytes der Datei betrachtet.
sh
sha-bang verwenden und die Datei enthält, bedeutet dies, dass sha-bang ignoriert wird, oder öffnet es die Shell, in der sich auch sh
Links befinden, und dann vielleicht eine andere Shell, oder was macht es :)?
Der Unterschied ist,
Mit führen sh
Sie ein Programm aus, das die Zeilen in Ihrem Skript so interpretiert, als hätten Sie sie über die interaktive Eingabeaufforderung des Terminals eingegeben.
Wenn ./
Sie eine Verknüpfung erstellen, gehen Sie davon aus, dass sich das Skript genau hier in dem aktuellen Verzeichnis befindet, in dem Sie sich befinden, UND dass es ausführbar sein wird (zum Beispiel, weil Sie es ausgestellt haben chmod +x myscript.sh
), was Ihnen wertvolle Zeit für zukünftige Zeiten erspart :-)
sh
der Datei nicht unbedingt ausführbar sein muss.
Es gibt drei Hauptgründe, warum Sie möglicherweise eine Fehlermeldung erhalten:
chmod +x <myscriptname.sh>
zu beheben , dassnoexec
"). /usr/local/bin
#!
Zeile ist ein Fehler #!/bin/sh
oder ist#!/bin/bash
Wenn Ihre erste Zeile richtig aussieht, aber immer noch nicht funktioniert, stellen Sie sicher, dass die Datei keine DOS-Zeilenenden hat.
Der Fehler würde ungefähr so aussehen:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Sie können das Problem beheben, indem Sie ausführen dos2unix <myscriptname.sh>
oder wenn Sie das nicht haben
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.
Und die Antwort ist, dass sh der Name für eine sehr beliebte Shell ist. Aber veraltet und durch andere ersetzt. Heutzutage ist sh mit anderen auf der Maschine installierten Shells verbunden. zB habe ich dort bash geputtet. Wenn Sie eine Shell von sh aus ausführen, wird normalerweise ein Kompatibilitätsmodus mit dem ursprünglichen Shell-Verhalten ausgelöst.
Die Lösung ist also ganz einfach. Schauen Sie nach, was sich hinter dem Befehl sh befindet (ls -al / bin / sh), und geben Sie #! / Bin / whatever_you_find_there als erste Zeile ein (oder bearbeiten Sie es, wenn es so etwas in Ihrem Skript gibt).
Und alternativ könnte es einen Fehler im Skript selbst geben. Wie eine Abhängigkeit, die von sh erfüllt wird, aber kein Interpret, der tatsächlich benutzt wird.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Nicht /usr/sbin
, das ist für unwesentliche administrative Tools /usr/local/bin
eine bessere Wahl, wenn Sie keine haben möchten ~/bin/
, aber sudo
es ist ratsam , so viel wie möglich zu vermeiden .
~/.profile
bereits Code zum Hinzufügen von ~/bin
, falls vorhanden, zu PATH
. In einem anderen Fall sollten Sie keine Erweiterungen für Skripte vornehmen.
ls ~/bin/|wc -l = 428
) Ich habe eine Menge Zeug da
/bin
und /usr/bin
Sie werden sehen , dass sie nicht Erweiterungen verwenden.