Pythonでシェルコマンドを実行する

現在侵入テストと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 がこれを実行できます。
  • そして私は考えましたbashは肥大化したシェルでした…
  • os.systemのドキュメントではsubprocessモジュール。
  • iptablesの出力が必要ですか?
  • この質問はStackoverflowに移行する必要があります。

回答

次のように、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/

開発: https://github.com/paramiko/paramiko

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です