简体   繁体   English

如何在Python中将变量传递给Shell函数?

[英]How do I pass variables to shell functions in Python?

I would like to write a Python script to automate the process of adding the dependencies of a npm package to my Open Build Service project. 我想编写一个Python脚本来自动化将npm软件包的依赖项添加到我的Open Build Service项目中的过程。 I have a shell function: 我有一个外壳函数:

function cpobsn {
    cdobsa
    mkdir nodejs-$1
    cd nodejs-$1
    npm2PKGBUILD $1 > PKGBUILD
    cpserv
    obsa
}

this is the Python script I have at the moment (the package.json file being imported is the package.json of the npm package): 这是我目前拥有的Python脚本(要导入的package.json文件是npm软件包的package.json ):

import json
import os

with open("/home/fusion809/OBS/home:fusion809:arch_extra/arch-wiki-man/package/package.json") as json_file:
    json_data = json.load(json_file)
    deps = json_data["dependencies"]
    for key, value in deps.items():
        print(key)
        os.system("cpobsn")

I would like to pass the key variable to the cpobsn shell function (ie, I would like this Python loop to run the shell command cpobsn key on every iteration). 我想将key变量传递给cpobsn shell函数(即,我希望此Python循环在每次迭代中运行shell命令cpobsn key )。 How do I do this? 我该怎么做呢?

Functions are good for interactive use, but this seems like a case where you want a stand-alone script instead. 函数适合交互使用,但是这似乎是您需要独立脚本的情况。

If you want to have a function you can load into your .zshrc or similar, you could do something like the Python __name__ == '__main__' idiom in the script file, too. 如果要具有可以加载到.zshrc或类似文件中的函数,则也可以在脚本文件中执行类似Python __name__ == '__main__'习惯用法。 But renaming the file to the name of the command and getting rid of the function would seem like the simplest way to achieve your end goal here. 但是,将文件重命名为命令名称并删除该函数似乎是在此处实现最终目标的最简单方法。

Save this as, say, $HOME/bin/cpobsn and chmod +x it. 将其另存为$HOME/bin/cpobsn并使用chmod +x Make sure $HOME/bin is in your PATH , too. 确保$HOME/bin也位于您的PATH

#!/bin/sh
cdobsa
mkdir nodejs-"$1"
cd nodejs-"$1"
npm2PKGBUILD "$1" > PKGBUILD
cpserv
obsa

(Note the addition of proper quotes for good measure.) (请注意添加适当的引号,以保证良好的度量。)

Now, you can call it from Python, as with any regular external command. 现在,您可以从Python调用它,就像使用任何常规外部命令一样。

from subprocess import check_call
check_call(['cpobsn', key])

The choice between subprocess.call() and subprocess.check_call() will depend on whether the script returns a useful exit code. subprocess.call()subprocess.check_call()之间的选择将取决于脚本是否返回有用的退出代码。 It doesn't at the moment, so actually call would be sufficient; 现在还不行,所以实际call就足够了; on the other hand, you should fix that, and use check_call to have Python tell you when some part of the shell script failed. 另一方面,您应该解决该问题,并使用check_call让Python告诉您何时外壳脚本的某些部分失败。

Minimally, adding set -e to the shell script will make it check for errors, and abort if anything fails; 最低限度地,将set -e添加到shell脚本将使它检查错误,并在任何失败的情况下中止; but this often requires refactoring to avoid terminating on non-fatal errors (like grep not returning a result -- this is technically an error, but often an acceptable part of normal flow). 但这通常需要进行重构,以避免终止非致命错误(例如grep不返回结果-从技术上讲这是一个错误,但通常是正常流程的可接受部分)。

Using Python string concatenation with os.system is a great security risk, a key "foo; rm -rf /" for example would delete all your files. 将python字符串连接与os.system一起os.system会带来很大的安全风险,例如,键"foo; rm -rf /"会删除您的所有文件。

Python's subprocess module is much more suited for this use: Python的subprocess模块更适合此用途:

from subprocess import call
call(['cpobsn', key])

Just input key into os.system as well. 只需将密钥输入os.system

import json
import os

with open("/home/fusion809/OBS/home:fusion809:arch_extra/arch-wiki-man/package/package.json") as json_file:
    json_data = json.load(json_file)
    deps = json_data["dependencies"]
    for key, value in deps.items():
        print(key)
        os.system("cpobsn" + " " + key)

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

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