Ich mache das Folgende in einer make-Datei
pushd %dir_name%
und ich bekomme folgenden Fehler
/bin/sh : pushd : not found
Kann mir bitte jemand sagen, warum dieser Fehler auftritt? Ich habe meine Variable $ PATH überprüft und sie enthält / bin, damit ich nicht glaube, dass dies ein Problem verursacht.
pushd
. Ist Pushd in deinem$PATH
?Antworten:
pushd
ist einebash
Erweiterung der POSIX-spezifizierten Bourne Shell.pushd
kann nicht einfach als Befehl implementiert werden, da das aktuelle Arbeitsverzeichnis eine Funktion eines Prozesses ist, der von untergeordneten Prozessen nicht geändert werden kann. (Ein hypothetischerpushd
Befehl könnte denchdir(2)
Aufrufpushd
ausführen und dann eine neue Shell starten, aber ... es wäre nicht sehr brauchbar.) Ist eine eingebaute Shell, genau wiecd
.Ändern Sie also entweder zunächst Ihr Skript
#!/bin/bash
oder speichern Sie das aktuelle Arbeitsverzeichnis in einer Variablen, erledigen Sie Ihre Arbeit und wechseln Sie dann zurück. Hängt davon ab, ob Sie ein Shell-Skript benötigen, das auf sehr reduzierten Systemen (z. B. einem Debian-Build-Server) funktioniert, oder ob Sie es immer benötigenbash
.quelle
SHELL = /bin/bash
eher eine Einstellung als ein Skriptstart mit#!/bin/bash
.test1
in meiner Antwort stackoverflow.com/questions/5193048/bin-sh-pushd-not-found/… .#!/bin/bash
die erste Zeile der Datei ist.hinzufügen
Oben in Ihrem Makefile habe ich es bei einer anderen Frage gefunden. Wie kann ich die Bash-Syntax in Makefile-Zielen verwenden?
quelle
Eine Problemumgehung hierfür wäre, dass eine Variable das aktuelle Arbeitsverzeichnis abruft. Dann können Sie eine CD herausnehmen, um alles zu tun, und wenn Sie es brauchen, können Sie wieder eine CD einlegen.
dh
quelle
cd
in das gewünschte Verzeichnis wechseln undcd -
diese$oldpath
Variable anschließend nicht mehr verwenden, wenn Sie sie nichtcd
zwischendurch verwenden. Das Interessante daranpushd
ist, dass Sie jedes Mal, wenn Sie es verwenden, ein Verzeichnis in einen Stapel verschieben und anschließend zum neuesten Verzeichnis zurückkehren können. Daher istpopd
es sinnvoll, es zu verwenden, wenn Sie in mehr als ein Verzeichnis wechseln und möchten ein sicherer Weg zurück.(cd /new_path ; command )
Dies liegt daran, dass pushd eine in bash integrierte Funktion ist. Es hängt also nicht mit der PATH-Variablen zusammen und wird auch nicht von / bin / sh unterstützt (was standardmäßig von make verwendet wird. Sie können dies ändern, indem Sie SHELL einstellen (obwohl es nicht direkt funktioniert (test1)).
Sie können stattdessen alle Befehle ausführen
bash -c "..."
. Dadurch werden die Befehle, einschließlich pushd / popd, in einer Bash-Umgebung ausgeführt (test2).Wenn Sie make test1 und make test2 ausführen, erhalten Sie Folgendes:
Für test1 wird, obwohl bash als Shell verwendet wird, jeder Befehl / jede Zeile in der Regel für sich ausgeführt, sodass der Befehl pushd in einer anderen Shell als popd ausgeführt wird.
quelle
tcsh
(und vielleichtcsh
?)>
$ tcsh haig:/> exit $ csh haig:/> exit $
(\u) \h:\w>
aber ich habe sie jetzt für die Antwort auf einen generischen String reduziert. Die Eingabeaufforderung unter DOS endet ebenfalls>
standardmäßig mit ($P$G
IIRC), und das gefällt mir.Ihre Shell (/ bin / sh) versucht, 'pushd' zu finden. Aber es kann es nicht finden, weil 'pushd', 'popd' und andere Befehle wie dieser in bash gebaut sind.
Starten Sie Ihr Skript mit Bash (/ bin / bash) anstelle von Sh, wie Sie es jetzt tun, und es wird funktionieren
quelle
Dann wählen Sie
no
.quelle
Die Synthese aus den anderen Antworten:
pushd
ist bash-spezifisch und Sie verwenden eine andere POSIX-Shell. Es gibt eine einfache Problemumgehung, um eine separate Shell für das Teil zu verwenden, das ein anderes Verzeichnis benötigt. Ändern Sie es also einfach in:(Ich habe den langen Pfad durch eine variable Erweiterung ersetzt. Ich bin wahrscheinlich einer im Makefile und er wird eindeutig auf das aktuelle Verzeichnis erweitert.)
Da Sie es von make aus ausführen, würde ich den Test wahrscheinlich auch durch eine make-Regel ersetzen. Gerade
(Das aktuelle Verzeichnispräfix wurde gelöscht. Sie haben ohnehin an einigen Stellen den relativen Pfad verwendet.) Und dann machen Sie die Regel einfach abhängig von
gen/SvcGenLog
. Es wäre ein bisschen besser lesbar und Sie können es auch von dem abhängig machengenscript/genmakefile.pl
, so dass dasMakefile
Ingen
neu generiert wird, wenn Sie das Skript ändern. Wenn sich irgendetwas anderes auf den Inhalt von auswirktMakefile
, können Sie die Regel natürlich auch davon abhängig machen.quelle
Beachten Sie, dass jede von einer make-Datei ausgeführte Zeile ohnehin in einer eigenen Shell ausgeführt wird. Wenn Sie das Verzeichnis wechseln, wirkt sich dies nicht auf nachfolgende Zeilen aus. Sie haben also wahrscheinlich wenig Verwendung für pushd und popd. Ihr Problem ist eher das Gegenteil, nämlich das Verzeichnis so lange zu ändern, wie Sie es brauchen!
quelle
Führen Sie "apt install bash" aus. Es installiert alles, was Sie benötigen, und der Befehl funktioniert
quelle
Hier ist eine Methode zu zeigen
sh -> bash
Führen Sie diesen Befehl auf dem Terminal aus
Danach sollten Sie sehen
Zeigen Sie auf / bin / bash (und nicht auf / bin / dash).
Referenz
quelle
Dies sollte den Trick tun:
Die Klammern starten eine neue untergeordnete Shell, wodurch das
cd
Verzeichnis nur innerhalb des untergeordneten Verzeichnisses geändert wird und alle darauf folgenden Befehle in den Klammern in diesem Ordner ausgeführt werden. Sobald Sie die Klammern verlassen, sind Sie wieder da, wo Sie vorher waren.quelle