<p>当您激活一个virtualenv(通过<code>source venv/bin/activate</code>或类似的方法)时,它基本上只是告诉您的shell:“嘿,当您搜索命令时,请先在<code>venv/bin</code>中查找,然后再查找其他地方”,方法是更新<code>$PATH</code>环境变量。这样,当您运行一个类似<code>python</code>的命令时,shell会在<code>venv/bin</code>中看到并运行<code>python</code>,而不是在<code>/usr/bin</code>或任何地方。Python的副本被配置为在<code>venv/lib</code>中查找包,而不是<code>/usr/lib</code>,因此您可以使用virtualenv中的包,而不是全局安装的包。在</p>
<p>但是,当您使用<code>sudo</code>运行程序时,它是<a href="https://unix.stackexchange.com/q/83191/226269"><em>ignores</em></a><code>$PATH</code>。为什么会这样?因为在*nix的历史时期,设置sudo是很常见的,这样用户就可以使用它执行特定的命令,比如(比如)<code>sudo iftop</code><sup>1</sup>,这样任何人都可以检查网络的用途,但是仍然没有人可以运行<code>sudo rm -rf /*</code>。如果sudo尊重用户的<code>$PATH</code>,那么您只需将<code>/bin/rm</code>复制到<code>~/bin/iftop</code>,将<code>~/bin</code>添加到<code>$PATH</code>,然后运行<code>sudo iftop</code>,但实际上你是以根用户身份运行<code>rm</code>!在</p>
<p>因此,sudo默认忽略<code>$PATH</code>。但是您仍然可以通过给sudo提供程序的完整路径来执行特定的程序,因此您可以在virtualenv中通过运行类似<code>sudo ./venv/bin/python</code>(假设您的virtualenv名为<code>venv</code>)的根来执行Python。这将使您在仍然可以访问virtualenv中的包(如pyserial)的情况下根目录。在</p>
<p><sup>1</sup>:我实际上不知道有什么命令会这样设置,这是一个很糟糕的例子,对不起。在</p>