쉘 스크립트의 하이브리드 코드. 변수 공유

쉘 스크립트의 하이브리드 코드. 변수 공유

이 답변터미널의 명령줄에서 여러 줄 Python 코드 조각을 실행하는 방법을 설명합니다. 나는 중첩된 들여쓰기를 사용하더라도 쉘 스크립트 내에서 대답이 훌륭하게 작동한다는 것을 알았습니다. 이는 매우 좋습니다.

#!/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

그러나 쉘 스크립트와 Python 코드 조각 간에 변수를 공유하는 데 어려움을 겪고 있습니다.

  1. Bash 스크립트에서 Python 첨자의 출력을 어떻게 수집할 수 있나요? (예: 와 같은 변수에서 $output).

  2. bash 변수(예: $some_text)를 Python 스크립트에 어떻게 전달할 수 있나요?

답변1

Python으로 변수 가져오기

(마커가 인용되지 않은 경우 EOF) 텍스트가 heredoc에서 의 python표준 입력으로 전달되기 전에 변수 대체가 발생하므로 스크립트에서 바로 변수를 던질 수 있습니다.

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

만약 some_text이었다면 test파이썬은 을 보게 될 것입니다 some_text = "test". 그러나 이는 코드 주입 취약점으로 간주될 수 있습니다. 예를 들어 some_textwas 인 경우 "; import os; os.system("evil-command"); x = "Python은 다음을 확인합니다.

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 스크립트가 더 이상 원래 stdin에 액세스할 수 없다는 것입니다(stdin이... 자체이기 때문에).

그것이 문제라면 다음과 같이 작성할 수 있습니다.

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)가 인용되지 않았기 때문에 여기 문서의 모든 줄은 매개변수 확장을 따릅니다. 이것을 사용하여 Python 스크립트에 내용을 전달할 수 있습니다.

관련 정보