[英]Import bash variables from a python script
我已經看到很多從 bash 腳本內部運行 python 腳本的例子,或者將變量作為參數傳遞或使用導出來授予子 shell 訪問權限,但我在這里嘗試做相反的事情。
我正在運行一個 python 腳本並有一個單獨的文件,我們稱之為 myGlobalVariables.bash
myGlobalVariables.bash:
foo_1="var1"
foo_2="var2"
foo_3="var3"
我的 python 腳本需要使用這些變量。
舉一個非常簡單的例子:
我的PythonScript.py:
print "foo_1: {}".format(foo_1)
有沒有辦法直接導入它們? 另外,如果可能的話,我不想更改 bash 腳本,因為它是一個在其他地方多次引用的公共文件。
如果您的.bash
文件按照您的指示格式化 - 您可以通過imp
模塊將其直接作為 Python 模塊imp
。
import imp
bash_module = imp.load_source("bash_module, "/path/to/myGlobalVariables.bash")
print bash_module.foo_1
您還可以使用 os.environ:
重擊:
#!/bin/bash
# works without export as well
export testtest=one
蟒蛇:
#!/usr/bin/python
import os
os.environ['testtest'] # 'one'
我對 python很陌生,所以我歡迎提供更多慣用方法的建議,但是下面的代碼使用 bash 本身告訴我們通過首先在空環境( env -i bash
)中調用 bash 來告訴我們設置了哪些值我們將哪些變量設置為基線,然后我再次調用它並告訴 bash 獲取您的“變量”文件,然后告訴我們現在設置了哪些變量。 刪除一些誤報和明顯的空白行后,我遍歷“附加”輸出,尋找不在基線中的變量。 新看到的變量被拆分(小心地)並放入bash
字典中。 我已經離開(但注釋掉了)我之前使用exec
在 python 中本地設置變量的想法,但我遇到了引用/轉義問題,所以我切換到使用 dict 。
如果對“變量”文件的確切調用(路徑等)與我的不同,那么您需要更改該值的所有實例——在list.remove()
subprocess.check_output()
調用中,在list.remove()
調用。
這是我使用的示例變量文件,只是為了演示一些可能發生的事情:
foo_1="var1"
foo_2="var2"
foo_3="var3"
if [[ -z $foo_3 ]]; then
foo_4="test"
else
foo_4="testing"
fi
foo_5="O'Neil"
foo_6='I love" quotes'
foo_7="embedded
newline"
...這是python腳本:
#!/usr/bin/env python
import subprocess
output = subprocess.check_output(['env', '-i', 'bash', '-c', 'set'])
baseline = output.split("\n")
output = subprocess.check_output(['env', '-i', 'bash', '-c', '. myGlobalVariables.bash; set'])
additional = output.split("\n")
# these get set when ". myGlobal..." runs and so are false positives
additional.remove("BASH_EXECUTION_STRING='. myGlobalVariables.bash; set'")
additional.remove('PIPESTATUS=([0]="0")')
additional.remove('_=myGlobalVariables.bash')
# I get an empty item at the end (blank line from subprocess?)
additional.remove('')
bash = {}
for assign in additional:
if not assign in baseline:
name, value = assign.split("=", 1)
bash[name]=value
#exec(name + '="' + value + '"')
print "New values:"
for key in bash:
print "Key: ", key, " = ", bash[key]
另一種方法:
受到Marat回答的啟發,我想出了這個兩階段的 hack。 從 python 程序開始,我們稱之為“階段 1”,它使用subprocess
調用 bash 來獲取變量文件,正如我上面的答案所做的那樣,但它然后告訴 bash 導出所有變量,然后執行其余的您的 Python 程序,處於“第 2 階段”。
第 1 階段 python 程序:
#!/usr/bin/env python
import subprocess
status = subprocess.call(
['bash', '-c',
'. myGlobalVariables.bash; export $(compgen -v); exec ./stage2.py'
]);
第 2 階段 python 程序:
#!/usr/bin/env python
# anything you want! for example,
import os
for key in os.environ:
print key, " = ", os.environ[key]
正如@theorifice 回答中所述,這里的技巧可能是這種格式化的文件可以被解釋為 bash 和 python 代碼。 但他的回答已經過時了。 不推薦使用imp
模塊以支持importlib
。
由於您的文件具有“.py”以外的擴展名,您可以使用以下方法:
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
spec = spec_from_loader("foobar", SourceFileLoader("foobar", "myGlobalVariables.bash"))
foobar = module_from_spec(spec)
spec.loader.exec_module(foobar)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.