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.stdout및 cpe.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.