我知道我可以运行此命令来生成后台进程并获取PID:
PID=`$SCRIPT > /dev/null 2>&1 & echo $!`
并在不同的用户下运行命令:
su - $USER -c "$COMMAND"
我不希望脚本以root身份运行,我无法弄清楚如何将两者结合起来并获得生成进程的PID。
谢谢!
答案 0 :(得分:1)
我想你想要runuser
命令。一般语法:
runuser -l userNameHere -c 'command'
我怀疑如果你将$ SCRIPT变量设置为上面的(通过适当的更改),你的第一个命令就会做你想要的。
答案 1 :(得分:0)
详细说明:请参阅以下内容: - stackoverflow.com/questions/9119885 / ...
特别参考Chris Dodd的以下引文:
不幸的是,在bash版本4之前没有简单的方法,当$ BASHPID是 介绍。你可以做的一件事是写一个打印其父PID的小程序:...
如果您有bash 4和BASHPID,请参阅$$ in a script vs $$ in a subshell
我没有版本4,所以我无法提供它的用法示例。
或者写一个小的C程序,它执行它的参数并使它成为USER
的setuid。
甚至可以制作一个setuid shell脚本(通常不推荐)。希望USER
是固定的;如果没有,获取runuser
的源代码,这实质上就是runuser(不是POSIX命令)所做的。
PID=`su - $USER -c "$SCRIPT > /dev/null 2>&1 & echo $!"`
使用su
(上文)时出现的问题包括:
$!
正在-c
的{{1}}子shell的上下文中执行,而不是su
所在的当前shell,PID
作为登录shell运行,因此您甚至不知道SCRIPT
的shell是否支持USER
,$!
(以及用户的shell)创建的父子流程链。IOW,当你使用
时su
只涉及一个程序,PID=`$SCRIPT > /dev/null 2>&1 & echo $!`
和两个(可能是三个?)进程,你几乎可以完全控制它们。当你将bash
投入混合时,这会改变事情,而不是在表面上显而易见 - su
和bash
支持类似的论点,对吧?!?
出于显而易见的原因,su
在保护它及其“儿童环境免受攻击”方面做了很多魔术。它甚至不喜欢被放在后台......
答案 2 :(得分:0)
这有点晚了,但是这里有两个班轮可以工作,似乎需要两个才能让它不等待$ SCRIPT完成:
su $USER -c "$SCRIPT 2>&1 & >> $LogOrNull echo $! > /some/writeable/path"
PID="$(cat /some/writeable/path)"
/some/writeable/path
需要由$ USER写入
运行这些命令的用户需要具有读取权限