Когда вы активируете virtualenv (по source venv/bin/activate
или аналогичному), он в основном просто говорит вашей оболочке: «эй, когда вы ищете команду, посмотрите в venv/bin
, прежде чем искать в другом месте», обновив $PATH
переменная окружения. Таким образом, когда вы запускаете команду типа python
, ваша оболочка видит и запускает python
в venv/bin
вместо /usr/bin
или где-либо еще. Эта копия Python настроена на поиск в venv/lib
пакетов, а не /usr/lib
, так что вы можете использовать пакеты в вашем virtualenv вместо тех, которые установлены глобально.
Однако, когда вы запускаете программу с sudo
, она игнорирует $PATH
. Почему это так? Потому что в исторические времена * nix было обычным делом настраивать sudo, чтобы пользователи могли выполнять с ним только определенные команды, такие как (скажем) sudo iftop
1 , чтобы каждый мог проверить, что сеть использовалась, но все равно никто не мог запустить sudo rm -rf /*
. Если sudo уважает пользователя $PATH
, вы можете просто скопировать /bin/rm
в ~/bin/iftop
, добавить ~/bin
в $PATH
, а затем запустить sudo iftop
- но вы на самом деле запустите rm
от имени root!
Итак, sudo игнорирует $PATH
по умолчанию. Но вы все равно можете выполнять определенные программы, указав sudo полный путь к программе, поэтому вы можете запускать Python в вашем virtualenv от имени root, выполнив что-то вроде sudo ./venv/bin/python
(при условии, что ваша virtualenv называется venv
). Это сделает вас root'ом, при этом все еще имея доступ к пакетам в вашем virtualenv, например, pyserial.
1 : На самом деле я не знаю ни одной команды, которая была бы настроена подобным образом, это плохой пример, извините.