![特定のファイルが見つかるまで現在のディレクトリをポップする](https://rvso.com/image/1311342/%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E8%A6%8B%E3%81%A4%E3%81%8B%E3%82%8B%E3%81%BE%E3%81%A7%E7%8F%BE%E5%9C%A8%E3%81%AE%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E3%83%9D%E3%83%83%E3%83%97%E3%81%99%E3%82%8B.png)
次のような動作をするスクリプトを書くことに興味があります。
- 現在のディレクトリに build.xml ファイルが存在するかどうかを確認し、存在する場合は、スクリプトの引数を通じて指定されたコマンドを実行します。
- そうでない場合は、現在のディレクトリをポップして親を確認します。 1 に進みます。
ファイルが見つかるかルートに到達するとスクリプトは終了します。また、スクリプトが終了して制御がユーザーに戻ったら、現在のディレクトリをスクリプトが最初にあったディレクトリにしたいです。
私はシェルスクリプトにあまり詳しくありませんが、どんな助けや指導でも大歓迎です。
答え1
bash では、次のようにしてこれを実現できます。
翻訳元
curr=`pwd`
file_name=build.xml
echo "Current directory: $curr"
while [ "$curr" != "/" ]; do
echo "Processing: $curr"
file="$curr/$file_name"
if [ -f "$file" ]; then
echo "Found at: $file, running command..."
cd "$curr"
"$@"
exit
fi
curr="`dirname \"$curr\"`"
done
echo "$file_name not found."
サンプル実行:
~$ cd /tmp
/tmp$ ls mkt.sh
mkt.sh
/tmp$ mkdir -p a/b/c/d
/tmp$ echo hello > a/build.xml
/tmp$ find a
a
a/build.xml
a/b
a/b/c
a/b/c/d
/tmp$ cd a/b/c/d
/tmp/a/b/c/d$ /tmp/mkt.sh cat build.xml
Current directory: /tmp/a/b/c/d
Processing: /tmp/a/b/c/d
Processing: /tmp/a/b/c
Processing: /tmp/a/b
Processing: /tmp/a
Found at: /tmp/a/build.xml, running command...
hello
/tmp/a/b/c/d$ rm /tmp/a/build.xml
/tmp/a/b/c/d$ r/tmp/mkt.sh cat build.xml
Current directory: /tmp/a/b/c/d
Processing: /tmp/a/b/c/d
Processing: /tmp/a/b/c
Processing: /tmp/a/b
Processing: /tmp/a
Processing: /tmp
build.xml not found.
また、スクリプトが終了し、制御がユーザーに戻ったら、現在のディレクトリをスクリプトが最初にあったディレクトリにしたい。
bash ではこれを行う必要はありません。子スクリプトは親 bash プロセスの現在の pwd を変更できません。次を試してください:
$ cd /tmp
$ echo "cd /usr" > a.sh
$ chmod u+x a.sh
$ pwd
/tmp
$ cat a.sh
cd /usr
$ ./a.sh
$ pwd
/tmp
ご覧のとおり、スクリプトcd /usr
内部が変更されたにもかかわらず、現在のパスワードは変更されていません。