问题:
我正在尝试执行从PostgreSQL数据库读取的cmd。我可以手动切换到root,然后切换到postgre用户并访问我想要的信息。
我遇到的问题是,当我运行它时,它只是挂起而没有任何反应。
我有root密码,在从当前用户切换时需要这个但是我没有被提示输入它。
如何让它不挂起并提示输入密码?
为简单起见,下面的代码只执行'ls'。
代码:
def popen_cmd_shell(command):
print command
process = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True)
proc_stdout = process.communicate()[0].strip()
return proc_stdout
if __name__ == '__main__':
querylist = popen_cmd_shell('su - root; ls;')
print querylist
更新一次:
我无法在Linux SUSE上使用任何不带python 2.7的库。我只需要执行命令并退出。
更新二:
我无法以root身份运行脚本,因为我需要执行其他任务,这些任务要求我不要成为root用户。
更新三:
根据LeBarton的建议,我已经让脚本登录到root,虽然ls命令永远不会以root身份执行,但它会以我原来的用户身份执行。当我运行该命令时,系统会提示我输入root密码并从“@ host”转移到“host”,除了exit之外不能执行任何命令。当我退出所有执行的命令输出时。
我不希望将用户密码存储在LeBarton所拥有的代码中。如何以root身份执行命令并返回并继续执行脚本的其余部分,而不会锁定到新用户并需要键入“exit”。
“stderr = subprocess.STDOUT”似乎是导致它挂起的原因。
代码:
if __name__ == '__main__':
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd('echo a; su - root; ls; cd;ls;')
...continue with rest of script where I execute commands as original user
答案:
感谢Tripleee的出色回答。
我已经实现了我对以下代码的处理:
if __name__ == '__main__':
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=False)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd(['su','-','root','-c','su -s /bin/sh postgres -c \'psql -U msa ..........])
我只需要在-c后以root身份执行命令。所以它现在切换到postgres用户,并在root后返回正常用户,找到所需的数据。
答案 0 :(得分:3)
你误解了su
的作用。 su
创建一个特权子进程;它不会更改当前进程的权限。 su
之后的命令将在su
完成后以您的正常权限执行。
相反,您希望传递-c
选项以指定要使用提升的权限运行的命令。 (另请参阅su
man page。)
popen_cmd_shell('su -c ls - root')
sudo
专门用于简化此类操作,因此您可能应该使用它。
对特权命令的脚本访问是一个棘手的主题。一种常见方法是让命令执行特权操作,然后删除其特权。从安全性和设计的角度来看,这种方法都倾向于简化整体逻辑。您需要确保您的特权代码尽可能简单明了 - 例如,在特权部分无需解析。
一旦特权代码得到适当的测试,审核和冻结,赋予脚本所需的权限应该是一件简单的事情(尽管许多组织都是偏执的,并且基本上无法为此类事情建立可行的策略)。
无论采用哪种方法,在任何安全敏感的上下文中都应该避免使用shell=True
,而是将任何外部命令作为列表传递,而不是作为单个字符串传递。
popen_cmd_shell(['su', '-c', 'ls', '-', 'root'])
(也许还重命名该函数,因为你特别不需要shell。显然,还要更改函数以指定shell=False
。)
同样,这些安全问题确定您是通过su
还是sudo
来删除权限还是请求权限提升。
答案 1 :(得分:1)
你的命令就是这个
su - root; ls;
shell将其解释为此
"su -root; ls;"
你可能没有带有空格的确切名称的可执行文件。
尝试使用
将其分成列表['su', '-', 'root', ';', 'ls', ';' ]
修改
stdout=subprocess.PIPE,
导致程序挂起。如果您尝试传入密码,请使用process.communicate('root password')
。
答案 2 :(得分:0)
您是否只想访问PostgreSQL数据库?如果是这样,您根本不需要使用命令行......
Python库psycopg2将允许向PostgreSQL服务器发送命令,更多信息请点击此处:https://wiki.postgresql.org/wiki/Psycopg2_Tutorial
但是我建议使用像SQLAlchemy这样的ORM,它们使与数据库的通信成为一项微不足道的任务。