Вывести текущий каталог, пока не будет найден конкретный файл

1

Я заинтересован в написании сценария со следующим поведением:

  1. Посмотрите, существует ли файл build.xml в текущем каталоге, если это так, выполните команду, переданную через аргументы скрипту.
  2. Если нет, откройте текущий каталог и посмотрите на родительский. Перейти к 1.

Сценарий завершится, как только мы найдем файл или достигнем корня. Кроме того, как только скрипт завершится и управление вернется к пользователю, я хочу, чтобы текущим каталогом был тот каталог, в котором скрипт был изначально установлен.

Я не очень знаком с сценариями оболочки, но любая помощь / руководство будет высоко ценится.

edarroyo
источник
Какая-то конкретная оболочка?
Игнасио Васкес-Абрамс
зш, но я думаю, что могу изменить ответ icyrock.com.
edarroyo

Ответы:

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

Как вы можете видеть, текущий pwd не изменился, хотя скрипт cd /usrвнутри него.

icyrock.com
источник
Хорошо, но этот скрипт не найдет нужный файл в корневом каталоге. Вы можете использовать do-whileвместо while-do. Я знаю, это довольно академично! Никто не поместит их build.xml в /! ;)
zpea
@zpea Ну, требование: «Сценарий закончится, как только мы найдем файл или достигнем корня». - так, это зависит от спецификации;) Полезный комментарий, хотя, спасибо!
icyrock.com
Спасибо! Я посмотрю, что мне нужно сделать, чтобы это работало в Zsh.
edarroyo