shell 腳本中的混合式程式碼。共享變數

shell 腳本中的混合式程式碼。共享變數

這個答案討論如何從終端機中的命令列運行多行 Python 程式碼片段。我注意到答案在 shell 腳本中效果很好,即使有嵌套縮進,這非常好,例如

#!/bin/bash
some_text="Hello world"
echo $some_text

cat <<EOF | python -
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF

印刷:

0 
hello
hello
1
hello
hello
2
hello
hello

但是,我很難在 shell 腳本和 Python 程式碼片段之間共用變數。

  1. 如何收集bash腳本中python下標的輸出? (例如,在諸如 之類的變數中$output)。

  2. 如何將 bash 變數(例如$some_text)傳遞給 Python 腳本?

答案1

取得 Python 變數

由於(當EOF標記未加引號時)變數替換發生在文字從定界符傳遞到python的標準輸入之前,因此您可以將變數直接丟到腳本中。

python - <<EOF
some_text = "$some_text"
EOF

如果some_text是的話test,Python 就會看到some_text = "test"。但請注意,它可以被視為程式碼注入漏洞。例如,如果some_textwas ,python 會看到:"; import os; os.system("evil-command"); x = "

some_text = ""; import os; os.system("evil-command"); x = ""

並且運行那個邪惡的命令。

如果您希望能夠將 Python 程式碼直接拉入腳本而不進行任何修改,您可以匯出變數。

export some_text

並用於os.environ檢索它。

some_text = os.environ['some_text']

這是一種更明智/更安全的方法。


從 Python 取得輸出

您可以使用命令替換來收集腳本的輸出。

output=$(
python - <<EOF
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)

(請注意,所有尾隨換行符都將被刪除)

答案2

您的方法的問題是嵌入式 python 腳本不再能夠存取原始的標準輸入(因為它的標準輸入是...本身)。

如果這是一個問題,你可以寫:

python -c '
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
'

或者如果 python 腳本可能包含單引號:

python -c "$(cat << 'EOF'
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)"

或者:

python <(cat << 'EOF'
import sys;
for r in range(3):
  print r
  for a in range(2):
    print "hello"
EOF
)

答案3

使用破折號作為檔案名稱:

ruby - a b <<'END'
puts ARGV.join(",")
END

python - a b <<'END'
import sys
print ",".join(sys.argv[1:])
END

我不知道sys.argv[1:]在 Python 中執行此操作是否正確。對於 -e / -c 您可以使用 -- 指定參數結尾:

set -- -a -b -c
ruby -e 'puts ARGV.join(",")' -- "$@"
python -c 'import sys; print ",".join(sys.argv[2:])' -- "$@"

捕獲輸出並重定向 STDERR:

x=$(ruby <<'END' 2> /dev/null
puts "a"
abort "b"
END
)

答案4

1)您可以在 python 中將變數賦值寫入文件,然後在 bash 腳本中取得該文件。

2)由於您的單字(EOF)沒有被引用,因此here-document的所有行都受到參數擴展。您可以使用它來將內容傳遞給 python 腳本。

相關內容