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


10

이 답변 에서는 터미널의 명령 줄에서 여러 줄 파이썬 스 니펫을 실행하는 방법에 대해 설명합니다. 나는 중첩 된 들여 쓰기가 있더라도 쉘 스크립트 내에서 대답이 훌륭하게 작동한다는 것을 알았습니다.

#!/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 스크립트에서 파이썬 첨자의 출력을 어떻게 수집 할 수 있습니까? (예 :와 같은 변수 $output).

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


1
python - <<EOF대신 할 수 있습니다 .

jftr imo 이것은 나쁜 스타일이며 당신은 그것을 피하려고 노력해야합니다
Ulrich Dangel

1
왜 / zsh 태그입니까?
Stéphane Chazelas

답변:


12

파이썬에 변수 얻기

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

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

경우 some_text였다 test, 파이썬은 볼 것이다 some_text = "test". 그러나 코드 삽입 취약점으로 볼 수 있습니다. 경우 some_text였다 "; 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']

그것은 훨씬 더 건전하고 안전한 접근 방식입니다.


파이썬에서 출력 받기

명령 대체를 사용하여 스크립트 출력을 수집 할 수 있습니다.

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

(마지막 줄 바꿈 문자는 모두 제거됩니다.)


멋지다. 당신이 말했을 때 "You could also pass the variable to the script as an argument", 파이썬 스크립트가 쉘 스크립트에 포함되어 있다고 생각하면 어떻게 할 것입니까?
Amelio Vazquez-Reina

죄송합니다. 잠시 잊어 버렸습니다. 해당 솔루션을 제거하고 더 나은 솔루션을 추가했습니다.

heredoc 마커의 이름을 어떻게 지정하는지주의하십시오. 예제와 같이 인용 부호가 없으면 heredoc 문자열 내에서 쉘 확장이 발생합니다. 예를 들어, 파이썬 코드가 just로 구성된 print '$SHELL'경우 출력은 /bin/bash또는 쉘이 무엇이든됩니다. 첫 번째 줄을로 변경하면 python - <<'END'출력은입니다 $SHELL. bash 스크립트에 포함시키기 위해 기존 코드를 복사하여 붙여 넣는 경우 거의 셸 대체를 원하지 않습니다. bash 스크립트에 포함되지 않은 코드와 동일한 방식으로 코드를 실행하고 싶습니까?
Chris Johnson

8

당신의 접근 방식의 문제는 임베디드 파이썬 스크립트가 더 이상 원래 stdin에 액세스 할 수 없다는 것입니다 (stdin은 ... 자체이기 때문에).

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

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

또는 파이썬 스크립트에 작은 따옴표가 포함될 수있는 경우 :

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
)

6

파일 이름으로 대시를 사용하십시오.

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

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

sys.argv[1:]파이썬 에서이 작업을 수행하는 올바른 방법 인지 모르겠습니다 . -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
)

2

1) 파이썬에서 파일에 변수 할당을 작성한 다음 bash 스크립트에서 소스를 지정할 수 있습니다.

2) 귀하의 단어 (EOF)가 인용되어 있지 않으므로 여기 문서의 모든 줄에 매개 변수 확장이 적용됩니다. 이것을 사용하여 파이썬 스크립트에 물건을 전달할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.