代码之家  ›  专栏  ›  技术社区  ›  Mykhailo Seniutovych

如何从内存运行python中的shell脚本?

  •  0
  • Mykhailo Seniutovych  · 技术社区  · 6 年前

    import subprocess
    
    script = retrieve_script()
    popen = subprocess.Popen(scrpit, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdOut, stdErr = popen.communicate()
    
    def retrieve_script_content():
        # in reality I retrieve a shell script content from network,
        # but for testing purposes I will just hardcode some test content here
        return "echo command1" + "\n" + "echo command2" + " \n" + "echo command3"
    

    此代码段将不起作用,因为 subprocess.Popen

    有没有其他方法可以从内存运行shell脚本?

    3 回复  |  直到 6 年前
        1
  •  2
  •   that other guy    6 年前

    此代码段将不起作用,因为subprocess.Popen希望您一次只提供一个命令。

    事实并非如此。相反,它不起作用的原因是:

    1. retrieve_script
    2. retrieve_script_content 而不是 检索\u脚本
    3. 你拼错了 script 作为 scrpit

    把它们修好就好了:

    import subprocess
    
    def retrieve_script():
        return "echo command1" + "\n" + "echo command2" + " \n" + "echo command3"
    
    script = retrieve_script()
    popen = subprocess.Popen(script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdOut, stdErr = popen.communicate()
    print(stdOut);
    

    $ python foo.py
    command1
    command2
    command3
    

    但是,请注意,这将忽略shebang(如果有的话),并使用系统的 sh 每一次。

        2
  •  1
  •   unutbu    6 年前

    use a virtual filesystem 制作一个类似内存文件的对象 subprocess.Popen :

    import subprocess
    import tempfile
    import os
    import stat
    
    def retrieve_script_content():
        # in reality I retrieve a shell script content from network,
        # but for testing purposes I will just hardcode some test content here
        return "echo command1" + "\n" + "echo command2" + " \n" + "echo command3"
    
    content = retrieve_script_content()
    with tempfile.NamedTemporaryFile(mode='w', delete=False, dir='/dev/shm') as f:
        f.write(content)
        os.chmod(f.name, stat.S_IRUSR | stat.S_IXUSR)
        # print(f.name)
    popen = subprocess.Popen(f.name, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
                             shell=True)
    stdOut, stdErr = popen.communicate()
    
    print(stdOut.decode('ascii'))
    # os.unlink(f.name)
    

    印刷品

    command1
    command2
    command3
    

    /dev/shm 作为虚拟文件系统 Linux systems based on Glibc always have a tmpfs mounted on /dev/shm . setup a ramfs .


    您可能希望使用虚拟文件而不是 passing the script contents directly to subprocess.Popen limited to 131071 bytes .

        3
  •  0
  •   Serge    6 年前

    可以使用Popen执行多命令脚本。当shell标志为False时,Popen仅将您限制为一个命令字符串,但是可以传递命令列表。 Popen 的旗帜 shell=True 允许多命令脚本(这被认为是不安全的,尽管您正在做的事情-从web执行脚本-已经非常危险)。