Ausführen von Skripten aus einem anderen Verzeichnis

11

Sehr oft befindet sich das Skript, das ich ausführen möchte, nicht in meinem aktuellen Arbeitsverzeichnis und ich möchte es nicht wirklich verlassen.

Ist es eine gute Praxis, Skripte (BASH, Perl usw.) aus einem anderen Verzeichnis auszuführen? Finden sie normalerweise alles, was sie brauchen, um richtig zu laufen?

Wenn ja, wie lässt sich ein "entferntes" Skript am besten ausführen? Ist es

. /path/to/script

oder

sh /path/to/script

und wie sudoin solchen Fällen zu verwenden? Dies funktioniert zum Beispiel nicht:

sudo . /path/to/script
Desmond Hume
quelle
Beachten Sie, dass das Skript als . /path/to/script Quelle dient ! Sie benötigen den Zeitraum überhaupt nicht, wenn Sie ihn nur ausführen möchten.
gniourf_gniourf

Antworten:

14

sh / path / to / script erzeugt eine neue Shell und führt das Skript unabhängig von Ihrer aktuellen Shell aus. Der sourceBefehl (.) Ruft alle Befehle im Skript in der aktuellen Shell auf. Wenn das Skript exitbeispielsweise aufruft, verlieren Sie die aktuelle Shell. Aus diesem Grund ist es normalerweise sicherer, Skripte in einer separaten Shell mit sh aufzurufen oder sie als Binärdateien entweder über den vollständigen (beginnend mit /) oder den relativen Pfad (./) auszuführen. Wenn sie als Binärdateien aufgerufen werden, werden sie mit dem angegebenen Interpreter ausgeführt (z. B. #! / Bin / bash).

Um zu wissen, ob ein Skript die benötigten Dateien findet oder nicht, gibt es keine gute Antwort, außer das Skript zu betrachten, um zu sehen, was es tut. Optional können Sie in einem Unterprozess jederzeit zum Ordner des Skripts wechseln, ohne den aktuellen Ordner zu verlassen:

$(cd /wherever/ ; sh script.sh)
Ярослав Рахматуллин
quelle
3
Meinst du (cd /wherever/ ; sh script.sh)? Warum hast du eine $vor?
G-Man sagt "Reinstate Monica"
7

Sie können das definitiv tun (mit den Anpassungen, die die anderen wie sudo sh /pathto/script.shoder mögen ./script.sh). Ich mache jedoch eines der wenigen Dinge, um sie systemweit auszuführen, um mir keine Sorgen um Verzeichnisse zu machen und mir unnötiges zusätzliches Tippen zu ersparen.

1) Symlink zu /usr/bin

ln -s /home/username/Scripts/name.sh /usr/bin/name

(Stellen Sie sicher, dass dort kein überlappender Name vorhanden ist, da Sie ihn offensichtlich überschreiben würden.) Auf diese Weise kann ich sie auch in meinen Entwicklungsordnern behalten, damit ich sie nach Bedarf anpassen kann.

2) Fügen Sie das Skriptverzeichnis zu Ihrem Pfad hinzu (mithilfe von .bash_profile - oder einem beliebigen Profil, das Sie auf Ihrer Shell haben).

PATH=/path/to/scripts/:$PATH

3) Erstellen Sie Alias ​​im .bash_profile In und ~/.bash_profilefügen Sie Folgendes hinzu:

alias l="ls -l"

Wie Sie sehen können, ist die Syntax nur ein Alias, Ziffern, die Sie als Befehl fungieren möchten, der Befehl. ls -l Wenn Sie also irgendwo im Terminal "l" eingeben, erhalten Sie Wenn Sie sudo möchten, nur alias sl="sudo ls -l"um sich selbst l vs sl (als nutzloses Beispiel) zu notieren.

In jedem Fall können Sie einfach tippen sudo nameofscriptund unterwegs sein. Sie müssen sich nicht mit ./ oder. oder sh usw. Markieren Sie sie zuerst als ausführbare Datei: D.

Nerdwaller
quelle
Ich würde Option 2 wärmstens empfehlen.
Bernhard
Warum? Ist es eine bewährte Methode oder nur Geschmack?
Sergio
3

Normalerweise mag ich es, wenn du sagst

sh /path/to/script

Und um es als root / superuser auszuführen

sudo sh /path/to/script

Ihr aktuelles Verzeichnis ist nur wichtig, wenn die Skripte davon ausgehen, dass Sie sich im selben Ordner wie es befinden. Ich würde annehmen, dass die meisten Skripte dies nicht tun und Sie sicher sind, es wie oben auszuführen.

Bolli
quelle
würde nicht funktionieren, wenn Secure_path in der Datei / etc / sudoers festgelegt ist
l1zard
3

Normalerweise behalte ich meine Skripte in /usr/local/binoder /usr/local/sbin/(wenn das Skript Root-Berechtigungen benötigt), wo sie gemäß dem FHS (Filesystem Hierarchy Standard) hingehören.

Sie müssen lediglich sicherstellen, dass diese beiden Verzeichnisse zu Ihrem Verzeichnis hinzugefügt werden PATH. Sie können dies tun, indem Sie Ihre $HOME/.bashrcDatei bearbeiten und diese Zeile hinzufügen:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

Wenn Sie ein Skript als root über ausführen möchten, müssen sudoSie diese Verzeichnisse der Variablen secure_pathin Ihrem hinzufügen /etc/sudoers.

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Das Bearbeiten dieser Datei erfolgt durch Ausführen visudo, um sicherzustellen, dass Sie keine Fehler haben.

l1zard
quelle
Tippfehler: du meinst .bashrcstatt .bachrc.
gniourf_gniourf
0

Ich bin mir nicht sicher, ob es unter Linux so funktioniert, vorausgesetzt, es funktioniert nicht, wenn niemand es vorgeschlagen hat. Aber anstatt ././ zu verwenden, um Verzeichnisse zurückzugehen. Können Sie Anführungszeichen verwenden, um einen absoluten Pfad anzugeben? Vielleicht gibt es Ihnen keinen Zugriff auf das gesamte Laufwerk, um überhaupt dazu in der Lage zu sein.

Codezilla
quelle
0

Wenn Sie Skripte herumliegen haben, die Sie häufig ausführen müssen und die von ihrem Speicherort abhängen, um Ressourcen zu finden, können Sie dies einfach tun, indem Sie einfach Befehle in einem Alias ​​wie diesem kombinieren.

alias run-script="cd /home/user/path/to/script/ && bash script.sh"

Auf diese Weise müssen Sie nichts anderes ändern, damit es funktioniert.

EvR2f
quelle
0

Ich bin mir nicht sicher, warum niemand diesen vorgeschlagen hat, aber es ist super einfach! Ich habe ein paar Mal gegoogelt und konnte nicht genau die Antwort finden, die ich gebe, also hatte ich gedacht, ich würde sie teilen. IMO, dies ist aber die beste Lösung, auch die einfachste für mich, wie auch immer andere die Dinge anders fühlen und tun mögen.

# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit

YOURCOMMAND () {
  cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}

Zuerst der Befehl 'cd', der das Verzeichnis des Speicherorts des Skripts angibt. Dann '&&', damit Sie es binden können, nachdem Sie den nächsten Befehl ausgeführt haben. Öffnen Sie Ihr Skript schließlich so, als würden Sie es im Terminal ausführen! Sie werden in Ihrer BASH-Datei gespeichert und die Einrichtung dauert 5 Sekunden.

Hoffe das hat jemandem geholfen.

AnonymousX
quelle
-1

Alte Frage, aber eine zeitlose.

Die Lösung, die ich immer wieder gesehen habe, besteht darin, ein $HOME/binVerzeichnis zu haben und es zuerst einzutragen $PATH(über, ~/.bashrcfalls es noch nicht vorhanden ist; auf einigen Systemen ~/binist es $PATHstandardmäßig das erste ). Das Ablegen von Skripten zur Ausführung oder von Symlinks zu Skripten / ausführbaren Dateien an anderer Stelle ist die einfache Möglichkeit, Pfadprobleme zu beheben, die das System oder andere Benutzer nicht betreffen sollten.

Wenn ein Skript zusätzliche Ressourcen benötigt, die relativ zu seinem eigenen Speicherort gefunden werden können (nicht ungewöhnlich), wird die envvar $BASH_SOURCEverwendet. $BASH_SOURCEenthält immer den absoluten Pfad zum aktuell ausgeführten Skript selbst, unabhängig vom Wert von $PWD.

Folgendes berücksichtigen:

ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Wir können also sehen, dass dies der $HOME/binerste ist $PATH, und alles, was ich eingebe ~/bin, läuft. Ich habe ein Demonstrationsskript namens ~/bin/findme:

#!/bin/bash

echo "Running from $BASH_SOURCE"

Dies kann verwendet werden, um den absoluten Pfad zum Speicherort des laufenden Skripts abzurufen.

ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme
zxq9
quelle
(1) Während dies scheint nützliche Informationen zu sein, die Frage nicht fragen , wie man Schreib Skripte , dass die Verwendung Ressourcen in Bezug auf den eigenen Standort; Es wurde nach dem Ausführen von Skripten gefragt. (2) Ich bin mir nicht sicher, wie Ihr zweiter Absatz die Frage behandelt. Schlagen Sie vor, dass Desmond, wenn ich ein Skript schreibe und es ausführen möchte, es mit seinem privaten binVerzeichnis verknüpfen sollte ? Das scheint umständlich. (3) Außerdem wird die Standortunabhängigkeit verletzt. Wenn /home/desmond/bin/fooes sich um einen Link zu meinem Skript handelt, ist dies BASH_SOURCEder Fall /home/desmond/bin/foo, und das Skript kann seine Ressourcen nicht finden.
G-Man sagt "Reinstate Monica"
@ G-Man (1) Der Benutzer hat nicht viel Kontext angegeben. Wann immer diese Frage in den letzten 30 Jahren an mich gestellt wurde, war es immer der Kontext, in dem ein Benutzer (normalerweise ein neuer Sysop oder Entwickler) eine Mischung aus seinen eigenen und anderen erworbenen Skripten ausführte, um triviale Aufgaben zu automatisieren. Deshalb habe ich darauf geantwortet Weg. Dies setzt ein wenig Skriptwissen seitens des fragenden Benutzers voraus. (2) Systemweite Skripte werden normalerweise an /binoder an einem bekannten Ort installiert /opt. (3) Die Standortunabhängigkeit ist genau das, was beim Schreiben einer voneinander abhängigen Sammlung persönlicher Skripte erhalten bleibt.
zxq9