Ich möchte das .sh-Skript für die Bereitstellung meiner App verwenden. Dieses Skript befindet sich auf meinem Heimserver (Ubuntu 15.10 Server) und ist als ausführbar markiert. Der Zugriff auf dieses Skript erfolgt über ssh. Mit diesem Tutorial habe ich die ssh-Anmeldung eingerichtet, mit der dieses Skript ausgeführt wird. Im Grunde rufe ich einfach auf ssh [email protected] someArguments
und es führt mein Skript mit someArguments
als Parameter aus. Der Benutzer deployer
hat uid = 0, also ist es im Grunde root
(dies wird in Zukunft geändert, ich habe es nur eingestellt, um Berechtigungsprobleme zu beseitigen, bis es gut funktioniert).
Und hier wird es schwierig. Das Skript meldet /usr/bin/env: php: No such file or directory
auf Befehl /bin/composer install
(mit Composer ). Die Dinge sind seltsamer, je mehr ich auf dieses Skript schaue. Vor dieser Zeile steht auch /bin/composer self-update
und /bin/composer -V
, das korrekt ausgeführt wird und die korrekte Ausgabe anzeigt.
Ich habe folgende Dinge überprüft:
/usr/bin/env php -v
zeigt die korrekte PHP-Version an (wie/usr/bin/php -v
)whereis php
Anzeigenphp: /usr/bin/php /usr/local/bin/php /usr/share/man/man1/php.1.gz
php5-cli
Paket ist installiert und neueste Version$PATH
enthält/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
which env
Anzeigen/usr/bin/env
Ich habe auch folgende Dinge versucht:
- Das Skript direkt wie
bash deploy.sh
unter root ausführen (da es mit diesem Benutzer identisch ist) - funktioniert einwandfrei ohne Fehler - Fehlerhafte Befehle direkt ausführen - auch perfekt ohne Fehler
Dies scheint mir also ein sehr spezifischer Fall zu sein, warum dieser Befehl nicht funktioniert. Ich habe 12 Stunden mit dem Debuggen verbracht und habe hier keine Ideen mehr.
PS: Ein ähnlicher Fehler ( /usr/bin/env: node: No such file or directory
) tritt auf, wenn bower install
(mit Bower ), aber nicht beim Ausführen npm install
(mit NPM ).
sh deploy
stattbash deploy
(vielleicht etwas Bashismus). Wie haben Sie die " folgenden Dinge " überprüft ? Ich empfehle, sie im Skript zu überprüfen, damit Sie eventuelle Überschreibungen und Bereinigungen von Envs feststellen können.sh deploy
undbash deploy
beide geben die gleichen Ergebnisse/usr/bin/env > environment.txt
Antworten:
Stellen Sie sicher, dass Zeilenenden und / oder unsichtbare Leerzeichen das Problem nicht verursachen.
Entfernen Sie die Leerzeichen in der ersten Zeile des Skripts und fügen Sie neue ein. Achten Sie dabei darauf, dass Sie beim Drücken der Leertaste nicht die STRG-Taste gedrückt halten.
Stellen Sie außerdem sicher, dass Sie keine DOS-Zeilenenden (CR + LF) haben. Weitere Informationen finden Sie unter /programming/82726/convert-dos-line-endings-to-linux-line-endings-in-vim .
quelle
Einfachster Weg .... Ändern Sie die Shell des Benutzers als Skript.
/ etc / passwd
Beispielskript (stellen Sie sicher, dass das Ausführungsbit auf chmod + x gesetzt ist)
/scripts/deploy.sh
Funktioniert immer! Sie sollten sogar in der Lage sein, das Skript zur Fehlerbehebung / zum Debuggen von Env-Variablen zu verwenden, von denen Sie glauben, dass sie nicht gesetzt sind usw. Auch die an ssh übergebenen Verarbeitungsargumente funktionieren.
Hinweis: Es wird empfohlen, die Pfade für Skripte, ausführbare Dateien usw. immer VOLLSTÄNDIG ZU QUALIFIZIEREN. Oben ist nur ein Beispiel aufgeführt, mit dem der Standardpfad so festgelegt werden kann, dass er moo.sh im Ordner moo aufruft.
Das war einfach .. Danke fürs posten ..
Referenz: / etc / passwd Format
quelle
ssh
auf dem Server, und nach dem Lane-Inauthorized_keys
wird das Skript aufgerufen und die Verbindung beendet. Wie soll ich Änderungen vornehmenauthorized_keys
, damit dies funktioniert?Der
env
Befehl durchsucht einen Benutzer$PATH
nach der ersten ausführbaren Datei mit dem angegebenen Namen. So/usr/bin/env php
wird für eine ausführbare Datei mit dem Namen suchenphp
in einem der Verzeichnisse in der$PATH
der Benutzer es läuft.In Ihrem Fall liegt das mit ziemlicher Sicherheit daran, dass Sie beim Ausführen eines Befehls
ssh
keine vollständige Shell starten und die Initialisierungsdateien Ihrer Shell nicht lesen. Sie können dies überprüfen, indem Sie diesen Befehl ausführen (beachten Sie die einfachen Anführungszeichen):Und vergleichen Sie die Ausgabe mit dem, was Sie erhalten, wenn Sie
ssh [email protected]
und dann ausführenecho $PATH
. Auf meinem System. beispielsweise:Daher ist das
$PATH
, auf das Ihr Skript beim Ausführen Zugriff hat,ssh [email protected]
nicht dasselbe wie beim Anmelden, um es zu testen.In jedem Fall besteht die einfache Lösung darin, stattdessen den vollständigen Pfad zum Interpreter zu verwenden
env
. Beideenv
und vollständige Pfade haben ihre Vor- und Nachteile, aber in diesem Fall ist der Pfad sicherer:quelle
composer install
Befehl gemeldet , den ich offensichtlich nicht ändern kann.$PATH
Ist auch in Ordnung, wie ich auch in meiner Frage erwähnt habe, habe ich alle Dinge überprüft, indem ich sie in das Skript eingefügt und per SSH-Login remote ausgeführt habe. Ich kann das auch nicht überprüfen,ssh [email protected] 'echo $PATH'
wie Sie angegeben haben, da mein SSH-Login nur auf ein Skript beschränkt ist, aber ich habe es jedoch überprüft, als ich $ PATH zu diesem Skript hinzugefügt habe (siehe oben). Wie auch immer, danke für Ihre Antwort und akzeptiere + 1 für die Erklärung derenv
Sacheenv
heißt eigentlich Inside Composer. Dies löst jedoch nicht das Problem, warum einige Komponistenaufrufe bestehen und andere nicht. Ich werde dies jedoch weiter untersuchen, indem ich mir den Code anschaue. Vielen Dank für Ihre ZeitIst es möglich, dass
bash
ein Reset auf die Hash-Tabelle erforderlich ist?In diesem Fall können Sie versuchen,
hash -r
irgendwo in Ihrem Skript etwas hinzuzufügen , wodurch die Shell gezwungen wird,$PATH
erneut zu suchen , anstatt sich auf (möglicherweise veraltete) Informationen aus der Hash-Tabelle zu verlassen.Bei Bedarf
hash
kann die Shell mithilfe der-p
Option auch Pfade zu ausführbaren Dateien speichern, die an nicht standardmäßigen Speicherorten installiert sind , oder Pfade mit der-d
Option vergessen .Quellen:
https://unix.stackexchange.com/a/86017/121251
https://stackoverflow.com/a/22543353/2146843
quelle
Sieht so aus, als müssten Sie Ihrem Pfad PHP hinzufügen. Versuchen:
Vielleicht möchten Sie auch überprüfen, wo Ihr PHP lebt, um sicherzustellen, dass der Pfad dort korrekt ist. Versuchen:
quelle
php -v
korrekte PHP-Version und diecomposer --version
Composer-Version ausgegeben werden. Wie gesagt, das Problem liegt nur in einem Befehl.Es ist klar, dass Sie ein Pfadproblem haben, da Ihr Bereitstellungsskript bei einer normalen SSH-Anmeldung keine Dinge finden kann, die sich definitiv auf dem Pfad befinden.
Um zu bestätigen, dass Sie ein PATH-Problem haben, müssen Sie zunächst Ihr Bereitstellungsskript aktualisieren, um die Ausgabe von
env
oder zumindest zu protokollierenecho $PATH
. Ich vermute, dass die Art und Weise, wie Ihr Bereitstellungsskript aufgerufen wird, $ PATH nicht wie erwartet festgelegt ist. Diese Debug-Ausgabe bestätigt / leugnet meine Theorie.Ich habe mir das Tutorial angesehen, dem Sie gefolgt sind. Sie sollten wahrscheinlich bei update sicherstellen , dass die
command=
sein ,command="/bin/sh /path/to/your/script..."
wenn Sie nicht bereits haben , um sicherzustellen , dass Ihr Skript durch die rechte Schale ausgeführt wird.Wenn Sie ein PATH-Problem haben, besteht eine schnelle / schmutzige Lösung darin, PATH zu Beginn Ihres Bereitstellungsskripts explizit festzulegen.
Detaillierte Erklärung und weitere Optionen ...
Unter Linux erben Befehle, wenn sie ausgeführt werden, die Umgebung ihres übergeordneten Prozesses.
Wenn Sie sich als normaler Benutzer über SSH anmelden, kann Folgendes passieren (z. B. Ausführen von / etc / bashrc / etc / profile ~ / .bash_profile ~ / .bashrc usw.). Zu diesem Zeitpunkt haben Sie möglicherweise die Umgebung Ihres Prozesses aktualisiert, indem Sie Dinge wie
export PATH="$PATH:~/mybin"
in diesen Skripten ausgeführt haben. Jetzt erben alle zukünftigen Prozesse, die Sie ausführen, Ihre aktuelle Umgebung.Das Ausführen eines Befehls anstelle einer Anmeldeshell bedeutet, dass der Befehl vom ssh-Daemon ausgeführt wird und die Umgebung des ssh-Daemon-Prozesses erbt. Dies unterscheidet sich wahrscheinlich von Ihrer Umgebung als angemeldeter Benutzer.
Die Manpage für autorisierte Schlüssel behandelt, was nach der Authentifizierung passiert. In Bezug auf die Umwelt:
Der geeignete Ort zum Konfigurieren der Umgebung für den Prozess befindet sich also im
~/.ssh/environment
Ausgangsverzeichnis~
des Benutzers, der zum Ausführen des Befehls authentifiziert ist. Sie müssen auch Ihre sshd_config überprüfen, um sicherzustellen, dass PermitUserEnvironment zulässig ist.~/.ssh/environment
Das Format ist natürlich auch in der Manpage angegeben.Eine alternative Möglichkeit, die Umgebung ohne Verwendung der oben genannten Methode anzugeben, besteht darin, die
environment="NAME=value"
Option in der Datei "authorized_keys" zu verwenden. Weitere Informationen finden Sie in der Manpage, die ich oben verlinkt habe.quelle
Without knowing exactly how you have setup your deploy script to run
: In meiner Frage am Anfang gibt es einen Link, wie ich es eingerichtet habe (mit~/.ssh/authorized_keys
. Danke für den Tipp mit dem Aktualisierungsbefehl, ich habe es versucht, aber leider ohne Unterschied. Ich werde dies jedoch weiter untersuchen und verschiedene Shells ausprobieren Bitte akzeptieren Sie eine +1 für diese Idee.