8

I see this all the time at my place of work:

#!/bin/sh

.....

CAT=/usr/bin/cat                                  # An alias for cat
MAIL=/usr/bin/mail                                # An alias for mail
WC=/usr/bin/wc                                    # An alias for word count
GREP=/usr/bin/grep                                # An alias for grep
DIRNAME=/usr/bin/dirname                          # An alias for dirname
RM=/usr/bin/rm                                    # An alias for rm
MV=/usr/bin/mv                                    # An alias for mv

.....

Is it just my company that does this? Is there a reason why you would want to spell out where these extremely common commands are? Why would I want $CAT to refer to /usr/bin/cat when cat already refers to /usr/bin/cat? Am I missing something? It seems like its needlessly redundant.

4 Answers 4

12

Using the full pathname ensures that the script operates correctly even if it's run by a user who customizes their PATH environment variable so that it finds different versions of these commands than the script expects.

Using variables simplifies writing the script, so you don't have to write the full pathname of a command each time it appears in the script.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I knew there must be some reason behind this.
4

Is it just my company that does this?

No.

Is there a reason why you would want to spell out where these extremely common commands are?

Yes.

Why would I want $CAT to refer to /usr/bin/cat when cat already refers to /usr/bin/cat?

Are you sure cat always refers to /usr/bin/cat? What if your script happens to be run in an environment where there is a different cat earlier in the path? Or where there is simply a user-controlled directory earlier in the path, where a user could install a rogue cat command? If your script ever happens to be run with elevated privileges, then do you really want to give random users the ability to do anything they want to your system?

Are you sure cat is supposed always to refer to /usr/bin/cat? If ever the script were installed in an environment where a different cat were needed (say /usr/local/bin/gnucat), then would you prefer to modify one line or twenty?

Am I missing something? It seems like its needlessly redundant.

Yes, you are missing something.

One would like to avoid writing out /usr/bin/cat everywhere they want to run cat, and one would like to be able to choose a different cat where needed (or more likely a different make or grep or sed). On the other hand, one wants to avoid potentially unsafe external influence on the behavior of a trusted script. Defining the full path to the command in a shell variable and then using that variable to run the command accomplishes these objectives.

2 Comments

The most common event in my use is running scripts via cron jobs, where the PATH is not the same as it is for me as USER, or root. Hard coding paths eliminates this problem. John is absolutely right, you cannot count on the path you assume to exist existing, so it's a good practice to code it, or, as another answer has, to set the PATH, but that's not as obvious in terms of reading the code down the road. Setting the paths like this also lets you use alternate paths for the tool depending on the environment, ie, in BSD or GNU/Linux.
You're correct about PATH, but aliases are irrelevant. Aliases aren't inherited, and they're not expanded in scripts unless the script specifically enables them.
3

One way to avoid this and still have the safety of ignoring the user's environment is to explicitly spell out the variables in the script

#!/bin/sh

PATH=/bin:/usr/bin   # maybe you need something in /usr/sbin, add that
LC_ALL=C             # ignore the user's locale
LD_LIBRARY_PATH=something # or unset it if you want nothing

# then
cat /a/file          # have confidence you're using /bin/cat

There may well be others: check the man pages of the programs you use in your code.

1 Comment

Probably not a realistic concern, but the custom path doesn't accommodate using, for example, /usr/bin/cat instead of /bin/cat.
2

Welcome to the enterprise where nothing is taken for granted.

These are commonly defined to ensure correct version, or to enforce env setup across many boxes.

https://github.com/torvalds/linux/blob/master/tools/scripts/Makefile.include#L15

This way you can check if dir exist.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.