Skip to content

Instantly share code, notes, and snippets.

@gvlx
Forked from tvlooy/unit.sh
Last active October 5, 2018 05:47
Show Gist options
  • Select an option

  • Save gvlx/0adfb1137937ad443df2eeaa73dc0ba7 to your computer and use it in GitHub Desktop.

Select an option

Save gvlx/0adfb1137937ad443df2eeaa73dc0ba7 to your computer and use it in GitHub Desktop.
Bash test: get the directory of a script
#!/bin/bash
function test(){
local MESSAGE="$1"
local RECEIVED="$2"
local EXPECTED="$3"
if [ "$RECEIVED" = "$EXPECTED" ]; then
# shellcheck disable=SC1117
echo -e "\033[32m✔ Tested $MESSAGE"
else
# shellcheck disable=SC1117
echo -e "\033[31m✘ Tested $MESSAGE"
echo -e " Received: $RECEIVED"
echo -e " Expected: $EXPECTED"
fi
# shellcheck disable=SC1117
echo -en "\033[0m"
}
function testSuite(){
test 'absolute call' "$(bash /tmp/1234/test.sh)" /tmp/1234
test 'via symlinked dir' "$(bash /tmp/current/test.sh)" /tmp/1234
test 'via symlinked file' "$(bash /tmp/test.sh)" /tmp/1234
test 'via multiple symlinked dirs' "$(bash /tmp/current/loop/test.sh)" /tmp/1234
pushd /tmp >/dev/null || exit 1
test 'relative call' "$(bash 1234/test.sh)" /tmp/1234
popd >/dev/null || exit 1
test 'with space in dir' "$(bash /tmp/12\ 34/test.sh)" /tmp/1234
test 'with space in file' "$(bash /tmp/1234/te\ st.sh)" /tmp/1234
echo
}
function teardown(){
# remove symlinks before files
local DIR="/tmp/1234";
local FILE="test.sh";
local DIR2="/tmp/12 34";
local FILE2="te st.sh";
[[ -e "${DIR2}" ]] && rm -rf "${DIR2:?}";
[[ -e "${DIR}/${FILE2}" ]] && rm -f "${DIR:?}/${FILE2}";
[[ -e "${DIR2}/${FILE}" ]] && rm -f "${DIR2:?}/${FILE}";
[[ -e "${DIR2}/${FILE2}" ]] && rm -f "${DIR2:?}/${FILE2}";
[[ -e /tmp/"${FILE}" ]] && rm -f "/tmp/${FILE}";
[[ -e /tmp/current ]] && rm -rf /tmp/current;
[[ -e /tmp/current/loop ]] && rm -rf /tmp/current/loop;
[[ -e "${DIR}" ]] && rm -rf "${DIR:?}";
[[ -e "${DIR}/${FILE}" ]] && rm -f "${DIR:?}/${FILE}";
}
function setup(){
local DIR=/tmp/1234
local FILE=test.sh
local DIR2="/tmp/12 34"
local FILE2="te st.sh"
mkdir "${DIR}"
touch "${DIR}/${FILE}"
ln -s "${DIR}/${FILE}" /tmp
ln -s "${DIR}" /tmp/current
ln -s "${DIR}" /tmp/current/loop
mkdir "${DIR2}"
ln -s "${DIR}/${FILE}" "${DIR}/${FILE2}"
ln -s "${DIR}/${FILE}" "${DIR2}/${FILE}"
ln -s "${DIR}/${FILE}" "${DIR2}/${FILE2}"
}
function test1(){
echo 'Test 1: via dirname'
cat <<- EOF >/tmp/1234/test.sh
echo \`dirname \$0\`
EOF
testSuite
}
function test2(){
echo 'Test 2: via pwd'
cat <<- EOF >/tmp/1234/test.sh
echo \$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )
EOF
testSuite
}
function test3(){
echo 'Test 3: overcomplicated stackoverflow solution'
cat <<- EOF >/tmp/1234/test.sh
SOURCE="\${BASH_SOURCE[0]}"
while [ -h "\$SOURCE" ]; do
DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )"
SOURCE="\$(readlink "\$SOURCE" 2> /dev/null)"
[[ \$SOURCE != /* ]] && SOURCE="\$DIR/\$SOURCE"
done
DIR="\$( cd -P "\$( dirname "\$SOURCE" )" && pwd )"
echo \$DIR
EOF
testSuite
}
function test4(){
echo 'Test 4: via readlink'
cat <<- EOF >/tmp/1234/test.sh
echo \`dirname \$(readlink -f \$0 2> /dev/null)\`
EOF
testSuite
}
function test5(){
echo 'Test 5: via readlink with space'
cat <<- EOF >/tmp/1234/test.sh
echo \`dirname \$(readlink -f "\$0" 2> /dev/null)\`
EOF
testSuite
}
function test6(){
echo 'Test 6: as Test 2 but with cd -P';
cat <<- EOF >/tmp/1234/test.sh
echo \$( cd -P "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )
EOF
testSuite
}
function test7(){
echo 'Test 7: via cd -P and pwd, testing for symlinked file first';
cat <<- EOF >/tmp/1234/test.sh
__SOURCE__="\${BASH_SOURCE[0]}"
while [[ -h "\${__SOURCE__}" ]]; do
# shellcheck disable=SC1117
__SOURCE__=\$(find "\${__SOURCE__}" -type l -ls | sed -n 's/^.* -> \(.*\)/\1/p');
done;
echo \$(cd -P "\$( dirname "\${__SOURCE__}" )" && pwd)
EOF
testSuite
}
echo;
teardown; # sanity check (in case last run was interrupted)
setup;
if [ "$1" != "" ]; then
$1;
else
test1
test2
test3
test4
test5
test6
test7
fi
teardown;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment