私はメイクファイル内で次のことをしています
pushd %dir_name%
そして私は次のエラーを受け取ります
/bin/sh : pushd : not found
誰かがこのエラーが表示されている理由を教えてもらえますか?$ PATH変数を確認したところ、/ binが含まれているため、問題が発生しているとは思われません。
私はメイクファイル内で次のことをしています
pushd %dir_name%
そして私は次のエラーを受け取ります
/bin/sh : pushd : not found
誰かがこのエラーが表示されている理由を教えてもらえますか?$ PATH変数を確認したところ、/ binが含まれているため、問題が発生しているとは思われません。
回答:
pushd
あるbash
POSIX指定ボーンシェルに強化。pushd
現在の作業ディレクトリは子プロセスで変更できないプロセスの機能であるため、コマンドとして簡単に実装することはできません。(架空のpushd
コマンドがchdir(2)
呼び出しを行ってから新しいシェルを開始する可能性がありますが、それpushd
はあまり使い道がありません。)と同様に組み込みのシェルcd
です。
そのため、スクリプトを最初から変更するか#!/bin/bash
、現在の作業ディレクトリを変数に格納し、作業を行ってから元に戻します。非常に削減されたシステム(たとえば、Debianビルドサーバー)で動作するシェルスクリプトが必要か、または常に必要な場合に依存しますbash
。
SHELL = /bin/bash
、スクリプトをで開始するのではなく設定し#!/bin/bash
ます。
test1
私の答えであるstackoverflow.com/questions/5193048/bin-sh-pushd-not-found/…を参照してください。
#!/bin/bash
ファイルの最初の行を確認してください。
これの回避策は、変数に現在の作業ディレクトリを取得させることです。それから、あなたはそれからcdして何でもすることができ、それが必要なときにcdして戻すことができます。
すなわち
oldpath = `pwd` #スクリプトが行うことをすべて実行します ... ... ... #pushdしたいディレクトリに戻ります cd $ oldpath
cd
ディレクトリに移動して、後で実行することもできます。中間で使用しない場合cd -
は、その$oldpath
変数を使用する必要はありませんcd
。興味深い点pushd
は、それを使用するたびにディレクトリをスタックにプッシュし、後でを使用して最新のディレクトリに戻ることができるpopd
ため、複数のディレクトリに移動して必要な場合にそれを使用することは理にかなっています確かな帰り道。
(cd /new_path ; command )
これは、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とは異なるシェルで実行されます。
tcsh
(おそらくcsh
?)で終わると思います>
:$ tcsh haig:/> exit $ csh haig:/> exit $
(\u) \h:\w>
が、私のPS1は実際にそうですが、答えを出すために今、それを一般的な文字列に削除しました。DOSのプロンプトも>
デフォルトで終了しています($P$G
IIRC)。
シェル(/ bin / sh)が 'pushd'を見つけようとしています。しかし、「pushd」、「popd」、およびそのような他のコマンドはbashに組み込まれているため、それを見つけることができません。
今のように、Shの代わりにBash(/ bin / bash)を使用してスクリプトを起動すると、動作します
sudo dpkg-reconfigure dash
次にを選択しますno
。
他の応答からの合成: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ルールに置き換えます。ただ
gen/SvcGenLog :
mkdir -p gen
cd genscript > /dev/null \
&& perl genmakefile.pl \
&& mv Makefile ../gen/ \
echo "" > gen/SvcGenLog
(現在のディレクトリプレフィックスを削除しました。とにかくいくつかの点で相対パスを使用していました)そして、ルールをに依存させるだけではありませんgen/SvcGenLog
。少し読みやすくなり、依存するようにできるgenscript/genmakefile.pl
ので、スクリプトを変更するとMakefile
in gen
が再生成されます。もちろん、何かがのコンテンツに影響を与えるMakefile
場合は、ルールもそれに依存するようにできます。
pushd
です。あなたの中に押し込まれています$PATH
か?