Łukasz Lew
Łukasz Lew

Reputation: 50298

How to properly make path handling robust in a bash program?

Questions are inline:

#!/bin/sh

# First arg should be Release or Debug    
# TODO test for that.

if test -n "$1"; then          # BTW how to test whether $1 is Debug or Release?
  BUILD_TYPE="$1"
else
  BUILD_TYPE="Release"
fi

# Set install prefix to current directory, unless second argument is given. 

if test -n "$2"; then
  INSTALL_PREFIX="$2"    # How to derelativize this path argument?
else
  INSTALL_PREFIX=bin     # How to make this path relative to script location?
fi

# Make build directory and do cmake, make, make install.

mkdir -p build/${BUILD_TYPE} && # How to make this path relative to script location?
cd build/${BUILD_TYPE} &&

cmake -D CMAKE_BUILD_TYPE=${BUILD_TYPE} \
      -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ # Possible relative to caller current directory. 
      ../../ &&             # Relative to scrip position.
make -j4 &&
make install

Is it a common problem or am I doing something in a non-standard way?

Upvotes: 1

Views: 1591

Answers (2)

Douglas Leeder
Douglas Leeder

Reputation: 53320

1)

test $1 == "Debug"

2) Put

SCRIPT_DIR="$(dirname $0)"
ORIGINAL_DIR="$(pwd)"

at the top of the script (first non-comment line after #! line)

To make a variable absolute relative to the script:

[ "${VAR/#\//}" != "$VAR" ] || VAR="$SCRIPT_DIR/$VAR"

To make it relative to the starting directory:

[ "${VAR/#\//}" != "$VAR" ] || VAR="$ORIGINAL_DIR/$VAR"

Basically we replace a leading slash with empty "${VAR/#\//}" and compare with "$VAR", if they are different then $VAR is absolute. Otherwise we prepend a directory that we want to make it absolute.

Upvotes: 1

Bombe
Bombe

Reputation: 83869

In addition to what Douglas Leeder said, I’d recommend to always surround your variables in double quotes to prevent paths with space characters messing up your script.

Upvotes: 1

Related Questions