Skip to content

Instantly share code, notes, and snippets.

@grosscol
Last active July 31, 2019 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grosscol/246a4d641c94650051ee88bf3b11332b to your computer and use it in GitHub Desktop.
Save grosscol/246a4d641c94650051ee88bf3b11332b to your computer and use it in GitHub Desktop.
Hacking at alternatives for symbolic link resolution that work across OSX, BSD, and GNU.
#!/bin/bash
# Consider the following structure where this script is target.sh
# /tmp/
# ├── target.sh
# └── l1
#    ├── one.sh -> ../target.sh
#    └── l2
# └── two.sh -> ../one.sh
# From your home directory run:
# /tmp/target.sh
# /tmp/l1/one.sh
# /tmp/l1/l2/two.sh
######################
### Showing State ###
######################
MYDIR=$(pwd)
DNAME=$(dirname $0)
CDPWD=$(cd ${DNAME} ; pwd -P)
echo "-----"
echo "pwd is the directory from which the command is run."
echo "pwd: ${MYDIR}"
echo "-----"
echo "Dirname of script prints directory symlink sits in."
echo "dirname: ${DNAME}"
echo "-----"
echo "Using cd and pwd -P on the dirname of the symlink still resolves to symlink dir."
echo "cd and pwd: ${CDPWD}"
#######################
### Testing LS LOOP ###
#######################
THIS_SCRIPT="$0"
export FUSEKI_HOME="${FUSEKI_HOME:-$PWD}"
# Handle resolving symlinks to this script on BSD or GNU systems by avoiding readlink.
while [ -h "$THIS_SCRIPT" ] ; do
ls=`ls -ld "$THIS_SCRIPT"`
# Drop everything prior to ->
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
THIS_SCRIPT="$link"
else
THIS_SCRIPT=`dirname "$THIS_SCRIPT"`/"$link"
fi
done
# Get path to the scripts directory.
LS_LOOP=$(dirname "${THIS_SCRIPT}")
#############################
### Testing Readlink LOOP ###
#############################
echo "-----"
echo "The ls loop resolves any number of links."
echo "ls loop: ${LS_LOOP}"
MY_FILE="$0"
while [ -h "$MY_FILE" ] ; do
READ_LINK=$(readlink ${MY_FILE})
RL_DIR=$(dirname $READ_LINK)
RL_FILE=$(basename $READ_LINK)
ACT_DIR=$(cd $RL_DIR; pwd -P) # This fails because $RL_DIR isn't absolute
MY_FILE=${ACT_DIR}/${RL_FILE}
done
RL_LOOP=$(dirname ${MY_FILE})
echo "-----"
echo "Looping readlink with cd and pwd -P"
echo "readlink loop: ${RL_LOOP}"
@grosscol
Copy link
Author

grosscol commented Jul 31, 2019

The following is the result of running this on Ubuntu 18.04

∫ home/grosscol ⮞ /tmp/l1/l2/two.sh 
-----
pwd is the directory from which the command is run.
pwd: /home/grosscol
-----
Dirname of script prints directory symlink sits in.
dirname: /tmp/l1/l2
-----
Using cd and pwd -P on the dirname of the symlink still resolves to symlink dir.
cd and pwd: /tmp/l1/l2
-----
The ls loop resolves any number of links.
ls loop: /tmp/l1/l2/../..
-----
Looping readlink with cd and pwd -P
readlink loop: /home

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment