셸 명령어 실행 및 출력 캡처
셸 명령어를 실행하여 출력 결과를 문자열로 반환하는 함수를 작성하려고 합니다.이 함수는 에러 메시지든 성공 메시지든 상관없습니다.명령줄을 사용했을 때와 같은 결과를 얻고 싶을 뿐입니다.
그런 일을 할 수 있는 코드 예는 무엇일까요?
예를 들어 다음과 같습니다.
def run_command(cmd):
# ??????
print run_command('mysqladmin create test -uroot -pmysqladmin12')
# Should output something like:
# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'
공식적으로 유지 보수된 모든 버전의 Python에서 가장 간단한 방법은 다음 함수를 사용하는 것입니다.
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output는 인수만 1입력으로 받는 단일 프로그램을 실행합니다.인쇄된 그대로 결과를 반환한다.stdout.stdin ahead ahead ahead ahead the 로 넘어갑니다.run ★★★★★★★★★★★★★★★★★」Popen를 참조해 주세요.명령어를 하려면 , 「 」의 「 」를 참조해 .shell=True이 답변의 끝에 있습니다.
check_output함수는 공식적으로 유지 보수된 모든 버전의 Python에서 작동합니다.그러나 최신 버전에서는 보다 유연한 접근 방식을 사용할 수 있습니다.
Python(3.5) :run
만약 당신이 Python 3.5+를 사용하고 있고 하위 호환성이 필요하지 않다면, 새로운 기능은 대부분의 작업에 대해 공식 문서에서 권장한다.모듈에 대한 매우 일반적인 고급 API를 제공합니다.프로그램의 출력을 캡처하려면subprocess.PIPE을 stdout그럼 접속해 주세요.stdout반환되는 객체의 속성:
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
은 「」입니다.bytes이므로 스트링을 decode호출된 프로세스가 UTF-8 인코딩된 문자열을 반환한다고 가정합니다.
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
원하는 경우 이 모든 것을 단일 라이너로 압축할 수 있습니다.
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
을 원하는 할 경우stdin , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .bytesinput다음 중 하나:
>>> cmd = ['awk', 'length($0) > 5']
>>> ip = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=ip)
>>> result.stdout.decode('utf-8')
'foofoo\n'
할 수 있는 은 에러입니다.stderr=subprocess.PIPE: (예:)에)result.stderr ) 。stderr=subprocess.STDOUT: (예:)에)result.stdout」를 참조해 주세요.네가 원한다면run가 제로 했을 때 , 「0」을 패스할 수 .check=True ( )을 할 수 .returncode「」의 어트리뷰트result보안이가 되지 않는 에는 보다 셸 를 실행할 수도 있습니다.shell=True이 답변의 끝에 기술된 바와 같이
이후 버전의 Python은 위의 내용을 더욱 합리화합니다.Python 3.7+에서는 위의 한 줄의 철자가 다음과 같습니다.
>>> subprocess.run(['ls', '-l'], capture_output=True, text=True).stdout
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
「」를 사용합니다.run이 방법은 기존의 작업 방식에 비해 약간의 복잡성만 더합니다.다 할 수 되었습니다.run기능하고 있습니다.
버전의 Python (4) : Python (3-3.4) : about세정세check_output
Python을 호환성이 Python을 할 수 .check_output이치노Python 2.7 python python python python python python python python python python python python python python python python python.
subprocess.check_output(*popenargs, **kwargs)
은 같은 합니다.Popen(아래 참조) 및 프로그램 출력을 포함하는 문자열을 반환합니다.이 답변의 첫머리에 보다 자세한 사용 예가 나와 있습니다..5 Python 3.5+의 check_output는 을 과 같습니다.runcheck=True ★★★★★★★★★★★★★★★★★」stdout=PIPE 「」만 한다.stdout여하하다
할 수 stderr=subprocess.STDOUT에러 메시지가 반환된 출력에 포함되도록 합니다.하지 않은 에는 보다 셸.shell=True이 답변의 끝에 기술된 바와 같이
가 stderr합니다.check_output를 참조해 주십시오.「 」를 참조해 주세요.Popen★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★,
Python ( 2 . 6 ) 의 python python :Popen
한 호환성이 보다 check_output ★★★★★★★★★★★★★★★★★」run 직접 .Popen오브젝트: 서브프로세스의 저레벨 API를 캡슐화합니다.
Popen컨스트럭터는 인수를 지정하지 않고 단일 명령어를 받아들이거나 첫 번째 항목으로 명령어를 포함하는 목록과 그 뒤에 임의의 수의 인수를 포함하여 목록 내의 개별 항목으로 문자열을 적절한 형식의 목록으로 해석하는 데 있습니다. Popen오브젝트에서는 프로세스 IO 관리 및 낮은 수준의 구성을 위해 서로 다른 인수를 여러 개 사용할 수도 있습니다.
및 출력을 하려면 , 「 」를 참조해 주세요.communicate거의 항상 권장되는 방법입니다. : :
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
또는
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
「 」를 설정했을 stdin=PIPE,communicate 를 할 수 있습니다.stdin:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
Aaron Hall의 답변에 주목해 주십시오.이것은, 일부의 시스템에서는, 다음의 설정을 실시할 필요가 있는 경우가 있습니다.stdout,stderr , , , , 입니다.stdin to 의 allPIPE (오류)DEVNULL 구하다communicate을 사용하다
드문 경우지만 복잡한 실시간 출력 캡처가 필요할 수 있습니다.Vartec의 답변은 앞으로 나아갈 방법을 제시하지만,communicate신중하게 사용하지 않으면 교착 상태가 되기 쉽습니다.
의 모든가 되지 않는 셸 할 수 .shell=True.
메모들
명령어를 합니다.1 . " " " :shell=True가 바뀌다
통상은, 「」, 「」에의 각 .run,check_output " " "Popen컨스트럭터는 단일 프로그램을 실행합니다.즉, 화려한 배쉬 스타일의 파이프가 없다는 뜻입니다.복잡한 셸 명령을 실행하려면shell=True아, 네, 네, 네, 네.예를 들어 다음과 같습니다.
>>> subprocess.check_output('cat books/* | wc', shell=True, text=True)
' 1299377 17005208 101299376\n'
그러나 이렇게 하면 보안에 대한 우려가 높아집니다.간단한 스크립팅 이외의 작업을 수행할 경우 각 프로세스를 개별적으로 호출하고 각 프로세스의 출력을 입력으로 다음 프로세스로 전달하는 것이 좋습니다.
run(cmd, [stdout=etc...], input=other_output)
또는
Popen(cmd, [stdout=etc...]).communicate(other_output)
파이프를 직접 연결하려는 유혹이 강합니다. 저항하십시오.그렇지 않으면 교착 상태가 되거나 이와 같은 해킹 행위를 해야 할 수 있습니다.
이것은 훨씬 쉽지만 Unix(Cygwin 포함)와 Python2.7에서만 작동합니다.
import commands
print commands.getstatusoutput('wc -l file')
(return_value, output)과 함께 태플을 반환합니다.
Python2 와의 양쪽 는, Python2 의 Python3 를 해 .subprocess듈듈: :
from subprocess import Popen, PIPE
output = Popen(["date"],stdout=PIPE)
response = output.communicate()
print response
뭐 이런 거:
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while(True):
# returns None while subprocess is running
retcode = p.poll()
line = p.stdout.readline()
yield line
if retcode is not None:
break
참고로 stderr을 stdout으로 리다이렉트하고 있습니다.원하는 대로가 아닐 수도 있지만 에러 메시지도 부탁드립니다.
이 함수는 한 줄씩 출력됩니다(일반적으로 출력 전체를 얻으려면 하위 프로세스가 완료될 때까지 기다려야 합니다).
사용 방법은 다음과 같습니다.
for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()):
print line,
저도 같은 문제가 있었지만 매우 간단한 방법을 알아냈습니다.
import subprocess
output = subprocess.getoutput("ls -l")
print(output)
도움이 되었으면 좋겠다
이 합니다: Python3는 Python3입니다.subprocess.getoutput()Python2 python python python2에 python python python python python python python python python python.
이 솔루션은 까다롭지만 매우 간단한 솔루션으로 많은 상황에서 작동합니다.
import os
os.system('sample_cmd > tmp')
print(open('tmp', 'r').read())
명령어 출력으로 임시 파일(여기서는 tmp)이 생성되어 원하는 출력을 읽을 수 있습니다.
코멘트의 추가 메모:일회성 작업의 경우 tmp 파일을 삭제할 수 있습니다.이 작업을 여러 번 수행해야 하는 경우 tmp를 삭제할 필요가 없습니다.
os.remove('tmp')
Vartec의 답변이 모든 행을 읽는 것은 아니기 때문에, 다음과 같은 것을 하는 버전을 만들었습니다.
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
사용법은 승인된 답변과 동일합니다.
command = 'mysqladmin create test -uroot -pmysqladmin12'.split()
for line in run_command(command):
print(line)
다음 명령을 사용하여 임의의 셸 명령을 실행할 수 있습니다.우분투에서 사용한 적이 있습니다.
import os
os.popen('your command here').read()
주의: 이것은 python 2.6 이후 사용되지 않습니다.이제 를 사용해야 합니다.subprocess.Popen
import subprocess
p = subprocess.Popen("Your command", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
print p.split("\n")
같은 문제의 풍미가 조금 달랐습니다.다음의 요건에 대해서입니다.
- STDOUT 버퍼에 누적된 STDOUT 메시지를 캡처하여 반환합니다(즉, 실시간으로).
- @와 '생산량vartec을 하여 이 를 파이톤적으로
의 키워드
- @와 '생산량vartec을 하여 이 를 파이톤적으로
- 모든 STDOUT 라인 인쇄(STDOUT 버퍼를 완전히 읽기 전에 프로세스가 종료되는 경우에도)
- 프로세스를 고주파 폴링하는 데 CPU 사이클을 낭비하지 않음
- 하위 프로세스의 반환 코드를 확인하십시오.
- 0 이외의 에러 리턴 코드가 표시되는 경우는, STDERR(STDOUT와는 별도)를 인쇄합니다.
이전 답변을 조합하고 수정하여 다음 사항을 제시했습니다.
import subprocess
from time import sleep
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# Read stdout from subprocess until the buffer is empty !
for line in iter(p.stdout.readline, b''):
if line: # Don't print blank lines
yield line
# This ensures the process has completed, AND sets the 'returncode' attr
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# The run_command() function is responsible for logging STDERR
print("Error: " + str(err))
이 코드는 이전 답변과 동일하게 실행됩니다.
for line in run_command(cmd):
print(line)
마일리지가 변동될 수 있습니다.Python 2.6.5에서 Windows에서 Vartec의 솔루션을 @senderle의 스핀을 시도했지만 오류가 발생하여 다른 솔루션은 작동하지 않았습니다.는 '오류이다'였습니다WindowsError: [Error 6] The handle is invalid
예상한 출력을 반환하기 위해 모든 핸들에 PIPE를 할당해야 한다는 것을 알게 되었습니다.다음은 저에게 효과가 있었습니다.
import subprocess
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE).communicate()
하는 거야[0]는 태플의 첫 인 '태플'을 .stdout
run_command('tracert 11.1.0.1')[0]
자세한 내용을 알게 된 후 다른 핸들을 사용하는 커스텀 시스템에서 작업 중이기 때문에 모든 STD를 직접 제어해야 했기 때문에 이러한 파이프 인수가 필요하다고 생각합니다.
(Windows에서) 콘솔 팝업을 중지하려면 다음 절차를 수행합니다.
def run_command(cmd):
"""given shell command, returns communication tuple of stdout and stderr"""
# instantiate a startupinfo obj:
startupinfo = subprocess.STARTUPINFO()
# set the use show window flag, might make conditional on being in Windows:
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
# pass as the startupinfo keyword argument:
return subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
startupinfo=startupinfo).communicate()
run_command('tracert 11.1.0.1')
Python 3.7+에서는 use 및 passcapture_output=True:
import subprocess
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True)
print(repr(result.stdout))
그러면 바이트가 반환됩니다.
b'hello world\n'
하려면 을 합니다.text=True:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, text=True)
print(repr(result.stdout))
기본 인코딩을 사용하여 바이트를 읽습니다.
'hello world\n'
인코딩을 해야 할 를 합니다.encoding="your encoding"text=True:
result = subprocess.run(['echo', 'hello', 'world'], capture_output=True, encoding="utf8")
print(repr(result.stdout))
의 초기 분할subprocess이치노
shlex.split()아서서먹먹먹먹먹
명령어 예시
git log -n 5 --since "5 years ago" --until "2 year ago"
코드
from subprocess import check_output
from shlex import split
res = check_output(split('git log -n 5 --since "5 years ago" --until "2 year ago"'))
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a\nAuthor: Artur Barseghyan...'
shlex.split()과 같습니다.
res = check_output([
'git',
'log',
'-n',
'5',
'--since',
'5 years ago',
'--until',
'2 year ago'
])
print(res)
>>> b'commit 7696ab087a163e084d6870bb4e5e4d4198bdc61a\nAuthor: Artur Barseghyan...'
여기에서는 프로세스 실행 중 또는 실행 중 출력 인쇄가 필요한 경우 해결 방법이 있습니다.
현재의 작업 디렉토리도 추가했습니다만, 몇 번인가 도움이 되었습니다.
솔루션이 누군가에게 도움이 되기를 바랍니다:).
import subprocess
def run_command(cmd_and_args, print_constantly=False, cwd=None):
"""Runs a system command.
:param cmd_and_args: the command to run with or without a Pipe (|).
:param print_constantly: If True then the output is logged in continuous until the command ended.
:param cwd: the current working directory (the directory from which you will like to execute the command)
:return: - a tuple containing the return code, the stdout and the stderr of the command
"""
output = []
process = subprocess.Popen(cmd_and_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
while True:
next_line = process.stdout.readline()
if next_line:
output.append(str(next_line))
if print_constantly:
print(next_line)
elif not process.poll():
break
error = process.communicate()[1]
return process.returncode, '\n'.join(output), error
어떤 이유로 Python 2.7에서 동작하며 os만 Import하면 됩니다!
import os
def bash(command):
output = os.popen(command).read()
return output
print_me = bash('ls -l')
print(print_me)
여러 파일에 대해 셸 명령을 실행해야 하는 경우 이 방법으로 해결했습니다.
import os
import subprocess
# Define a function for running commands and capturing stdout line by line
# (Modified from Vartec's solution because it wasn't printing all lines)
def runProcess(exe):
p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
# Get all filenames in working directory
for filename in os.listdir('./'):
# This command will be run on each file
cmd = 'nm ' + filename
# Run the command and capture the output line by line.
for line in runProcess(cmd.split()):
# Eliminate leading and trailing whitespace
line.strip()
# Split the output
output = line.split()
# Filter the output and print relevant lines
if len(output) > 2:
if ((output[2] == 'set_program_name')):
print filename
print line
편집: 방금 Max Persson의 J.F. 솔루션을 확인했습니다.세바스찬의 제안.그것을 도입했습니다.
@senderle에 따르면 나처럼 python3.6을 사용하는 경우:
def sh(cmd, input=""):
rst = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, input=input.encode("utf-8"))
assert rst.returncode == 0, rst.stderr.decode("utf-8")
return rst.stdout.decode("utf-8")
sh("ls -a")
bash에서 명령어를 실행하는 것과 동일하게 동작합니다.
그그 、 기상상향향향 향향향향 。
출력을 향상시키기 위해 반복기를 사용할 수 있습니다.보면 는 더 .
from subprocess import Popen, getstatusoutput, PIPE
def shell_command(cmd):
result = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
output = iter(result.stdout.readline, b'')
error = iter(result.stderr.readline, b'')
print("##### OutPut ###")
for line in output:
print(line.decode("utf-8"))
print("###### Error ########")
for line in error:
print(error.decode("utf-8")) # Convert bytes to str
status, terminal_output = run_command(cmd)
print(terminal_output)
shell_command("ls") # this will display all the files & folders in directory
getstatus 출력을 사용하는 기타 메서드(이해하기 쉬움)
from subprocess import Popen, getstatusoutput, PIPE
status_Code, output = getstausoutput(command)
print(output) # this will give the terminal output
# status_code, output = getstatusoutput("ls") # this will print the all files & folder available in the directory
「 」를하고 있는 는,subprocesspython module, STDOUT, STDERR 반환 코드.완전한 명령어 발신자의 실장의 예를 참조할 수 있습니다. '하다'로 할 수 있습니다.try..except네가 원한다면.
다음 함수는 STDOUT, STDERR 및 Return 코드를 반환하여 다른 스크립트로 처리할 수 있도록 합니다.
import subprocess
def command_caller(command=None)
sp = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
out, err = sp.communicate()
if sp.returncode:
print(
"Return code: %(ret_code)s Error message: %(err_msg)s"
% {"ret_code": sp.returncode, "err_msg": err}
)
return sp.returncode, out, err
검토 대상으로 simppl을 제안하고 싶습니다.이 모듈은 pypi를 통해 사용할 수 있습니다.pip install simpplpython3는 python3는 python3는 python3를 사용합니다.
simppl 를 사용하면 셸 명령어를 실행하여 화면에서 출력을 읽을 수 있습니다.
개발자들은 세 가지 유형의 사용 사례를 제안합니다.
- 가장 간단한 사용법은 다음과 같습니다.
from simppl.simple_pipeline import SimplePipeline sp = SimplePipeline(start=0, end=100): sp.print_and_run('<YOUR_FIRST_OS_COMMAND>') sp.print_and_run('<YOUR_SECOND_OS_COMMAND>') ```
- 여러 명령을 동시에 실행하려면 다음을 사용합니다.
commands = ['<YOUR_FIRST_OS_COMMAND>', '<YOUR_SECOND_OS_COMMAND>'] max_number_of_processes = 4 sp.run_parallel(commands, max_number_of_processes) ```
- 마지막으로 프로젝트에서 CLI 모듈을 사용하는 경우 파이프라인의 일부로 다른 command_line_tool을 직접 실행할 수 있습니다.다른 도구는 동일한 프로세스에서 실행되지만 로그에서 파이프라인의 다른 명령으로 나타납니다.이를 통해 다른 도구를 호출하는 도구를 보다 원활하게 디버깅하고 리팩터링할 수 있습니다.
from example_module import example_tool sp.print_and_run_clt(example_tool.run, ['first_number', 'second_nmber'], {'-key1': 'val1', '-key2': 'val2'}, {'--flag'}) ```
의 STDOUT/STDERR를 .logging★★★★★★ 。
다음은 simppl의 동작을 나타내는 완전한 코드입니다.
import logging
from logging.config import dictConfig
logging_config = dict(
version = 1,
formatters = {
'f': {'format':
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
},
handlers = {
'h': {'class': 'logging.StreamHandler',
'formatter': 'f',
'level': logging.DEBUG}
},
root = {
'handlers': ['h'],
'level': logging.DEBUG,
},
)
dictConfig(logging_config)
from simppl.simple_pipeline import SimplePipeline
sp = SimplePipeline(0, 100)
sp.print_and_run('ls')
다음은 셸 모드에서 IPython을 사용하는 다양한 OS 버전과 Python 2 및 3 모두에서 작동하는 단순하고 유연한 솔루션입니다.
from IPython.terminal.embed import InteractiveShellEmbed
my_shell = InteractiveShellEmbed()
result = my_shell.getoutput("echo hello world")
print(result)
Out: ['hello world']
몇 가지 장점이 있습니다.
- IPython 설치만 필요하므로 사용 시 특정 Python 또는 OS 버전에 대해 걱정할 필요가 없습니다. 광범위한 지원을 제공하는 Jupyter가 포함되어 있습니다.
- 기본적으로는 단순한 문자열이 필요하므로 셸 모드 arg 또는 문자열 분할을 사용할 필요가 없으므로 IMO가 약간 깨끗해집니다.
- 또한 문자열 자체에서 변수 또는 전체 Python 명령을 쉽게 대체할 수 있습니다.
데모 방법:
var = "hello world "
result = my_shell.getoutput("echo {var*2}")
print(result)
Out: ['hello world hello world']
특별히 Jupyter가 이미 설치되어 있는 경우 추가 옵션을 제공하고자 합니다.
물론 .py 스크립트가 아닌 실제 Jupyter 노트북에 있는 경우 언제든지 다음 작업을 수행할 수 있습니다.
result = !echo hello world
print(result)
같은 일을 이루다.
출력을 텍스트 파일로 리디렉션한 다음 다시 읽을 수 있습니다.
import subprocess
import os
import tempfile
def execute_to_file(command):
"""
This function execute the command
and pass its output to a tempfile then read it back
It is usefull for process that deploy child process
"""
temp_file = tempfile.NamedTemporaryFile(delete=False)
temp_file.close()
path = temp_file.name
command = command + " > " + path
proc = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
if proc.stderr:
# if command failed return
os.unlink(path)
return
with open(path, 'r') as f:
data = f.read()
os.unlink(path)
return data
if __name__ == "__main__":
path = "Somepath"
command = 'ecls.exe /files ' + path
print(execute(command))
예를 들어, execute('ls -ahl')는 3/4의 반품 가능성과 OS 플랫폼을 구분합니다.
- 출력은 없지만 정상적으로 실행됨
- 출력 빈 줄, 성공적으로 실행됨
- 실행 실패
- 출력, 실행 성공
이하의 기능을 하다
def execute(cmd, output=True, DEBUG_MODE=False):
"""Executes a bash command.
(cmd, output=True)
output: whether print shell output to screen, only affects screen display, does not affect returned values
return: ...regardless of output=True/False...
returns shell output as a list with each elment is a line of string (whitespace stripped both sides) from output
could be
[], ie, len()=0 --> no output;
[''] --> output empty line;
None --> error occured, see below
if error ocurs, returns None (ie, is None), print out the error message to screen
"""
if not DEBUG_MODE:
print "Command: " + cmd
# https://stackoverflow.com/a/40139101/2292993
def _execute_cmd(cmd):
if os.name == 'nt' or platform.system() == 'Windows':
# set stdin, out, err all to PIPE to get results (other than None) after run the Popen() instance
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
else:
# Use bash; the default is sh
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable="/bin/bash")
# the Popen() instance starts running once instantiated (??)
# additionally, communicate(), or poll() and wait process to terminate
# communicate() accepts optional input as stdin to the pipe (requires setting stdin=subprocess.PIPE above), return out, err as tuple
# if communicate(), the results are buffered in memory
# Read stdout from subprocess until the buffer is empty !
# if error occurs, the stdout is '', which means the below loop is essentially skipped
# A prefix of 'b' or 'B' is ignored in Python 2;
# it indicates that the literal should become a bytes literal in Python 3
# (e.g. when code is automatically converted with 2to3).
# return iter(p.stdout.readline, b'')
for line in iter(p.stdout.readline, b''):
# # Windows has \r\n, Unix has \n, Old mac has \r
# if line not in ['','\n','\r','\r\n']: # Don't print blank lines
yield line
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# responsible for logging STDERR
print("Error: " + str(err))
yield None
out = []
for line in _execute_cmd(cmd):
# error did not occur earlier
if line is not None:
# trailing comma to avoid a newline (by print itself) being printed
if output: print line,
out.append(line.strip())
else:
# error occured earlier
out = None
return out
else:
print "Simulation! The command is " + cmd
print ""
언급URL : https://stackoverflow.com/questions/4760215/running-shell-command-and-capturing-the-output
'programing' 카테고리의 다른 글
| 가입 시 특정 사용자에 대한 문서를 표시하는 SQL 조회 (0) | 2022.09.20 |
|---|---|
| 자바에서 스크린샷을 찍어서 이미지 같은 것에 저장하는 방법이 있나요? (0) | 2022.09.20 |
| SimpleX에서 @attribute 접근ML (0) | 2022.09.20 |
| JVM이 테일콜 최적화를 지원하지 않는 이유는 무엇입니까? (0) | 2022.09.20 |
| 테이블 스키마를 업데이트할 때 MariaDB가 매우 큰 크기의 파일을 미리 할당하려는 이유 (0) | 2022.09.20 |