Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

E.g. check if $PWD is a subdirectory of /home. In other words I'm searching for a bash string operation to check if one string starts with another.

share|improve this question

7 Answers 7

up vote 4 down vote accepted

How about this:

test "${PWD##/home/}" != "${PWD}"

If $PWD starts with "/home/", it gets stripped off in the left side, which means it won't match the right side, so "!=" returns true.

share|improve this answer
    
+1 perfect, and for a more general case: [ "${PWD##$VAR}" != "$PWD" ] And if this were a [code-golf ](stackoverflow.com/questions/tagged/code-golf)question you'd have beaten me by two chars ;-) Also it looks more readable... –  Tobias Kienzler Jan 26 '11 at 11:16

To test if a string is a prefix of another, in any Bourne-style shell:

case $PWD/ in
  /home/*) echo "home sweet home";;
  *) echo "away from home";;
esac

The same principle works for a suffix or substring test. Note that in case constructs, unlike in file names, * matches any character, including a / or an initial ..

In shells that implement the [[ … ]] syntax (i.e. bash, ksh and zsh), it can be used to match a string against a pattern. (Note that the [ command can only test strings for equality.)

if [[ $PWD/ = /home/* ]]; then …

If you're specifically testing whether the current directory is underneath /home, a simple substring test is not enough, because of symbolic links.

If /home is a filesystem of its own, test whether the current directory (.) is on that filesystem.

if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
  echo 'The current directory is on the /home filesystem'
fi

If you have the NetBSD, OpenBSD or GNU (i.e. Linux) readlink, you can use readlink -f to strip symbolic links from a path.

case $(readlink -f .)/ in $(readlink -f /home)/*) …

Otherwise, you can use pwd to show the current directory. But you must take care not to use a shell built-in if your shell tracks cd commands and keeps the name you used to reach the directory rather than its “actual” location.

case $(pwd -P . 2>/dev/null || command pwd)/ in
  $(cd /home && { pwd -P . 2>/dev/null || command pwd; })/*) …
share|improve this answer
    
+1 Thanks for this exhaustive answer. I didn't consider links and filesystem peculiarities when asking this, but it's definitely good to know –  Tobias Kienzler Jan 26 '11 at 11:08

Crude version:

[ ${PWD:0:6} = "/home/" ]

Has the disadvantage that one has to count characters first and one can't replace /home/ by something general like $1.

edit (thanks @Michael) for the generalization to compare with $VAR one can use

[ "${PWD:0:${#VAR}}" = $VAR ]
share|improve this answer
3  
${#var} is the length of $var, so you can generalize it as [ "${PWD:0:${#1}}" = "$1" ] –  Michael Mrozek Jan 25 '11 at 15:58
    
@Michael Mrozek♦: Thanks, works perfect :) –  Tobias Kienzler Jan 26 '11 at 11:03

Using awk:

echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
share|improve this answer
    
+1 for working, but a bit slower than a native bash test –  Tobias Kienzler Jan 26 '11 at 11:13

I don't understand the question too well, but to find the parent of $PWD, do dirname $PWD. To find the parent of the parent, run dirname $(dirname $PWD), and so on...

share|improve this answer
    
That would only work if I knew the depth, otherwise I end up with /. Ok, I could check recursively, but isn't there something easier? –  Tobias Kienzler Jan 25 '11 at 15:41
    
@tob If only I knew shell programming ;-) –  Tshepang Jan 25 '11 at 16:06

Hm, it's pity that [ doesn't have an option of testing STRING1 starts with STRING2 condition.

You may try echo $PWD | grep '^$VAR', but it can fail in interesting ways when VAR contains special symbols.

awk's index function should be able to do the trick. But all this seems just too heavy for such an easy thing to test.

share|improve this answer

If the searched part of path is found I "empty" the variable :

[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
share|improve this answer

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.