使用python

时间:2015-08-05 13:38:07

标签: python postgresql shell python-2.7 subprocess

问题:

我正在尝试执行从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后返回正常用户,找到所需的数据。

3 个答案:

答案 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,它们使与数据库的通信成为一项微不足道的任务。