Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于执行Bash/ksh环境和shell应用程序的Python GUI?_Python_Linux_Bash_Shell_User Interface - Fatal编程技术网

用于执行Bash/ksh环境和shell应用程序的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和GUI应用程序,并取得了一些相当大的进展。但是,我想就如何进行以下工作提出一些建议:

  • 我已经使用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
    ,后跟
    external_app1
    命令,然后让python通过以下命令执行该
    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进程
    更加用户友好,特别是对于您正在描述的用例。这就是我建议做的。

    这些答案有帮助吗?子流程似乎处理环境变量和执行。。。