-c
1-liner 루프를 실행하기 위해 Python을 사용 하고 있습니다.
$ python -c "for r in range(10): print 'rob'"
이것은 잘 작동합니다. 그러나 for 루프 전에 모듈을 가져 오면 구문 오류가 발생합니다.
$ python -c "import sys; for r in range(10): print 'rob'"
File "<string>", line 1
import sys; for r in range(10): print 'rob'
^
SyntaxError: invalid syntax
이것이 어떻게 고칠 수 있는지 아십니까?
Makefile에 포함시킬 수 있도록 이것을 하나의 라이너로 만드는 것이 중요합니다.
답변
넌 할 수있어
echo -e "import sys\nfor r in range(10): print 'rob'" | python
또는 파이프없이 :
python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"
또는
(echo "import sys" ; echo "for r in range(10): print 'rob'") | python
또는 @ SilentGhost의 답변 / @Crast의 답변
답변
이 스타일은 메이크 파일에서도 사용할 수 있습니다 (실제로 자주 사용됨).
python - <<EOF
import sys
for r in range(3): print 'rob'
EOF
또는
python - <<-EOF
import sys
for r in range(3): print 'rob'
EOF
후자의 경우 선행 탭 문자 도 제거됩니다 (일부 구조화 된 전망을 달성 할 수 있음)
EOF 대신 행 시작 부분에 here 문서에 표시되지 않은 마커 단어를 표시 할 수 있습니다 (bash 맨 페이지 또는 here의 문서 참조 ).
답변
문제는 실제로 import 문과 관련이 없으며 for 루프 이전에 문제가 있습니다. 또는 더 구체적으로, 인라인 블록 앞에 나타나는 모든 것.
예를 들어, 다음은 모두 작동합니다.
python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"
수입품이 성명서 인 경우 문제가되지만 다음과 같이 작동하지는 않습니다.
python -c "__import__('sys'); for r in range(10): print 'rob'"
가장 기본적인 예를 들어, 다음과 같이 다시 작성할 수 있습니다.
python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"
그러나 람다는 명령문이나 여러 명령문이 아닌 표현식 만 실행할 수 있으므로 원하는 작업을 계속 수행하지 못할 수 있습니다. 그러나 생성자 표현식, 목록 이해, 람다, sys.stdout.write, “map”내장 및 일부 창의적인 문자열 보간 사이에 강력한 단일 라이너를 수행 할 수 있습니다.
문제는 얼마나 멀리 가고 싶고, 어떤 시점에서 .py
makefile이 실행 하는 작은 파일 을 작성하는 것이 낫지 않습니까?
답변
– 파이썬이 응답 작업을하려면 3.X을 뿐만 아니라, print
A와 호출 기능 : 3.X에서, 단지 print('foo')
작동 2.X도 받아 반면 print 'foo'
. -Windows
를 포함하는 크로스 플랫폼 관점 은 kxr의 유용한 답변을 참조하십시오 .
에서 bash
, ksh
또는zsh
:
문자열이 전달되기 전에 실제 개행으로 확장되는 개행을 나타내는 데 사용할 수 있는 ANSI C 인용 문자열 ( $'...'
)을 사용 \n
하십시오 python
.
python -c $'import sys\nfor r in range(10): print("rob")'
노트 \n
사이 import
와 for
줄 바꿈에 영향을하기 위해 문을.
쉘 변수 값 을 이러한 명령에 전달 하려면 인수 를 사용 sys.argv
하여 Python 스크립트 내에서 액세스하는 것이 가장 안전합니다 .
name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"
포함 된 쉘 변수 참조 와 함께 (이스케이프 시퀀스 사전 처리 된) 큰 따옴표로 묶인 명령 문자열 을 사용하는 장단점에 대한 설명은 아래를 참조하십시오.
$'...'
문자열을 안전하게 사용하려면 :
- 원래 소스 코드
\
에서 더블 인스턴스 .\<char>
서열 – 등\n
이 경우에, 또한 예컨대 보통 용의자\t
,\r
,\b
-로 확장된다$'...'
(참조 :man printf
지원 탈출을위한)
- 로
'
인스턴스를 이스케이프 합니다\'
.
POSIX 호환 상태를 유지해야하는 경우 :
명령 대체printf
와 함께 사용 :
python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"
이 유형의 문자열로 안전하게 작업하려면 :
- 원래 소스 코드
\
에서 더블 인스턴스 .\<char>
같은 – 시퀀스\n
이 경우에는, 그러나 또한이 같은 보통의 용의자\t
,\r
,\b
-에 의해 확장된다printf
(참조man printf
지원되는 이스케이프 시퀀스).
-
패스 단일 인용 에 문자열
printf %b
과 같은 임베디드 작은 따옴표 탈출'\''
(원문 참조).-
작은 따옴표를 사용하면 셸 이 문자열 내용을 해석하지 못하도록 보호합니다 .
-
즉, 짧은 파이썬 스크립트 (이 경우와 같이)의 경우에는 큰 함정 문자열을 사용하여 쉘 변수 값을 스크립트 에 통합 할 수 있습니다 . 예를 들어, 쉘
$HOME
은 현재 사용자의 홈 디렉토리로 확장 됩니다. 다음 명령에서 :python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
-
그러나 일반적으로 선호되는 접근 방식은 arguments 를 통해 쉘에서 값을 전달
sys.argv
하고 Python을 통해 값 에 액세스하는 것입니다 . 위의 명령과 동일합니다 :python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
-
-
큰 따옴표로 묶인 문자열을 사용하는 것이 더 편리 하지만 포함되지 않은 작은 따옴표를 이스케이프 처리하지 않고 포함 된 큰 따옴표로 사용할 수 있습니다.
\"
또한 문자열 의 의도 에 따라 셸 에서 해석 될 수도 있습니다. 소스 코드에서 쉘$
용이`
아닌 문자는 구문 오류를 유발하거나 문자열을 예기치 않게 변경할 수 있습니다.- 또한
\
큰 따옴표로 묶인 셸에서 셸 자체 처리가 방해 될 수 있습니다. 예를 들어, 파이썬 이 리터럴 출력을 생성하게ro\b
하려면 전달ro\\b
해야합니다. 로모그래퍼'...'
쉘 문자열과 두 배로\
경우, 우리는 얻을 :
python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
반면에,이 수행 되지 로모그래퍼 의도 한대로 작업을"..."
쉘 문자열 :
python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
쉘 해석 모두"\b"
와"\\b"
문자 등의\b
추가의 현기증 번호 요구,\
원하는 효과를 달성하기 위해 인스턴스를 :
python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"
- 또한
-
하기 를 통해 코드를 전달stdin
보다는 -c
:
참고 : 여기서는 단일 회선 솔루션 에 중점을두고 있습니다. xorho의 답변 은 여러 줄로 된 here-document 를 사용하는 방법을 보여줍니다 . 그러나 구분 기호 를 인용 하십시오. 예를 들어, <<'EOF'
쉘에서 명시 적으로 문자열을 확장하지 않으려는 경우 (위의 경고와 함께 제공)
에서 bash
, ksh
또는zsh
:
결합 ANSI C-인용 문자열을 ( $'...'
로모그래퍼) 여기에 문자열 ( <<<...
) :
python - <<<$'import sys\nfor r in range(10): print("rob")'
-
python
stdin (기본적으로 수행)에서 읽도록 명시 적으로 지시 합니다.
-
이 경우 선택 사항이지만 스크립트에 인수 를 전달 하려면 스크립트 파일 이름에서 인수를 명확하게 지정해야합니다.
python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'
POSIX 호환 상태를 유지해야하는 경우 :
stdin을 통해 출력을 전달하기 위해 파이프 라인printf
과 함께 위와 같이 사용하십시오 .
printf %b 'import sys\nfor r in range(10): print("rob")' | python
논쟁과 함께 :
printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'
답변
이것이 어떻게 고칠 수 있는지 아십니까?
으로 구분 된 Python 문 ;
은 “단일 문”일 수 있다는 사실에 의해 문제가 발생 합니다. 파이썬 문서 의 문법 파일에서 :
stmt: simple_stmt | compound_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
복합 명령문은 세미콜론을 통해 다른 명령문과 같은 행에 포함될 수 없으므로 -c
플래그로 이를 수행하는 것은 매우 불편합니다.
bash 쉘 환경에서 파이썬을 시연 할 때 복합 문장을 포함시키는 것이 매우 유용하다는 것을 알았습니다. 이것을 확실하게 수행하는 유일한 간단한 방법은 heredocs (posix shell 일)를 사용하는 것입니다.
Heredocs
용도 히어 닥 (로 만든 <<
)과 파이썬의 명령 줄 인터페이스 옵션을 , -
:
$ python - <<-"EOF"
import sys # 1 tab indent
for r in range(10): # 1 tab indent
print('rob') # 1 tab indent and 4 spaces
EOF
-
후 <<
( <<-
)를 추가하면 탭 을 사용 하여 들여 쓸 수 있습니다 (Stackoverflow는 탭을 공백으로 변환하므로 이것을 강조하기 위해 8 칸을 들여 쓰기했습니다). 선행 탭이 제거됩니다.
탭없이 다음과 같이 할 수 있습니다 <<
.
$ python - << "EOF"
import sys
for r in range(10):
print('rob')
EOF
인용 부호를 넣으면 매개 변수 및 산술 확장이EOF
방지 됩니다 . 이것은 heredoc을 더 강력하게 만듭니다.
배쉬 여러 줄 문자열
큰 따옴표를 사용하면 셸 확장이 나타납니다.
$ python -c "
> import sys
> for p in '$PATH'.split(':'):
> print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...
쉘 확장을 피하려면 작은 따옴표를 사용하십시오.
$ python -c '
> import sys
> for p in "$PATH".split(":"):
> print(p)
> '
$PATH
파이썬에서 리터럴에서 따옴표 문자를 교체해야합니다. 기본적으로 BASH가 해석하는 따옴표 문자는 사용할 수 없습니다. 우리는 파이썬에서와 같이 그것들을 대체 할 수 있습니다. 그러나 이것은 이미 혼란스러워 보입니다. 그래서 나는 이것을 권장하지 않습니다 :
$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...
허용 된 답변 (및 기타)에 대한 비판
이것은 읽기 쉽지 않습니다 :
echo -e "import sys\nfor r in range(10): print 'rob'" | python
읽기가 어렵고 오류가 발생한 경우 디버깅하기가 추가로 어렵습니다.
python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"
아마도 좀 더 읽기 쉽지만 여전히 추한 것입니다.
(echo "import sys" ; echo "for r in range(10): print 'rob'") | python
"
파이썬에 있으면 나쁜 시간을 보낼 것입니다 .
$ python -c "import sys > for r in range(10): print 'rob'"
map
for-loops를 얻기 위해 이해를 남용 하거나 나열 하지 마십시오 .
python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"
이것들은 모두 슬프고 나쁘다. 하지 마십시오.
답변
return을 사용하고 다음 줄에 입력하십시오.
user@host:~$ python -c "import sys
> for r in range(10): print 'rob'"
rob
rob
...
답변
$ python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"
잘 작동합니다. “[]”를 사용하여 for 루프를 인라인하십시오.