/bin /sh: pushd: не найден

Я делаю следующее внутри файла make

pushd %dir_name%

и я получаю следующую ошибку

/bin/sh : pushd : not found

Может кто-нибудь сказать мне, почему эта ошибка появляется? Я проверил свою переменную $ PATH, и она содержит /bin, поэтому я не думаю, что это вызывает проблему.

73 голоса | спросил Pein 4 MarpmFri, 04 Mar 2011 14:20:16 +03002011-03-04T14:20:16+03:0002 2011, 14:20:16

8 ответов


0

pushd является расширением bash к указанной в POSIX оболочке Bourne. pushd не может быть легко реализовано как команда, поскольку текущий рабочий каталог является функцией процесса, которая не может быть изменена дочерними процессами. (Гипотетическая команда pushd может выполнить chdir(2) вызовите и затем запустите новую оболочку, но ... она не очень удобна в использовании.) pushd это встроенная оболочка, как и cd.

Итак, либо измените ваш скрипт, чтобы он начинался с #!/bin/bash, либо сохраните текущий рабочий каталог в переменной, сделайте свою работу, затем измените назад. Зависит от того, хотите ли вы сценарий оболочки, который работает на очень ограниченных системах (например, на сервере сборки Debian), или если у вас все нормально, всегда требуется bash.

ответил sarnold 4 MarpmFri, 04 Mar 2011 14:25:34 +03002011-03-04T14:25:34+03:0002 2011, 14:25:34
0

добавить

  

SHELL: = /bin /bash

вверху вашего make-файла Я нашел его в другом вопросе Makefile цели?

ответил Juan Jose Pablos 17 Mayam11 2011, 04:08:52
0

Обходной путь для этого должен был бы иметь переменную, получающую текущий рабочий каталог. Затем вы можете сделать из него все что угодно, затем, когда вам это нужно, вы можете вернуться обратно.

то есть.

OLDPATH = `pwd`
# делай, что делает твой скрипт
...
...
...
# вернитесь в каталог, который вы хотели нажать
cd $ oldpath
ответил Classified 31 +04002012-10-31T23:55:25+04:00312012bEurope/MoscowWed, 31 Oct 2012 23:55:25 +0400 2012, 23:55:25
0

Это потому, что pushd является встроенной функцией в bash. Таким образом, он не связан с переменной PATH, а также не поддерживается /bin /sh (который используется по умолчанию make. Вы можете изменить это, установив SHELL (хотя он не будет работать напрямую (test1)).

Вместо этого вы можете выполнить все команды через bash -c "...". Это заставит команды, включая pushd /popd, работать в среде 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;"

При запуске make test1 и make test2 выдается следующее:

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>

Для test1, даже если bash используется в качестве оболочки, каждая команда /строка в правиле запускается сама по себе, поэтому команда pushd запускается в другой оболочке, нежели popd.

ответил hlovdal 4 MarpmFri, 04 Mar 2011 14:26:08 +03002011-03-04T14:26:08+03:0002 2011, 14:26:08
0

Ваша оболочка (/bin /sh) пытается найти «pushd». Но он не может найти его, потому что команды «pushd», «popd» и другие подобные команды встроены в bash.

Запустите ваш скрипт, используя Bash (/bin /bash) вместо Sh, как вы делаете сейчас, и он будет работать

ответил joseignaciorc 4 MarpmFri, 04 Mar 2011 14:26:18 +03002011-03-04T14:26:18+03:0002 2011, 14:26:18
0

Синтезирование из других ответов: pushd зависит от bash, и вы используете другую оболочку POSIX. Существует простой обходной путь для использования отдельной оболочки для части, которая нуждается в другом каталоге, поэтому просто попробуйте изменить ее на:

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

(я заменил длинный путь расширением переменной. Я, вероятно, один в make-файле, и он явно расширяется до текущего каталога).

Поскольку вы запускаете его из make, я бы, вероятно, также заменил тест правилом make. Просто

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

(отбросил текущий префикс каталога; в любом случае вы использовали относительный путь в некоторых точках) И чем просто заставить правило зависеть от gen/SvcGenLog. Это было бы немного более читабельно, и вы можете сделать так, чтобы это зависело и от genscript/genmakefile.pl, поэтому Makefile в gen будет обновлено, если вы измените скрипт. Конечно, если что-то еще влияет на содержимое Makefile, вы также можете сделать правило зависимым от этого.

ответил Jan Hudec 4 MarpmFri, 04 Mar 2011 15:11:33 +03002011-03-04T15:11:33+03:0003 2011, 15:11:33
0

Обратите внимание, что каждая строка, выполняемая файлом make, в любом случае запускается в своей собственной оболочке. Если вы измените каталог, это не повлияет на последующие строки. Так что вы, вероятно, мало пользуетесь pushd и popd, ваша проблема скорее в том, чтобы заставить каталог оставаться измененным до тех пор, пока он вам нужен!

ответил Mark Baker 4 MarpmFri, 04 Mar 2011 15:15:48 +03002011-03-04T15:15:48+03:0003 2011, 15:15:48
0

Запустите "apt install bash" Он установит все, что вам нужно, и команда будет работать

ответил MatanN 16 +03002018-10-16T14:41:23+03:00312018bEurope/MoscowTue, 16 Oct 2018 14:41:23 +0300 2018, 14:41:23

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132