python virtualenv中的sudo权限

时间:2018-05-14 17:12:50

标签: python python-3.x virtualenv

环境

  • Windows Subsystem for Linux与GPS进行串行通信。

  • Adafruit GPS连接到与COM10连接的Arduino Nano。在Windows Subsystem for Linux中,这相当于/dev/ttyS10

  • 要求:pyserial

我写了一个简单的脚本来从GPS模块中读取信息:

import serial

def select_sentence():
""" This function sends serial data to the GPS module to display only GPGGA and GPRMC"""

def read_gps():
    ser = serial.Serial("/dev/ttyS10", 9600)
    while True:
         print(ser.readline().decode('utf-8'))

if __name__ == "__main__":
     select_sentence()
     read_gps()

在virtualenv中我选择了Python3,当我执行它时,我得到了Permission Error的串口/ttyS10所以我选择了sudo chmod 666 /dev/ttyS10来使用virtualenv中的脚本{1}}。

但为了避免chmod /dev/serial

可以替代上面提到的PermissionErrors

我知道即使在virtualenv使用sudo时,也不会考虑virtualenv中安装的软件包,而是sudo会查找您的全局pip软件包。

4 个答案:

答案 0 :(得分:2)

When you activate a virtualenv (by source venv/bin/activate or similar), that basically just tells your shell: "hey, when you search for a command, look in venv/bin before you look anywhere else", by updating the $PATH environment variable. That way, when you run a command like python, your shell sees and runs the python in venv/bin instead of in /usr/bin or wherever. That copy of Python is configured to look in venv/lib for packages rather than /usr/lib, so you can use the packages in your virtualenv instead of the ones installed globally.

However, when you run a program with sudo, it ignores $PATH. Why does it do that? Because in the historical days of *nix, it was common to have sudo set up so that users could execute only specific commands with it, like (say) sudo iftop1, so that anyone could check what the network was being used for, but still nobody could run sudo rm -rf /*. If sudo respected the user's $PATH, you could just copy /bin/rm to ~/bin/iftop, add ~/bin to your $PATH, then run sudo iftop – but you would actually be running rm as root!

So, sudo ignores $PATH by default. But you can still execute specific programs by giving sudo the full path to the program, so you can execute the Python in your virtualenv as root by running something like sudo ./venv/bin/python (assuming your virtualenv is called venv). That will make you root while still having access to the packages in your virtualenv, like pyserial.

1: I don't actually know of any command that would be set up like this, this is a bad example, sorry.

答案 1 :(得分:0)

另外请确保您在没有sudo命令的情况下创建了virtualenv,因为这可能会导致在以后使用虚拟环境而不使用sudo时出现权限问题。如果是这种情况,请运行以下命令:

sudo chown -R your_username:your_username path/to/virtuaelenv/

您可以为您的用户启用读取/dev/ttyS10的权限,并为该用户运行python脚本。

注意:您还想将shebang行添加到python脚本的顶部,其中包含位于env中的python interpreter的路径。所以你可以在没有翻译的情况下调用它。

#!/path/to/venv/bin python3

详情请参阅答案:Should I put #! (shebang) in Python scripts, and what form should it take?

答案 2 :(得分:0)

这是我对bash的解决方法。将其放在您PATH上的可执行文件中(例如vesudo):

#!/bin/bash

if [ -z "$VIRTUAL_ENV" ]; then
  echo "Error: Virtual environment not found" >&2
  exit 1
fi

_args=''
for _a in "$@"; do
  _a="${_a//\\/\\\\}"
  _args="$_args \"${_a//\"/\\\"}\""
done

sudo bash <<_EOF
source "$VIRTUAL_ENV/bin/activate"
$_args
_EOF

逻辑很简单:转义输入参数,运行特权子shell,源虚拟环境,然后将参数传递给子shell。

用法示例:

~/tmp$ source .venv/bin/activate
(.venv) ~/tmp$ which python
/home/omer/tmp/.venv/bin/python
(.venv) ~/tmp$ vesudo which python
/home/omer/tmp/.venv/bin/python
(.venv) ~/tmp$ which pip
/home/omer/tmp/.venv/bin/pip
(.venv) ~/tmp$ vesudo which pip
/home/omer/tmp/.venv/bin/pip
(.venv) ~/tmp$ vesudo python -c 'import sys; print(sys.argv)' it works 'with spaced arguments' as well
['-c', 'it', 'works', 'with spaced arguments', 'as', 'well']
(.venv) ~/tmp$ vesudo echo '$HOME'
/root

为方便起见,我将此脚本放在repo中。

答案 3 :(得分:0)

在你的 linux 机器上添加别名:

# ~/.bash_aliases

alias spython='sudo $(printenv VIRTUAL_ENV)/bin/python3'

注意:确保您已激活虚拟环境。

使用 spython 命令运行 python 脚本 :)

spython file.py