Check If Shell Script $1 Is Absolute Or Relative Path

<>

This question already has an answer here:

Answers


[ ... ] doesn't do pattern matching. /* is being expanded to the contents of /, so effectively you have

if [ "$DIR" = /bin /boot /dev /etc /home /lib /media ... /usr /var ]

or something similar. Use [[ ... ]] instead.

if [[ "$DIR" = /* ]]; then

For POSIX compliance, or if you just don't have a [[ that does pattern matching, use a case statement.

case $DIR in
  /*) echo "absolute path" ;;
  *) echo "something else" ;;
esac

Just test on the first character:

if [ "${DIR:0:1}" = "/" ]

Writing tests is fun:

#!/bin/bash

declare -a MY_ARRAY # declare an indexed array variable

MY_ARRAY[0]="/a/b"
MY_ARRAY[1]="a/b"
MY_ARRAY[2]="/a a/b"
MY_ARRAY[3]="a a/b"
MY_ARRAY[4]="/*"


# Note that 
# 1) quotes around MY_PATH in the [[ ]] test are not needed
# 2) the expanded array expression "${MY_ARRAY[@]}" does need the quotes
#    otherwise paths containing spaces will fall apart into separate elements.
# Nasty, nasty syntax.

echo "Test with == /* (correct, regular expression match according to the Pattern Matching section of the bash man page)"

for MY_PATH in "${MY_ARRAY[@]}"; do
   # This works
   if [[ $MY_PATH == /* ]]; then
      echo "'$MY_PATH' is absolute"
   else
      echo "'$MY_PATH' is relative"
   fi
done

echo "Test with == \"/*\" (wrong, becomes string comparison)"

for MY_PATH in "${MY_ARRAY[@]}"; do
   # This does not work at all; comparison with the string "/*" occurs!
   if [[ $MY_PATH == "/*" ]]; then
      echo "'$MY_PATH' is absolute"
   else
      echo "'$MY_PATH' is relative"
   fi
done

echo "Test with = /* (also correct, same as ==)"

for MY_PATH in "${MY_ARRAY[@]}"; do
   if [[ $MY_PATH = /* ]]; then
      echo "'$MY_PATH' is absolute"
   else
      echo "'$MY_PATH' is relative"
   fi
done

echo "Test with =~ /.* (pattern matching according to the regex(7) page)"

# Again, do not quote the regex; '^/' would do too

for MY_PATH in "${MY_ARRAY[@]}"; do
   if [[ $MY_PATH =~ ^/[:print:]* ]]; then
      echo "'$MY_PATH' is absolute"
   else
      echo "'$MY_PATH' is relative"
   fi
done

ShellCheck automatically points out that "[ .. ] can't match globs. Use [[ .. ]] or grep."

In other words, use

if [[ "$DIR" = /* ]]

This is because [ is a regular command, so /* is expanded by the shell beforehand, turning it into

[ "$DIR" = /bin /dev /etc /home .. ]

[[ is handled specially by the shell, and doesn't have this problem.


One more case is paths started from ~ (tilde). ~user/some.file or ~/some.file are some kind of absolute paths.

if [[ "${dir:0:1}" == / || "${dir:0:2}" == ~[/a-z] ]]
then
    echo "Absolute"
else
    echo "Relative"
fi

Need Your Help

Html.BeginForm() with an absolute URL?

html asp.net-mvc forms

I need to have the POST action be to an absolute URL (e.g., http://www.cnn.com). Is there a way to use Html.BeginForm() helper and pass it the url?