Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm interested in writing a script with the following behavior:

  1. See if a file, build.xml, exists in the current directory, if so run a command supplied through arguments to the script.
  2. If not, pop the current directory and look at the parent. Go to 1.

The script would end once we find the file or we reach the root. Also, once the script finishes and control comes back to the user I want the current directory to be that one where the script was initially l

I'm not very familiar with shell scripting but any help/guidance will be much appreciated.

share|improve this question
    
Any particular shell? –  Ignacio Vazquez-Abrams Apr 14 '12 at 2:38
    
zsh, but I think I can modify icyrock.com's answer. –  edarroyo Apr 17 '12 at 6:35
add comment

1 Answer

up vote 1 down vote accepted

In bash, you can achieve this e.g. like this:

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."

Sample run:

~$ 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.

Also, once the script finishes and control comes back to the user I want the current directory to be that one where the script was initially l

There's no need to do this in bash. Child scripts cannot change the current pwd of the parent bash process. Try this:

$ cd /tmp
$ echo "cd /usr" > a.sh
$ chmod u+x a.sh
$ pwd
/tmp
$ cat a.sh
cd /usr
$ ./a.sh
$ pwd
/tmp

As you can see, the current pwd did not change, even though the script did cd /usr inside it.

share|improve this answer
    
Nice, but this script would not find the desired file in the root directory. You might want to use do-while instead of while-do. I know, this is rather academic! No one would place their build.xml in /! ;) –  zpea Apr 14 '12 at 5:30
    
@zpea Well, the requirement as "The script would end once we find the file or we reach the root." - so, it's up to the specs ;) Useful comment, though, thanks! –  icyrock.com Apr 15 '12 at 20:55
    
Thanks! I'll see what I need to do to make it work in zsh. –  edarroyo Apr 17 '12 at 6:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.