Мне интересно написать скрипт со следующим поведением:
- Проверьте, существует ли файл build.xml в текущем каталоге, если да, выполните команду, указанную в аргументах скрипта.
- Если нет, вытащите текущий каталог и посмотрите на родительский. Перейдите к 1.
Скрипт завершится, как только мы найдем файл или достигнем корня. Также, как только скрипт завершится и управление вернется к пользователю, я хочу, чтобы текущим каталогом был тот, где изначально был скрипт l
Я не очень хорошо разбираюсь в написании сценариев оболочки, но буду очень признателен за любую помощь/руководство.
решение1
В bash это можно сделать, например, так:
mkt.sh
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 этого делать не нужно. Дочерние скрипты не могут изменить текущий pwd родительского процесса bash. Попробуйте это:
$ 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
внутри него изменился.