143 votes

/ bin / sh: pushd: introuvable

Je fais ce qui suit dans un fichier make

 pushd %dir_name%
 

et j'obtiens l'erreur suivante

 /bin/sh : pushd : not found
 

Quelqu'un peut-il me dire pourquoi cette erreur apparaît? J'ai vérifié ma variable $ PATH et elle contient / bin, donc je ne pense pas que cela cause un problème.

147voto

sarnold Points 62720

pushd est bash d'amélioration de l'POSIX spécifié Bourne Shell. pushd ne peut pas être facilement mis en œuvre comme une commande, car le répertoire de travail courant est une fonction d'un processus qui ne peuvent pas être modifiées par les processus enfants. (Un hypothétique pushd commande peut faire l' chdir(2) appel et le début d'une nouvelle coque, mais ... il ne serait pas très utilisable.) pushd est une commande interne du shell, comme cd.

Donc, soit changer votre shell pour démarrer avec #!/bin/bash ou le magasin le répertoire de travail courant dans une variable, de faire leur travail, puis revenir. Dépend si vous voulez un shell script qui fonctionne très réduite des systèmes (par exemple, une Debian serveur de build) ou si vous êtes fine toujours exigeant bash.

39voto

ajouter

SHELL: = / bin / bash

en haut de votre makefile je l'ai trouvé sur une autre question Comment utiliser la syntaxe bash dans les cibles Makefile?

22voto

Classified Points 611

Une solution de contournement serait que la variable récupère le répertoire de travail actuel. Ensuite, vous pouvez en sortir pour faire n'importe quoi, puis quand vous en avez besoin, vous pouvez revenir en arrière.

c'est à dire

oldpath = `pwd`
# faites tout ce que fait votre script
...
...
...
# retourne au répertoire que tu voulais pousser
cd $ oldpath

12voto

hlovdal Points 11039

C'est parce que pushd est une fonction builtin dans bash. Donc, il n'est pas lié à la variable PATH et aussi il n'est pas pris en charge par /bin/sh (qui est utilisé par défaut par faire. Vous pouvez modifier que par la mise en COQUILLE (bien que cela ne fonctionnera pas directement (test1)).

Vous pouvez exécuter toutes les commandes par le biais bash -c "...". Qui va prendre les commandes, y compris pushd/popd, s'exécutent dans un environnement bash (test2).

SHELL = /bin/bash

test1:
        @echo before
        @pwd
        @pushd /tmp
        @echo in /tmp
        @pwd
        @popd
        @echo after
        @pwd

test2:
        @/bin/bash -c "echo before;\
        pwd; \
        pushd /tmp; \
        echo in /tmp; \
        pwd; \
        popd; \
        echo after; \
        pwd;"

Lors de l'exécution de faire test1 et faire test2 il donne les éléments suivants:

prompt>make test1
before
/download/2011/03_mar
make: pushd: Command not found
make: *** [test1] Error 127
prompt>make test2
before
/download/2011/03_mar
/tmp /download/2011/03_mar
in /tmp
/tmp
/download/2011/03_mar
after
/download/2011/03_mar
prompt>

Pour test1, même si bash est utilisé comme une coquille, chaque commande/de la ligne de la règle est exécutée par elle-même, de sorte que le pushd commande est exécutée dans un autre shell que la popd.

3voto

Jan Hudec Points 27417

Synthétiser à partir d'autres réponses: pushd est bash spécifiques et vous faire est d'utiliser un autre shell POSIX. Il existe une solution simple pour utiliser des shell pour la partie qui doit répertoire différent, donc, juste essayez de la remplacer par:

test -z gen || mkdir -p gen \
 && ( cd $(CURRENT_DIRECTORY)/genscript > /dev/null \
 && perl genmakefile.pl \
 && mv Makefile ../gen/ ) \
 && echo "" > $(CURRENT_DIRECTORY)/gen/SvcGenLog

(J'ai remplacé le long chemin avec une extension variable. J'ai probablement l'un est dans le makefile et s'étend dans le répertoire courant).

Puisque vous l'exécutez à partir de la, je serais probablement remplacer le test avec une règle, trop. Juste

gen/SvcGenLog :
    mkdir -p gen
    cd genscript > /dev/null \
     && perl genmakefile.pl \
     && mv Makefile ../gen/ \
    echo "" > gen/SvcGenLog

(a abandonné le répertoire courant préfixe; vous avez été à l'aide de chemin d'accès relatif à certains points de toute façon) Et que juste faire de l'etat dépendent gen/SvcGenLog. Il serait un peu plus lisible et vous pouvez le faire dépendre de l' genscript/genmakefile.pl , donc l' Makefile en gen sera régénérée si vous modifiez le script. Bien sûr, si rien d'autre affecte le contenu de l' Makefile, vous pouvez faire de l'etat en dépend aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X