現在侵入テストとPythonプログラミングを勉強しています。 PythonでLinuxコマンドを実行する方法を知りたいだけです。実行したいコマンドは次のとおりです。
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
をターミナルで実行すると、自分で入力して Enter を押した場合と同じように実行されますか?
コメント
回答
次のように、os.system()
を使用できます。
import os os.system("ls")
またはあなたの場合:
os.system("echo 1 > /proc/sys/net/ipv4/ip_forward") os.system("iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080")
さらに良いことに、サブプロセスの呼び出しを使用できます。より安全で、より強力で、おそらくより高速です:
from subprocess import call call("echo "I like potatos"", shell=True)
または、シェルを呼び出さずに:
call(["echo", "I like potatos"])
出力をキャプチャする場合、その1つの方法は次のようになります。
import subprocess cmd = ["echo", "I like potatos"] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) o, e = proc.communicate() print("Output: " + o.decode("ascii")) print("Error: " + e.decode("ascii")) print("code: " + str(proc.returncode))
強く設定することをお勧めしますのcommunicate
で、呼び出し時に発生する可能性のある例外をキャプチャします。これは非常にエラーが発生しやすいコードであるため、エラーが発生することを予期し、それに応じて処理する必要があります。
https://docs.python.org/3/library/subprocess.html
コメント
- os.systemは、バージョン2.6以降非推奨になりました。サブプロセスは使用するのに適切なモジュールです。
- @binarysubsite、サポートされていない、または利用できないなどの非推奨ですか? '最近2.7のマシンで作業していますが(選択ではありません)、
os.system
は引き続き機能します。 - また、推奨されるように
subprocess.call
を使用する場合は、shell=True
を指定する必要がある場合があります… here - Python 3.4では、shell = Trueを指定する必要があります。そうしないと、callコマンドが機能しません。デフォルトでは、shell = Trueが設定されていない限り、呼び出しは文字列で指定されたファイルを開こうとします。また、Python3.5では呼び出しがrunに置き換えられているようです
- 一般的なPOSIXコードは、おそらく
LC_CTYPE
<の文字セットを使用してdecode()
を呼び出す必要があります。 / div>環境変数。
回答
最初のコマンドは単にファイルに書き込むだけです。 python
はシェルを使用せずにファイルの読み取りと書き込みを行うことができるため、これをシェルコマンドとして実行することはありません。
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
iptables
コマンドは、外部で実行することをお勧めします。これを行う最良の方法は、を使用することです。サブプロセスモジュール。
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
このメソッドもシェルを使用しないことに注意してください。これは、不要なオーバーヘッドです。
回答
最も簡単な方法:
import os os.system("your command here")
これは最も柔軟なアプローチではありません; 「1回実行して完了し、終了するまでブロックする」よりもプロセスを制御する必要がある場合は、代わりにsubprocess
モジュールを使用する必要があります。
回答
原則として、可能な限りPythonバインディングを使用することをお勧めします(例外のキャッチなどの利点があります)。
echo
コマンドの場合、@ jordanmの回答で提案されているように、Pythonを使用してファイルに書き込む方が明らかに優れています。
iptables
コマンド、おそらくpython-iptables
( PyPiページ、説明とドキュメントが記載されたGitHubページ)は、必要なものを提供します(特定のコマンドはチェックしませんでした)。
これにより、外部ライブラリなので、メリットを重視する必要があります。サブプロセスの使用は機能しますが、出力を使用する場合は、「自分で解析し、将来のiptables
バージョンで出力の変更に対処する必要があります。
コメント
- もう1つ注意すべき点は、
subprocess
呼び出しを使用した単体テストコードはあまり役に立たないということです。はい、モックアウトできます。呼び出しがありますが、テストでは外部呼び出しの結果について仮定する必要があります。 - あなたの答えはアドバイスのようなものです。OPは、PythonからLinuxシステムコマンドを実行する方法を具体的に尋ねました。
- @kapadはい、しかし彼はなぜそうしたいのかを特定し、私は代替案を提案しました。
回答
あなたのシェルのPythonバージョン。注意してください。私はそれをテストしていません。
from subprocess import run def bash(command): run(command.split()) >>> bash("find / -name null") /dev/null /sys/fs/selinux/null /sys/devices/virtual/mem/null /sys/class/mem/null /usr/lib/kbd/consoletrans/null
コメント
- 文字列分割は、単純な場合にのみ機能します。 シェルスタイルのコマンド分割には、
shlex.split
回答
SSHの後に他のシステムでこのコマンドを実行する場合は、Paramikoという名前のモジュールを使用する必要がある場合があります。 これは本当に便利です。
コマンドの実行をローカルマシンから実行する必要がある場合は、osモジュール関数が役立ちます。
ホームページ: https://www.paramiko.org/
bash
は肥大化したシェルでした…os.system
のドキュメントではsubprocess
モジュール。