繁体   English   中英

如何从内存中运行Python中的Shell脚本?

[英]How to run a shell script in python from memory?

我正在编写的应用程序通过HTTP从网络检索外壳程序脚本,我想在python中运行此脚本,但是我不想将其物理保存到硬盘,因为我已经将其内容存储在内存中了,所以我想只是执行它。 我已经尝试过这样的事情:

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脚本?

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

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

  1. 在调用之前必须声明retrieve_script
  2. 您将其称为retrieve_script_content而不是retrieve_script
  3. 您拼写错误的scriptscrpit

只需修复这些,就可以了:

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运行脚本。

您是否正在使用类似Unix的操作系统? 如果是这样,您应该能够使用虚拟文件系统制作一个类似于内存的文件对象,您可以在该对象上指向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用作虚拟文件系统,因为基于Glibc的Linux系统始终在/ dev / shm上安装了tmpfs 如果出于安全考虑,您可能希望设置一个ramfs


您可能希望使用虚拟文件而不是将脚本内容直接传递到subprocess.Popen是,单个字符串参数的最大大小限制为131071字节

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM