如何执行任意shell脚本并通过Python传递多个变量?

时间:2022-08-29 01:13:59

I am building an application plugin in Python which allows users to arbitrarily extend the application with simple scripts (working under Mac OS X). Executing Python scripts is easy, but some users are more comfortable with languages like Ruby.

我正在使用Python构建一个应用程序插件,允许用户使用简单的脚本(在Mac OS X下工作)任意扩展应用程序。执行Python脚本很简单,但有些用户更喜欢Ruby等语言。

From what I've read, I can easily execute Ruby scripts (or other arbitrary shell scripts) using subprocess and capture their output with a pipe; that's not a problem, and there's lots of examples online. However, I need to provide the script with multiple variables (say a chunk of text along with some simple boolean information about the text the script is modifying) and I'm having trouble figuring out the best way to do this.

根据我的阅读,我可以使用子进程轻松执行Ruby脚本(或其他任意shell脚本),并使用管道捕获它们的输出;这不是问题,网上有很多例子。但是,我需要为脚本提供多个变量(比如一大块文本以及一些关于脚本正在修改的文本的简单布尔信息),并且我无法找出最佳方法。

Does anyone have a suggestion for the best way to accomplish this? My goal is to provide scripts with the information they need with the least required code needed for accessing that information within the script.

有没有人建议最好的方法来实现这一目标?我的目标是为脚本提供所需的信息,以及在脚本中访问该信息所需的最少代码。

Thanks in advance!

提前致谢!

3 个解决方案

#1


See http://docs.python.org/library/subprocess.html#using-the-subprocess-module

args should be a string, or a sequence of program arguments. The program to execute is normally the first item in the args sequence or the string if a string is given, but can be explicitly set by using the executable argument.

args应该是一个字符串,或一系列程序参数。要执行的程序通常是args序列中的第一项,如果给出了字符串,则是字符串,但可以使用可执行参数显式设置。

So, your call can look like this

所以,你的电话看起来像这样

p = subprocess.Popen( args=["script.sh", "-p", p_opt, "-v", v_opt, arg1, arg2] )

You've put arbitrary Python values into the args of subprocess.Popen.

您已将任意Python值放入subprocess.Popen的args中。

#2


If you are going to be launching multiple scripts and need to pass the same information to each of them, you might consider using the environment (warning, I don't know Python, so the following code most likely sucks):

如果您要启动多个脚本并需要将相同的信息传递给每个脚本,您可以考虑使用该环境(警告,我不知道Python,因此以下代码很可能很糟糕):

#!/usr/bin/python 

import os

try:
    #if environment is set
    if os.environ["child"] == "1":
        print os.environ["string"]
except:
    #set environment
    os.environ["child"]  = "1"
    os.environ["string"] = "hello world"

    #run this program 5 times as a child process
    for n in range(1, 5):
        os.system(__file__)

#3


One approach you could take would be to use json as a protocol between parent and child scripts, since json support is readily available in many languages, and is fairly expressive. You could also use a pipe to send an arbitrary amount of data down to the child process, assuming your requirements allow you to have the child scripts read from standard input. For example, the parent could do something like (Python 2.6 shown):

您可以采用的一种方法是使用json作为父脚本和子脚本之间的协议,因为json支持很容易以多种语言提供,并且具有相当的表现力。您还可以使用管道将任意数量的数据发送到子进程,假设您的要求允许您从标准输入中读取子脚本。例如,父级可以执行类似的操作(显示Python 2.6):

#!/usr/bin/env python

import json
import subprocess

data_for_child = {
    'text' : 'Twas brillig...',
    'flag1' : False,
    'flag2' : True
}

child = subprocess.Popen(["./childscript"], stdin=subprocess.PIPE)
json.dump(data_for_child, child.stdin)

And here is a sketch of a child script:

这是一个儿童脚本的草图:

#!/usr/bin/env python
# Imagine this were written in a different language.

import json
import sys

d = json.load(sys.stdin)
print d

In this trivial example, the output is:

在这个简单的例子中,输出是:

$ ./foo12.py
{u'text': u'Twas brillig...', u'flag2': True, u'flag1': False}

#1


See http://docs.python.org/library/subprocess.html#using-the-subprocess-module

args should be a string, or a sequence of program arguments. The program to execute is normally the first item in the args sequence or the string if a string is given, but can be explicitly set by using the executable argument.

args应该是一个字符串,或一系列程序参数。要执行的程序通常是args序列中的第一项,如果给出了字符串,则是字符串,但可以使用可执行参数显式设置。

So, your call can look like this

所以,你的电话看起来像这样

p = subprocess.Popen( args=["script.sh", "-p", p_opt, "-v", v_opt, arg1, arg2] )

You've put arbitrary Python values into the args of subprocess.Popen.

您已将任意Python值放入subprocess.Popen的args中。

#2


If you are going to be launching multiple scripts and need to pass the same information to each of them, you might consider using the environment (warning, I don't know Python, so the following code most likely sucks):

如果您要启动多个脚本并需要将相同的信息传递给每个脚本,您可以考虑使用该环境(警告,我不知道Python,因此以下代码很可能很糟糕):

#!/usr/bin/python 

import os

try:
    #if environment is set
    if os.environ["child"] == "1":
        print os.environ["string"]
except:
    #set environment
    os.environ["child"]  = "1"
    os.environ["string"] = "hello world"

    #run this program 5 times as a child process
    for n in range(1, 5):
        os.system(__file__)

#3


One approach you could take would be to use json as a protocol between parent and child scripts, since json support is readily available in many languages, and is fairly expressive. You could also use a pipe to send an arbitrary amount of data down to the child process, assuming your requirements allow you to have the child scripts read from standard input. For example, the parent could do something like (Python 2.6 shown):

您可以采用的一种方法是使用json作为父脚本和子脚本之间的协议,因为json支持很容易以多种语言提供,并且具有相当的表现力。您还可以使用管道将任意数量的数据发送到子进程,假设您的要求允许您从标准输入中读取子脚本。例如,父级可以执行类似的操作(显示Python 2.6):

#!/usr/bin/env python

import json
import subprocess

data_for_child = {
    'text' : 'Twas brillig...',
    'flag1' : False,
    'flag2' : True
}

child = subprocess.Popen(["./childscript"], stdin=subprocess.PIPE)
json.dump(data_for_child, child.stdin)

And here is a sketch of a child script:

这是一个儿童脚本的草图:

#!/usr/bin/env python
# Imagine this were written in a different language.

import json
import sys

d = json.load(sys.stdin)
print d

In this trivial example, the output is:

在这个简单的例子中,输出是:

$ ./foo12.py
{u'text': u'Twas brillig...', u'flag2': True, u'flag1': False}