0

I used to work with another, more experienced programmer who would put almost ALL of the utility calls within a shell script in the following manner:

FOO=`which foo`

$FOO -bar

After working with the guy for over a year, I knew pretty well that he was not the type to do these things on a whim, but I never really paid attention until he quit and i had to start maintaining his code. My only assumption is that, being an OpenBSD proponent and VERY security minded, it might have something to do with permissions or being able to test whether the user running the script had permissions? To counter this, however, I don't recall him ever testing against the success of setting those variables.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
Mange
  • 5
  • 2
  • As much respect as you may have for your coworker -- this is considered bad practice (in freenode's #bash; I can't speak for other forums), and is generally ill-advised. – Charles Duffy Mar 31 '14 at 22:22
  • 1
    In most of the cases I've seen that done, it was in the name of efficiency, and done by people who didn't realize that modern shells cache PATH lookups automatically, making it entirely unnecessary. – Charles Duffy Mar 31 '14 at 22:26
  • I actually had a feeling this might be the case. Respect perhaps, but I also realize he did a LOT of things in the name of "security" that were bad practices on the face of it. I just was curious if there was a strong benefit to doing this, like making sure a utility required by the script but not always in the default PATH wouldn't cause an issue with compatibility. Thank you both, Glenn and Charles, for the explanation. I'll have to start hanging out in #bash. – Mange Apr 03 '14 at 13:45
  • 1
    This also occurs as a result of cargo-cult programming and people copying the style out of autogenerated scripts (like the configure script that is generated by autoconf) – William Pursell Apr 03 '14 at 13:57
  • @WilliamPursell: yeah, I see a LOT of that in every job I go to. You look up how to fix something, and find a blogpost about the package you're working in, with the code example copied VERBATIM. The only thing I've found to counter it is forcing myself to work from scratch as much as project timelines allow me to. – Mange Apr 04 '14 at 20:07

2 Answers2

1

Using 'which' this way is pretty much a no-op, but it makes it much easier to maintain the code if you want to specify a utility. For example, if you find yourself running somewhere that has two installed FOO tools, and one is known be be problematic, you can hard code the correct FOO in the script and users who may have their PATH set to use the broken FOO will not be harmed (or call an insecure FOO). By assigning the value early, assigning a specific value is localized to one change rather than spreading to every instance in the script.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • If you wanted to replace the utility later without changing the code that calls it (a code smell on its own), the Right Thing would be a function wrapper, not an unquoted `$FOO` invocation. – Charles Duffy Mar 31 '14 at 22:23
  • @charles, I agree. I find the practice of specifying tools like this quite horrific, but it's very common. I think your comment about PATH cacheing is probably more accurate than my answer. – William Pursell Mar 31 '14 at 22:28
  • This is similar to what I was thinking was his reasoning. I'll have to read up more on writing wrappers in shell so I'm doing it in a more proper way. – Mange Apr 03 '14 at 13:49
  • @Mange, so, let's say you wanted to wrap `ls` to always pass `-l` as its first argument: `ls() { command ls -l "$@"; }` would be an appropriate wrapper. Unlike aliases, functions can also do conditional logic, pass additional command-line arguments in other-than-final position, aren't disabled by default in scripts, &c. – Charles Duffy Apr 03 '14 at 14:42
  • Yeah, I read a bit of a refresher on it yesterday during work. I'm guilty of not always using the best methodology, so I'm trying to force myself to improve. – Mange Apr 04 '14 at 20:01
1

I would say that code significantly reduces, maybe not security, but correctness. Suppose you expect to find foo in the path as /usr/bin/foo, and that utility is supposed to parse some file and emit some text. So you release the script into production. Then some user happens to have a $HOME/bin/foo script that, say, launches a music app, and this user has put ~/bin before /usr/bin in his PATH. Now, for that user, your script is broken.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Well -- `$PATH` is going to be respected in any case where a fully-qualified path isn't given, whether or not `which` is being used, and that's generally desired behavior -- it puts the user in control, allows them to add their own wrappers, etc. – Charles Duffy Mar 31 '14 at 22:24