Python의 Bash Backticks와 동일 [duplicate]


84

Python의 Ruby 및 Perl에서 발견 된 백틱에 해당하는 것은 무엇입니까? 즉, Ruby에서 다음과 같이 할 수 있습니다.

foo = `cat /tmp/baz`

파이썬에서 동등한 문장은 어떻게 생겼습니까? 나는 시도 os.system("cat /tmp/baz")했지만 결과를 표준에 넣고 해당 작업의 오류 코드를 반환합니다.


답변:


100
output = os.popen('cat /tmp/baz').read()

4
@mckenzm 문제는 외부 프로세스의 출력을 캡처하는 것입니다. Python 함수의 출력을 캡처하는 것은 매우 다른 질문입니다.
John Kugelman

1
`...`놀랍도록 간결하고 실제로 Ruby와 동일합니다 (stdout 캡처, stderr 전달)-한 가지 예외가 있습니다. Ruby는 $?이후에 프로세스의 종료 코드를 결정할 수 있습니다 . 파이썬에서는 제가 알 수 있듯이 subprocess모듈의 함수를 사용해야합니다.
mklement0

82

가장 유연한 방법은 subprocess모듈 을 사용하는 것입니다 .

import subprocess

out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)

capture_outputPython 3.7에서 도입되었으며 이전 버전의 경우 특수 함수 check_output()를 대신 사용할 수 있습니다.

out = subprocess.check_output(["cat", "/tmp/baz"])

세밀한 제어가 필요한 경우 하위 프로세스 개체를 수동으로 생성 할 수도 있습니다.

proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()

이러한 모든 함수는 키워드 매개 변수 를 지원 하여 하위 프로세스가 정확히 실행되는 방식을 사용자 정의합니다. 예를 들어 shell=True파일 이름 확장과 같은 것이 필요한 경우 셸을 통해 프로그램을 실행하는 데 사용할 수 *있지만 제한이 있습니다.


2
예,이 ( "명령")을 실행처럼 당신이 뭔가를 호출 할 수 있도록하는 기능에 포장 할 수있는 유일한 온건 한 방법입니다
Vinko Vrsalovic

이 경우 baz가 디렉토리이고 해당 디렉토리에있는 모든 파일의 내용을 가져 오려고합니다. (cat / tmp / baz / * 실행은 틱 단위로 작동하지만 여기에 설명 된 방법을 통해서는 작동하지 않습니다.)
Chris Bunch

6
re : "*"가 작동하지 않습니다. 대신 subprocess.Popen ([ "cat", "/ tmp / baz"], stdout = subprocess.PIPE, shell = True)를 사용하십시오. glob (별표) 확장은 셸에서 처리하므로이 경우 하위 처리 모듈은 셸 확장을 사용해야합니다 (/ bin / sh에서 제공).
Pasi Savolainen

1
From docs.python.org/2/library/subprocess.html#popen-constructor : "(with shell = True) args가 시퀀스 인 경우 첫 번째 항목은 명령 문자열을 지정하고 추가 항목은 추가 인수로 처리됩니다. 껍질 자체에. " 따라서 shell = True를 사용하려면 첫 번째 인수는 "cat / tmp / baz"문자열이어야합니다. 또는 시퀀스를 첫 번째 인수로 사용하려면 shell = False를 사용해야합니다
onlynone

1
@gerrit : 더 이상 사용되지 않습니다. 워드 프로세서는 추천 subprocess.run() 당신이 제공하는 유연성이 필요하지 않은 경우 이전 버전을 지원하기 위해 필요하거나하지 않는 경우 (내가이 자격 유무를 알 수없는) Popen().
JFS

27

sth가 맞다 . os.popen ()을 사용할 수도 있지만 가능한 경우 (Python 2.4+) 하위 프로세스가 일반적으로 선호됩니다.

그러나이를 장려하는 일부 언어와 달리 일반적으로 언어 내에서 동일한 작업을 수행 할 수있는 하위 프로세스를 생성하는 것은 잘못된 형식으로 간주됩니다. 느리고 덜 안정적이며 플랫폼에 따라 다릅니다. 귀하의 예는 다음과 같이 더 나을 것입니다.

foo= open('/tmp/baz').read()

eta :

baz는 디렉토리이고 해당 디렉토리에있는 모든 파일의 내용을 가져 오려고합니다.

? 디렉토리의 고양이는 나에게 오류를 가져옵니다.

파일 목록이 필요한 경우 :

import os
foo= os.listdir('/tmp/baz')

디렉토리에있는 모든 파일의 내용을 원하면 다음과 같습니다.

contents= []
for leaf in os.listdir('/tmp/baz'):
    path= os.path.join('/tmp/baz', leaf)
    if os.path.isfile(path):
        contents.append(open(path, 'rb').read())
foo= ''.join(contents)

또는 거기에 디렉토리가 없다는 것을 확신 할 수 있다면 한 줄에 넣을 수 있습니다.

path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))

1
이 질문에 대한 답은 아니지만 사용자 교육을위한 최선의 답입니다.
noamtm

1
질문 제목은 "백틱에 해당하는 것"입니다. 나는 "고양이"가 단지 예제 명령이라고 가정했습니다. 이 답변은 일반적인 경우에 도움이되지 않습니다.
제이슨

15
foo = subprocess.check_output(["cat", "/tmp/baz"])

3
이것은 지금 가장 간단한 방법입니다. "subprocess.check_output"은 다른 "popen"답변이 제공된 후 2010 년 7 월에 릴리스 된 Python 2.7에 추가되었습니다.
Robert Fleming

10

Python 3.5부터 권장되는 방법은 subprocess.run. Python 3.7부터 설명하는 것과 동일한 동작을 얻으려면 다음을 사용합니다.

cpe = subprocess.run("ls", shell=True, capture_output=True)

이것은 subprocess.CompletedProcess객체 를 반환 합니다. stdout에 대한 출력은 in cpe.stdout이고 stderr에 대한 출력은 in cpe.stderr이며 둘 다 bytes객체가됩니다. 출력을 디코딩하여 str객체 를 가져 cpe.stdout.decode()오거나 다음을 전달 text=True하여 가져올 수 있습니다 subprocess.run.

cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)

후자의 경우 cpe.stdoutcpe.stderr둘 다 str객체입니다.


파이썬 3.7부터는 text=True매개 변수를 사용하여 바이트 대신 str을 반환 할 수 있습니다 .
bwv549

6

가장 쉬운 방법은 명령 패키지를 사용하는 것입니다.

import commands

commands.getoutput("whoami")

산출:

'바가 네산'


6
매우 쉽지만 모듈은 이제 더 이상 사용되지 않습니다.
Gringo Suave

3
import os
foo = os.popen('cat /tmp/baz', 'r').read()

3
이것은 Ruby의 백틱과 동일하지만 디렉토리의 내용을 나열하는 것이 문제라면 이것이 최선의 방법이 아닙니다.
awatts

2

나는 사용하고있다

(6 : 0) $ python-버전 Python 2.7.1

위의 예 중 하나는 다음과 같습니다.

import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

나를 위해 이것은 / tmp 디렉토리에 액세스하지 못했습니다. 하위 프로세스에 대한 문서 문자열을 살펴본 후

[ "prog", "arg"]

"프로그램 인수"

원하는 셸 확장 동작을 얻었습니다 (a la Perl의`prog arg`).

print subprocess.Popen ( "ls -ld / tmp / v *", stdout = subprocess.PIPE, shell = True) .communicate () [0]


나는 펄`cmd ...`와 동등한 것을 수행하는 것이 어렵 기 때문에 잠시 전에 파이썬 사용을 중단했습니다. 파이썬이 이것을 합리적으로 만들었다는 것을 알게되어 기쁩니다.


1

subprocess.Popen을 사용하는 경우 bufsize를 지정해야합니다. 기본값은 0으로, "적당한 기본값 선택"이 아니라 "버퍼되지 않음"을 의미합니다.


1

이것은 python3에서 작동하지 않지만 python2에서는 쉘 명령을 호출하고 다음과 같이 반환 str하는 사용자 정의 __repr__메서드로 확장 할 수 있습니다 .

#!/usr/bin/env python

import os

class Command(str):
    """Call system commands"""

    def __repr__(cmd):
        return os.popen(cmd).read()

다음과 같이 사용할 수 있습니다.

#!/usr/bin/env python
from command import Command

who_i_am = `Command('whoami')`

# Or predeclare your shell command strings
whoami = Command('whoami')
who_i_am = `whoami`

4
또한이 작업을하지 말아야합니다 *
ThorSummoner 2015 년

-1

repr()

backtick(`) 연산자 제거한 에서 Python 3. 작은 따옴표와 혼동을 일으킬 정도로 유사하며 일부 키보드에서는 입력하기 어렵습니다. 대신 backtick동등한 내장 함수를 사용하십시오 repr().


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