Search code examples
bashcentos6

sudo: command: command not found on CentOS 6


MVCE:

on bash 4.1.2, Centos 6.10 (because we're monsters).

sudo command vim

returns

sudo: command: command not found

I don't understand why. on bash 4.4.23, Mac OS High Sierra it works as expected. It is very difficult to google this as people use "command" as a placeholder for various commands they are talking about.

Actual problem:

I have a function (seen below) named vim, taking the command out from its calls to vim doesn't cause it to fail, like I'd expect, on both bash 4.4 and 4.1.

I have a function to automatically sudo vim if I can't write to file:

vim() {
    #only good for auto-sudo. delete if no sudo privileges.
    if [[ "$#" -ne 1 ]]; then
        command vim "$@"
    #cases: if we can write to the file, or the file doesn't exist but we can make new files in that dir
    elif [[ -w "$1" || ( -w $(dirname "$1") && ! -f "$1" ) ]]; then
        # \vim or 'vim' only escape aliases, not functions
        command vim "$1"
    else
        #this 'command' isn't required! It won't loop forever without it.
        sudo env HOME="$HOME" command vim -u $HOME/.vim/vimrc "$1"
    fi
}

I expect command to be required, since otherwise vim should refer to the function I made and call itself ad infinitum. However, not only is it not required, on both the CentOS and Mac systems, but also it causes the function to fail on the CentOS box!

Can anyone explain this behavior?

Is there a convenient bash changelog I can look at to know if "command" somehow wasn't implemented until after bash 4.1?


Solution

  • sudo expects an executable; command is (usually) a shell built-in, not an executable, that modifies how the shell performs its lookup. sudo vim would work fine, because sudo can't run a shell function or use an alias named vim that shadows the executable that command vim would give you.

    macOS actually does provide a shell script /usr/bin/command which (as far as I can tell) appears to simulate the shell built-in while compensating for the case-insensitivity that HFS+ defaults to. The built-in command will shadow it in bash, but it would be available from other shells (or from commands that run other commands, like sudo).


    POSIX requires that command be implemented, though not necessarily as a shell built-in. Providing a shell with command as a built-in is probably sufficient for the OS. (The POSIX spec states "The command utility is most likely to be provided as a regular built-in.", and proceeds to list some reasons why command isn't listed among the other commands that must be built-ins.)