11

I want to ask the user of my bash script to pass a directory path as argument. Which one of the following is a good programming practice?

  • Require that the user enter a trailing / (forward slash)
  • Require that a user doesn't enter a trailing / (forward slash)
3
  • 3
    Note that rsync behaves differently in a very important way depending on the presence of trailing /, and so in some cases you'd want to normalise for consistency, and in others you'd want to pass through cleanly to implement what the user said (if they knew they were talking to rsync).
    – sh1
    Jul 3, 2013 at 13:10
  • 1
    Another one that surprised me recently is that ls -l dir behaves differently to ls -l dir/ if dir is a symlink to a directory.
    – Flimm
    Dec 30, 2013 at 10:25

5 Answers 5

28

Best practice is to assume neither.

If you have access to path builder utilities/classes use those, if not write your code to accept either format and act accordingly.

Nothing's more annoying for the user than having to remember whether to add a trailing slash or not.

4
  • 6
    Corollary: Always parse paths with the suitable command-line tools - dirname, basename and readlink. A very common problem is using ${path##*/} as a replacement for basename, but if the path ends with a slash that returns an empty string instead of the last path element.
    – l0b0
    Jun 17, 2011 at 11:18
  • 1
    +1 for using utility classes. I can't say how many times I've seen developers re-invent the wheel when it comes to assembling paths, when most frameworks can do it easily nowadays. Jun 17, 2011 at 12:16
  • 1
    Also, I'm greatly annoyed when some application requires me to do this in a specific way. And sometimes the user can't control how to write that path: Sometimes they write it, so then yes, they choose to write with or without trailing slash, but in cases where the user autocompletes using TAB, many shells put the trailing slash, so you would require the user to delete it? And even more annoying is when an application behaves differently if you put the trailing slash in a directory passed as an argument (rsync I'm looking at you) Jun 17, 2011 at 14:16
  • I recently needed to verify a trailing slash from user input for use with rsync (as it is sensitive to these things). As @ChrisF noted, it is best practice to assume neither. I came up with the following as a graceful way of assuming neither: ${STR}$(printf \\$(printf '%03o' $(($(printf '%d' "'${STR:(-1)}")==47?0:47)))) I also documented it in a gist for clarity: add or remove trailing slash in bash Apr 5, 2016 at 14:18
10

Since bash ignores multiple slashes, you can safely assume that the user didn't enter a trailing slash in the path and add a slash yourself.

cat /etc/hosts

is the same like

cat /////etc//////////hosts

So your script could look like that:

echo -n "enter path: "
read path
if [ -f $path/myfile ]
then
  echo "found myfile!"
else
  echo "nope"
fi

and you don't have to worry whether or not the user enters a trailing / in the path.

1
  • 5
    Nit: That's not bash behavior, the kernel does it.
    – Blrfl
    Jun 17, 2011 at 13:15
7

The late Jon Postel had some great advice in section 3.2 of RFC 760 that applies here:

In general, an implementation should be conservative in its sending behavior, and liberal in its receiving behavior. That is, it should be careful to send well-formed datagrams, but should accept any datagram that it can interpret (e.g., not object to technical errors where the meaning is still clear).

3

Conceptually, the slash is not part of the name. The slash is only a delimiter between names. My home-dir is /home/stefan and not /home/stefan/.

If you don't expect a trailing slash, you will not fail if there is one, as ammoQ already noted. But you can easily glue together names and vars, because you don't have to quote the slash:

a="/home"
b="stefan"

dir=$a/$b
0

Requiring that the directory must not have a trailing slash would be extremely annoying for interactive use on the console: auto-completion with TAB automatically adds a trailing slash for directories.

So you certainly need to allow that directories are specified with trailing slash.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.