LocalhostでPython=を使用してdate | grep -o -w '"+tz+"'' | wc -w
コマンドを実行する必要があります。同じためにsubprocess
モジュールを使用し、check_output
メソッドを使用しています同じための出力をキャプチャする必要があります。
しかし、それは私にエラーを投げています:
Traceback (most recent call last):
File "test.py", line 47, in <module>
check_timezone()
File "test.py", line 40, in check_timezone
count = subprocess.check_output(command)
File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception-
OSError: [Errno 2] No such file or directory
どこがおかしいのか助けてください。私はpythonが初めてです
シェルコマンドを実行するには_Shell=True
_を追加する必要があります。 _check_output
_は、_date | grep -o -w '"+tz+"'' | wc -w
_という実行可能ファイルを見つけようとしていますが、見つけることができません。 (エラーメッセージから重要な情報を削除した理由はわかりません)。
次の違いをご覧ください。
_>>> subprocess.check_output('date | grep 1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 603, in check_output
with Popen(*popenargs, stdout=PIPE, **kwargs) as process:
File "/usr/lib/python3.4/subprocess.py", line 848, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.4/subprocess.py", line 1446, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'date | grep 1'
_
そして:
_>>> subprocess.check_output('date | grep 1', Shell=True)
b'gio 19 giu 2014, 14.15.35, CEST\n'
_
Shell
引数の詳細および他の引数の解釈の変更方法については、 よく使用される引数 に関するドキュメントを参照してください。
_Shell=True
_の使用は避けなければならないことに注意してください。シェルの生成はセキュリティ上の危険になる可能性があるためです(Shellshockのような信頼できない入力攻撃を実行しなくても実行できます!)。
サブプロセスモジュールのドキュメントには、 シェルパイプラインの置き換え に関する小さなセクションがあります。そのためには、pythonで2つのプロセスを生成し、_subprocess.PIPE
_を使用します。
_date_proc = subprocess.Popen(['date'], stdout=subprocess.PIPE)
grep_proc = subprocess.check_output(['grep', '1'], stdin=date_proc.stdout, stdout=subprocess.PIPE)
date_proc.stdout.close()
output = grep_proc.communicate()[0]
_
パイプラインを簡単に定義する簡単なラッパー関数を作成できます。
_import subprocess
from shlex import split
from collections import namedtuple
from functools import reduce
proc_output = namedtuple('proc_output', 'stdout stderr')
def pipeline(starter_command, *commands):
if not commands:
try:
starter_command, *commands = starter_command.split('|')
except AttributeError:
pass
starter_command = _parse(starter_command)
starter = subprocess.Popen(starter_command, stdout=subprocess.PIPE)
last_proc = reduce(_create_pipe, map(_parse, commands), starter)
return proc_output(*last_proc.communicate())
def _create_pipe(previous, command):
proc = subprocess.Popen(command, stdin=previous.stdout, stdout=subprocess.PIPE)
previous.stdout.close()
return proc
def _parse(cmd):
try:
return split(cmd)
except Exception:
return cmd
_
これを適切に配置すると、pipeline('date | grep 1')
またはpipeline('date', 'grep 1')
またはpipeline(['date'], ['grep', '1'])
を記述できます。
私の経験では、サブプロセスでのFileNotFoundの最も一般的な原因は、コマンドでのスペースの使用です。代わりにリストを使用してください。
# Wrong, even with a valid command string
subprocess.run(["date | grep -o -w '\"+tz+\"' | wc -w"])
# Fixed
subprocess.run(["date", "|", "grep", "-o", "-w", "'\"+tz+\"'", "|", "wc", "-w"])
この変更により、FileNotFoundエラーが発生しなくなり、より簡単なコマンドでその例外を検索できるようになった場合、これは素晴らしいソリューションです。 python 3.5以降を使用している場合、このアプローチを使用してみてください。
import subprocess
a = subprocess.run(["date"], stdout=subprocess.PIPE)
print(a.stdout.decode('utf-8'))
b = subprocess.run(["grep", "-o", "-w", "'\"+tz+\"'"],
input=a.stdout, stdout=subprocess.PIPE)
print(b.stdout.decode('utf-8'))
c = subprocess.run(["wc", "-w"],
input=b.stdout, stdout=subprocess.PIPE)
print(c.stdout.decode('utf-8'))
シェルパイプを使用するのと同じように、1つのコマンドの出力が別のコマンドの入力になる様子を確認する必要がありますが、Pythonでプロセスの各ステップを簡単にデバッグできます。 python> 3.5には subprocess.run を使用することをお勧めしますが、以前のバージョンでは使用できません。