To remove a trailing slash if there is one, you can use the suffix removal parameter expansion construct present in all POSIX-style shells:
x=${x%/}
There are a few complications. This only removes a single slash, so if you started with a/b/c//
then you'll still end up with a slash. Furthermore, if the original path was /
, you need to keep the slash. Here's a more complex solution that takes care of these cases:
case $x in
*[!/]*/) x=${x%"${x##*[!/]}"};;
*[/]) x="/";;
esac
Alternatively, in ksh, or in bash after shopt -s extglob
:
[[ x = *[!/] ]] || x=${x%%*(/)}
Note that in many cases, it doesn't matter that there is a trailing slash. It does matter if the argument is a symbolic link to a directory: with a trailing slash, the argument designates the directory, whereas with no trailing slash, the argument designates the symbolic link itself. It also matters with a few other programs, for example the source argument of rsync
is treated differently depending on the presence of a trailing slash.
/
. – muru Apr 23 '15 at 01:40rsync
. – Gilles 'SO- stop being evil' Apr 24 '15 at 04:55a/////b/c
ora/../a/.././//a/b/c////
. The best solution is usuallycd
-{ cd -- "$1" && cd - || exit; } >/dev/null"
which will handle all of that correctly, automatically print a properly formatted diag for error and put a full path in$OLDPWD
. Usecd -P
to automatically canonicalize symlinks in your argument to absolute paths. And strip$PWD
from the head of$OLDPWD
for relative paths likedir=${OLDPWD#"$PWD"/}; [ -n "${dir##/*}" ] || ! echo not relative\!
– mikeserv Apr 24 '15 at 05:28