Python调用shell命令.什么类型的shell启动?

Ame*_*ina 5 python shell

我有以下python函数,允许我从python脚本中运行shell命令:

import subprocess   

def run_shell_command(cmd,cwd=None):
      retVal = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, cwd=cwd);
      retVal = retVal.stdout.read().strip('\n');
      return(retVal);
Run Code Online (Sandbox Code Playgroud)

这允许我做以下事情:

output = run_shell_command("echo 'Hello world'")
Run Code Online (Sandbox Code Playgroud)

我的问题是:通过run_shell_command上面的定义,启动了哪种类型的shell?(例如登录与互动).

其shell启动,将有助于了解知道哪些该dot文件(例如.bashrc,.profile等)之前,我的shell命令执行.

And*_*Dog 8

/bin/sh在POSIX上.查看源代码subprocess.py(这里引用Python 2.7):

def _execute_child(self, args, executable, preexec_fn, close_fds,
                   cwd, env, universal_newlines,
                   startupinfo, creationflags, shell,
                   p2cread, p2cwrite,
                   c2pread, c2pwrite,
                   errread, errwrite):
    """Execute program (POSIX version)"""

    if isinstance(args, types.StringTypes):
        args = [args]
    else:
        args = list(args)

    if shell:
        args = ["/bin/sh", "-c"] + args
        if executable:
            args[0] = executable

    [...]
Run Code Online (Sandbox Code Playgroud)


wkl*_*wkl 5

运行什么shell?

这在Python subprocess文档中提到:

可执行参数指定要执行的程序.它很少需要:通常,执行的程序由args参数定义.如果shell = True,则可执行参数指定要使用的shell.在Unix上,默认shell是/bin/sh.在Windows上,默认shell由COMSPEC环境变量指定.您需要shell=True在Windows 上指定的唯一原因是您希望执行的命令实际内置于shell中,例如dir,copy.您不需要shell = True来运行批处理文件,也不需要运行基于控制台的可执行文件.

/bin/sh 在Linux/MacOSX上通常是bash(或bash兼容 - Debian使用短划线的新版本)的别名,而在像Solaris这样的Unix上,它可能是经典的Bourne Shell.

对于Windows,通常是cmdcommand.bat.

登录shell还是不通过popen

我刚刚意识到我没有回答你的第二个问题 - 但是设置shell=True会产生一个非登录shell(看看@AndiDog的源代码链接,shell分叉的方式会创建一个非登录shell).


安全意义

另外请注意shell=True,虽然它允许您使用shell原语和快捷方式,但也可能存在安全风险,因此请务必检查可能用于进程生成的任何可能输入.

警告执行包含来自不受信任源的未经过处理的输入的shell命令会使程序容易受到shell注入攻击,这是一个严重的安全漏洞,可能导致任意命令执行.因此,在从外部输入构造命令字符串的情况下,强烈建议不要使用shell = True:

>>>
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
Run Code Online (Sandbox Code Playgroud)

shell=False禁用所有基于shell的功能,但不会受此漏洞影响; 请参阅Popen构造函数文档中的注释,以获取有关使shell = False工作的有用提示.