在命令前添加 "sudo" 使命令未知

Adding "sudo" before a command makes the command unknown

这是一个困扰我一段时间的 linux 问题。在我的工作 linux box (运行 RedHat) 中,我试图安装一些 Python 包。然而,一些有趣的事情正在发生,见下文:

  1. 这是我的 objective 和第一个命令

    pip install scrapylib
    
  2. 这会造成 'Permission Denied' 错误

    OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/site-packages/scrapylib'
    
  3. 我下意识的反应是把 "sudo" 放在完全相同的命令前面...

    sudo pip install scrapylib
    
  4. 即产生此异常,

    sudo: pip: command not found
    
  5. 为了解决这个问题,我输入

    sudo su - root
    
  6. 现在这个命令运行成功 100%

    pip2.7 install scrapylib
    
  7. 终于换回我了

    sudo su - uspowpow
    

谁能给我解释一下这个现象?我是一名刚毕业的大学毕业生,除了基本的 Linux 知识外什么都没有,如果有人能解释为什么将 "sudo" 放在有效命令前面会使它无效,我将非常感激(两者都用于修复和知识)。

发生这种情况的原因有多种。挑几个:

  • 您的命令可能不在 sudo 强制执行的 PATH 中。对于 /usr/local/bin 中的命令(您的 pip 似乎所在的位置),这是完全可能的。
  • 您的命令可能需要一个别名或 shell 函数才能生效(也许您有 pip 别名为 pip2.7?),或者可能是一个 shell 内置函数本身(尽管 pip 并非如此)。默认情况下 sudo 使用 execv* 系统调用家族的成员直接调​​用子级,没有 shell,因此 (1) shell 函数和别名不会在其下全部调用;和 (2) 即使您 使用 shell,那个 shell 也不会 运行 您当前用户的点文件(是非交互式 shell,如果给 运行 一个命令,它不会 运行 most 点文件)。

要知道实际原因是什么,首先要找出pip是什么命令。为此,运行:

$ type pip

如果您得到的答案是:

pip is /usr/local/bin/pip

...那么您应该查看 /etc/sudoers 中设置的 secure_path 值以确保它包含 /usr/local/bin,或者只是 运行 sudo /usr/local/bin/pip 回避问题。相比之下,如果你得到:

pip is aliased to `pip2.7'

...那么你知道问题是它是一个别名,你需要 运行 sudo pip2.7 (如果 PATH 不是 also一个问题)。