简体   繁体   English

python virtualenv 中的 sudo 权限

[英]sudo privileges within python virtualenv

Environment环境

  • Windows Subsystem for Linux with Serial Communication to a GPS. Windows Subsystem for Linux具有与 GPS 的串行通信。

  • Adafruit GPS connected to a Arduino Nano which is connected to COM10 . Adafruit GPS 连接到连接到COM10的 Arduino Nano。 In Windows Subsystem for Linux this is equivalent to /dev/ttyS10Windows Subsystem for Linux这相当于/dev/ttyS10

  • Requirements: pyserial要求: pyserial

I have written a simple script to read information from the GPS module:我写了一个简单的脚本来从 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()

In the virtualenv I chose Python3 and when I executed it I got Permission Error for the serial port /ttyS10 so I chose to sudo chmod 666 /dev/ttyS10 to use the script in the virtualenv .在 virtualenv 中,我选择了Python3 ,当我执行它时,串行端口/ttyS10出现Permission Error ,因此我选择sudo chmod 666 /dev/ttyS10以使用virtualenv的脚本。

However is there an alternative to the above mentioned chmod /dev/serial in order to avoid the PermissionErrors ?但是,是否有上述chmod /dev/serial的替代方法以避免PermissionErrors

I am aware that even in the virtualenv when one uses sudo the packages installed in the virtualenv are no considered and instead sudo looks for your global pip packages.我知道即使在virtualenv使用sudo ,也不会考虑安装在 virtualenv 中的软件包,而是 sudo 查找您的全局pip软件包。

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.当你激活一个 virtualenv(通过source venv/bin/activate或类似的)时,它基本上只是告诉你的 shell:“嘿,当你搜索一个命令时,在你查看其他任何地方之前先查看venv/bin ”,通过更新$PATH环境变量。 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.这样,当您运行像python这样的命令时,您的 shell 会在venv/bin而不是/usr/bin或其他任何地方看到并运行python 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.该 Python 副本配置为在venv/lib查找包而不是/usr/lib ,因此您可以使用 virtualenv 中的包而不是全局安装的包。

However, when you run a program with sudo , it ignores $PATH .但是,当您使用sudo运行程序时,它会忽略$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 iftop 1 , so that anyone could check what the network was being used for, but still nobody could run sudo rm -rf /* .因为在 *nix 的历史时期,设置 sudo 是很常见的,这样用户只能用它执行特定的命令,比如(比如) sudo iftop 1 ,这样任何人都可以检查网络的用途,但是仍然没有人可以运行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!如果 sudo 尊重用户的$PATH ,您可以将/bin/rm复制到~/bin/iftop ,将~/bin添加到您的$PATH ,然后运行sudo iftop - 但实际上您将以 root 身份运行rm

So, sudo ignores $PATH by default.因此,sudo 默认忽略$PATH 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 ).但是您仍然可以通过为 sudo 提供程序的完整路径来执行特定程序,因此您可以通过运行类似sudo ./venv/bin/python (假设您的 virtualenv 被称为venv东西)以 root 身份在您的 virtualenv 中执行 Python。 That will make you root while still having access to the packages in your virtualenv, like pyserial.这将使您成为 root 用户,同时仍然可以访问您的 virtualenv 中的包,例如 pyserial。

1 : I don't actually know of any command that would be set up like this, this is a bad example, sorry. 1 :我实际上不知道有任何命令可以这样设置,这是一个不好的例子,抱歉。

Also make sure you have created virtualenv without sudo command, since that may cause permissions issues on using virtual env without sudo later.还要确保您已经创建了没有 sudo 命令的 virtualenv,因为这可能会导致以后在没有 sudo 的情况下使用虚拟环境时出现权限问题。 If that's the case run the command below:如果是这种情况,请运行以下命令:

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

Than you can enable permissions for reading the /dev/ttyS10 for your user and run python script by that user.比您可以为您的用户启用读取/dev/ttyS10权限并由该用户运行 python 脚本。

NOTE : Also you want to add shebang line to to the top of your python script with the path to python interpreter which sits in your env.注意:您还想将 shebang 行添加到 python 脚本的顶部,其中包含位于 env 中的 python 解释器的路径。 So you will be able to call it without interpreter.所以你可以在没有解释器的情况下调用它。

#!/usr/bin/env python

See more on that SO Answer: Should I put #!查看更多关于 SO 答案: 我应该把 #! (shebang) in Python scripts, and what form should it take? (shebang) 在 Python 脚本中,它应该采用什么形式?

Here is my workaround on bash.这是我对 bash 的解决方法。 Put this in an executable file on your PATH (eg vesudo ):将其放在 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

The logic is simple: Escape input arguments, run a privileged subshell, source virtual environment and pass arguments to the subshell.逻辑很简单:转义输入参数,运行特权子shell,源虚拟环境并将参数传递给子shell。

Example usage:用法示例:

~/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

I put this script in a repo for convenience.为了方便起见,我把这个脚本放在了一个repo中。

Add alias in your linux machine:在你的 linux 机器中添加别名:

# ~/.bash_aliases

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

NOTE: make sure you have virtual env activated.注意:确保您已激活虚拟环境。

Run python script with spython command :)使用 spython 命令运行 python 脚本 :)

spython file.py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM