2

I installed a utility on a server recently and discovered that it wasn't available when running from sudo. That is, foo executed as expected buy sudo foo resulted in sudo: foo: command not found.

I traced this back to the command being linked from /usr/local/bin and sudo using a PATH that only had /usr/bin. I modified the setup script to install the /usr/bin instead and everything is happy.

I would like to change my server setup script to detect this case and report an error if something changes and the command is not available for any reason in the future. I'm working from this StackOverflow question and its answers that suggest to use a test like this:

command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }

However, this does not behave as expected for sudo.

$ command -v foo
/usr/bin/foo
$ sudo command -v foo
sudo: command: command not found
$ sudo type foo
sudo: type: command not found
$ sudo hash -v foo
sudo: hash: command not found
$ sudo foo
   ...executes normally...
$ sudo bash
# command -v foo
/usr/bin/foo
# sudo command -v foo
sudo: command: command not found
# foo
   ...executes normally...
# sudo foo
   ...executes normally...

Curiously sudo which foo finds the command in /usr/bin/; when I run sudo which bar, it tells me which: no foo in (/sbin:/bin:/usr/sbin:/usr/bin), implying that the path for sudo does contain /usr/bin when launching subcommands.

What is going on?
What test can I run to determine whether a command is available to be invoked with sudo without invoking the command? (Also, without invoking which, as several comments and answers in the linked question warn against; otherwise I'd be fine with that...)

1
  • That works! If you can turn that into an answer and explain or link to how sudo works (or in this case, doesn't) with shell builtins, I will upvote and accept. – Patrick M Mar 2 '18 at 21:40
3

sudo is used to execute a binary, so shell builtins aren't available unless a shell is executed. bash -c tells bash to interpret the next argument, so sudo bash -c "command -V <exe>" tells sudo to execute bash which interprets the string command -V <exe> and invokes the proper builtin.

1
  • That makes more sense, but how is the command builtin getting executed by sudo, if not in a shell? – Patrick M Mar 2 '18 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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