Wykonuję następujące czynności wewnątrz pliku make
pushd %dir_name%
i otrzymuję następujący błąd
/bin/sh : pushd : not found
Czy ktoś może mi powiedzieć, dlaczego ten błąd się pojawia? Sprawdziłem moją zmienną $ PATH i zawiera ona / bin, więc nie sądzę, że powoduje to problem.
pushd
. Czy jest wciśnięty w twoim$PATH
?Odpowiedzi:
pushd
jestbash
rozszerzeniem powłoki Bourne Shell określonej w standardzie POSIX.pushd
nie można łatwo zaimplementować jako polecenie, ponieważ bieżący katalog roboczy jest cechą procesu, której nie można zmienić przez procesy potomne. (Hipotetycznepushd
polecenie może wykonaćchdir(2)
wywołanie, a następnie uruchomić nową powłokę, ale ... nie byłoby to zbyt użyteczne.)pushd
Jest wbudowaną powłoką, tak jakcd
.Zatem albo zmień skrypt, aby zaczynał od,
#!/bin/bash
albo zapisz bieżący katalog roboczy w zmiennej, wykonaj swoją pracę, a następnie zmień z powrotem. Zależy od tego, czy potrzebujesz skryptu powłoki, który działa na bardzo ograniczonych systemach (powiedzmy, serwer kompilacji Debiana), czy też możesz zawsze wymagaćbash
.źródło
SHELL = /bin/bash
zamiast uruchamiania skryptu z#!/bin/bash
.test1
w mojej odpowiedzi stackoverflow.com/questions/5193048/bin-sh-pushd-not-found/… .#!/bin/bash
jest to pierwsza linia pliku.Dodaj
na początku twojego pliku makefile znalazłem go w innym pytaniu. Jak mogę używać składni Bash w celach Makefile?
źródło
Aby obejść ten problem, zmienna powinna pobierać bieżący katalog roboczy. Następnie możesz z niego wydobyć CD, aby zrobić cokolwiek, a kiedy tego potrzebujesz, możesz z powrotem wejść.
to znaczy
źródło
cd
do katalogu, który chcesz, a potem zrobićcd -
, nie musisz używać tej$oldpath
zmiennej, jeśli nie będziesz używaćcd
między. Ciekawostkąpushd
jest to, że za każdym razem, gdy go używasz, umieszczasz katalog na stosie, a potem możesz wrócić do ostatniego, używającpopd
, więc sensowne jest użycie go, gdy wchodzisz do więcej niż jednego katalogu i chcesz pewna droga powrotna.(cd /new_path ; command )
Dzieje się tak, ponieważ pushd jest funkcją wbudowaną w bash. Nie jest więc powiązany ze zmienną PATH, a także nie jest obsługiwany przez / bin / sh (który jest używany domyślnie przez make. Możesz to zmienić ustawiając SHELL (chociaż nie będzie to działać bezpośrednio (test1)).
Zamiast tego możesz uruchomić wszystkie polecenia
bash -c "..."
. Spowoduje to, że polecenia, w tym pushd / popd, będą działać w środowisku bash (test2).Podczas uruchamiania make test1 i make test2 daje to co następuje:
W przypadku testu1, mimo że bash jest używany jako powłoka, każde polecenie / wiersz w regule jest uruchamiane samodzielnie, więc polecenie pushd jest uruchamiane w innej powłoce niż popd.
źródło
tcsh
(a możecsh
?)>
$ tcsh haig:/> exit $ csh haig:/> exit $
(\u) \h:\w>
ale właśnie rozebrałem go do ogólnego ciągu znaków, aby uzyskać odpowiedź. Podpowiedź w DOS również>
domyślnie kończy się na ($P$G
IIRC) i podoba mi się to.Twoja powłoka (/ bin / sh) próbuje znaleźć „pushd”. Ale nie może go znaleźć, ponieważ „pushd”, „popd” i inne podobne polecenia są wbudowane w bash.
Uruchom skrypt za pomocą Bash (/ bin / bash) zamiast Sh, jak teraz robisz, i zadziała
źródło
Następnie wybierz
no
.źródło
Syntetyzacja z innych odpowiedzi:
pushd
jest specyficzna dla basha, a twój make używa innej powłoki POSIX. Istnieje proste obejście, aby użyć oddzielnej powłoki dla części, która wymaga innego katalogu, więc po prostu spróbuj zmienić ją na:(Zastąpiłem długą ścieżkę rozwinięciem zmiennej. Prawdopodobnie znajduje się w pliku makefile i wyraźnie rozwija się do bieżącego katalogu).
Ponieważ uruchamiasz go z make, prawdopodobnie zastąpiłbym test również regułą make. Właśnie
(usunięto prefiks bieżącego katalogu; i tak w niektórych miejscach używałeś ścieżki względnej) I nie tylko uzależnij regułę od
gen/SvcGenLog
. Byłoby nieco bardziej czytelne i można zrobić to zależy odgenscript/genmakefile.pl
zbyt, więcMakefile
wgen
będzie regenerowany jeśli zmodyfikować skrypt. Oczywiście, jeśli cokolwiek innego wpływa na zawartośćMakefile
, możesz uzależnić regułę również od tego.źródło
Zauważ, że każda linia wykonywana przez plik make i tak jest uruchamiana we własnej powłoce. Jeśli zmienisz katalog, nie wpłynie to na kolejne wiersze. Więc prawdopodobnie nie masz pożytku z pushd i popd, twój problem jest bardziej odwrotny, niż zmiana katalogu tak długo, jak tego potrzebujesz!
źródło
Uruchom "apt install bash" Zainstaluje wszystko, czego potrzebujesz, a polecenie zadziała
źródło
oto metoda na wskazanie
sh -> bash
uruchom to polecenie na terminalu
Po tym powinieneś zobaczyć
wskaż / bin / bash (a nie / bin / dash)
Odniesienie
źródło
To powinno załatwić sprawę:
Nawiasy rozpoczynają nową powłokę podrzędną, a zatem
cd
zmienia katalog tylko w obrębie dziecka, a każde polecenie znajdujące się po nim w nawiasach zostanie uruchomione w tym folderze. Po wyjściu z nawiasów jesteś z powrotem tam, gdzie byłeś wcześniej.źródło