用于执行Bash/ksh环境和shell应用程序的Python GUI?
我一直在深入研究Python和GUI应用程序,并取得了一些相当大的进展。但是,我想就如何进行以下工作提出一些建议:用于执行Bash/ksh环境和shell应用程序的Python GUI?,python,linux,bash,shell,user-interface,Python,Linux,Bash,Shell,User Interface,我一直在深入研究Python和GUI应用程序,并取得了一些相当大的进展。但是,我想就如何进行以下工作提出一些建议: 我已经使用python(2.6.6-由于它是遗留的,所以无法升级系统)和gtk创建了一个GUI应用程序,其中显示了几个按钮,例如app1、app2、app3 当我点击一个按钮时,它就会运行一个bashshell脚本。此脚本将设置一些必需的环境变量,然后执行另一个外部应用程序(使用这些环境变量) 示例: 1) 点击按钮app1 2) GUI然后启动app1.sh以设置环境变量 3
- 我已经使用python(2.6.6-由于它是遗留的,所以无法升级系统)和gtk创建了一个GUI应用程序,其中显示了几个按钮,例如app1、app2、app3
- 当我点击一个按钮时,它就会运行一个bashshell脚本。此脚本将设置一些必需的环境变量,然后执行另一个外部应用程序(使用这些环境变量)
1) 点击按钮app1
2) GUI然后启动
app1.sh
以设置环境变量3) GUI然后运行
外部应用程序1
#外部应用程序app1是一个示例应用程序#这需要一些环境
#要在启动之前设置的变量
示例
app1.sh
内容:
#/bin/bash
export DIR=/some/location/
export LICENSE=/some/license/
export SOMEVAR='some value'
#!/usr/bin/env bash
source app1.sh # sets up env variables
if [ $? = 0 ]; then
external_app & # Runs the actual application in background
else
echo "Error executing app1.sh" 2>/dev/stderr
fi
注意:由于环境的配置方式,它必须先启动shell脚本来设置环境等,然后启动外部应用程序。shell脚本将被锁定,因此在我测试完它们后,任何人都无法对其进行编辑
因此,我考虑了如何让python GUI执行此操作,到目前为止,我正在执行以下操作:
- 当用户单击app1时,检查app1.sh是否可执行/可读,如果不可执行,则返回错误
- 创建另一个helper脚本,比如说
,它将包含helper1.sh
,后跟app1.sh
命令,然后让python通过以下命令执行该external_app1
脚本:helper1.sh
subprocess.Popen(helper1.sh,shell=True,stdout=out,stderr=subprocess.PIPE,close\u fds=True)
示例
helper1.sh
内容:
#/bin/bash
export DIR=/some/location/
export LICENSE=/some/license/
export SOMEVAR='some value'
#!/usr/bin/env bash
source app1.sh # sets up env variables
if [ $? = 0 ]; then
external_app & # Runs the actual application in background
else
echo "Error executing app1.sh" 2>/dev/stderr
fi
这样做是为了帮助器脚本在其自己的子shell中执行,这样我就可以运行多个环境设置/外部应用程序(app2、app3等) 所以我问:
helper1.sh
)捕获stderr或stdout而不阻塞/冻结GUI?使用线程还是队列谢谢。据我所知,您试图使用
n
组环境变量之一执行外部命令,其中n
由用户指定。它是GUI应用程序这一事实似乎与问题无关。如果我遗漏了什么,请纠正我
您有几个选择:
使用自定义环境变量在Python中执行命令
与将环境变量存储在单独的文件中不同,您可以使用以下命令直接设置它们:
如果env不是None
,则它必须是定义新流程的环境变量的映射;它们被使用,而不是继承当前进程的环境,这是默认行为
因此,不要使用app1.sh
、app2.sh
、app3.sh
,而是将环境变量集存储在Python中,并将它们添加到传递给Popen()
的环境中,如下所示:
env_vars = {
1: {
'DIR': '/some/location/',
'LICENSE': '/some/license/'
'SOMEVAR': 'some value'
},
2: ...
}
...
environ_copy = dict(os.environ)
environ_copy.update(env_vars[n])
subprocess.Popen('external_application', shell=True, env=environ_copy, ...)
使用包装器脚本修改环境
如果您的环境变量必须生活在单独的、专用的shell脚本中,那么像您的助手这样的脚本是最好的选择
不过,我们可以稍微清理一下:
#!/usr/bin/env bash
if source "$1"; then # Set up env variables
external_app # Runs the actual application
else
echo "Error executing $1" 2>/dev/stderr
exit 1 # Return a non-zero exit status
fi
这允许您将app1.sh
传递给脚本,而不是创建n
单独的帮助文件。不清楚为什么要使用&
作为进程的后台-Popen
启动一个单独的进程,该进程不会阻止Python进程继续。使用subprocess.PIPE
可以获取进程的stdout和stderr
避免设置环境变量
如果您可以控制external_进程
(即您编写了它,并且可以修改它),那么最好将其更改为使用命令行参数,而不是环境变量。这样你可以称之为:
subprocess.Popen('external_command', '/some/location/', '/some/license/', 'some value')
并避免完全需要shell=True
或包装器脚本。如果external\u命令
需要大量变量,则最好使用--标志
(例如--dir/some/location/
)而不是位置参数。大多数编程语言都有一个(或多个)参数处理库来简化这一过程;Python为此提供了支持
使用命令行参数而不是环境变量将使
external\u进程
更加用户友好,特别是对于您正在描述的用例。这就是我建议做的。这些答案有帮助吗?子流程似乎处理环境变量和执行。。。