我读取了this,但无法解决问题。我不知道如何使用setuid
我有一个小的python应用程序,在linux机器上运行python命令和bash命令。我只希望下面这部分以普通用户身份运行。应用程序以sudo python3 app.py
运行,因为做一些需要sudo权限的命令。我只上传我想以普通用户身份运行的部分。
我怎么能那样做呢?
import alsaaudio
m = alsaaudio.Mixer('Capture')
m.setvolume(10) # set volume
vol = m.getvolume() # get volume float value
1条答案
按热度按时间moiiocjp1#
一个人不能简单地随意来回改变一个进程的所有者(好吧,一个人可以用适当的称呼:
os.seteuid
,我在开始回答这个问题后才知道。无论哪种方式,这个特定的问题需要做的事情比设置UID更多-答案的底部有一个子进程方法):只有root用户可以执行此操作,并且一旦完成此操作,就不再是root用户可以切换回来。因此,技巧是在一个独占运行有限任务的进程中调用它。您可以派生进程并在子进程上调用
os.setuid
,然后终止它:当然,这不会使
vol
变量在父进程上可用--您必须设置一种方法来沿着该值。在这种情况下,可以使用Python多处理,而不是fork,通过多处理队列发送
vol
值,并添加所需的暂停来破坏其他用户进程:如果你正在写“生产质量”的代码,而这些代码需要在第三方计算机上处理大量的极端情况,那么这是很好的。2如果你的对象是一个简单的脚本,用于在你的机器中设置一些东西,那么将值写入一个文件,并在父文件中阅读它将更容易:根据OP注解,这不仅仅是更改有效UID的问题,还包括环境变量,以及重新导入
alsaaudio
模块-“fork”不会将其删除(因为env变量没有更改,并且在Python端更改os.environment
条目可能不会在alsalib初始化时反映在alsalib的本地代码端)。在这种情况下,使用
subprocess.Popen
运行进程,并确保在它之前的环境正确,可以达到预期的效果。进程间通信可以通过捕获子进程stdout来解决--这样我们就可以避免pickle。另外,默认的子进程调用是同步的,不需要为目标子进程设置任意的暂停来初始化alsa并选择它的值:在默认调用中,主进程将在子进程完成后继续。我并不是在这里尝试alsaaudio,这可能是因为在子进程上需要比我设置的2个环境变量更多的环境变量,如果是这样的话,就继续根据需要将then添加到代码的
env={ ...}
部分。这个示例只是按照您的要求执行操作,并将“vol”的值传递回来--如果您需要更多的数据,请将“encoding”参数放到子进程中,并将任意数据pickle到子进程上的
sys.stdout
中--然后您可以使用pickle检索它。