web-dev-qa-db-ja.com

pythonにbashを埋め込む

Pythonスクリプトを作成していて、時間が足りなくなっています。bashでよく知っていることをいくつか実行する必要があるので、bashの行をPythonスクリプト。

ありがとう

20
Open the way

システムコマンドを呼び出す場合は、 サブプロセス モジュールを使用します。

12
ghostdog74

それを行うための理想的な方法:

def run_script(script, stdin=None):
    """Returns (stdout, stderr), raises error on non-zero return code"""
    import subprocess
    # Note: by using a list here (['bash', ...]) you avoid quoting issues, as the 
    # arguments are passed in exactly this order (spaces, quotes, and newlines won't
    # cause problems):
    proc = subprocess.Popen(['bash', '-c', script],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        stdin=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if proc.returncode:
        raise ScriptException(proc.returncode, stdout, stderr, script)
    return stdout, stderr

class ScriptException(Exception):
    def __init__(self, returncode, stdout, stderr, script):
        self.returncode = returncode
        self.stdout = stdout
        self.stderr = stderr
        Exception.__init__('Error in script')

また、Nice __str__メソッドをScriptExceptionに追加することもできます(スクリプトのデバッグには必ず必要です)。ただし、それは読者にお任せします。

stdout=subprocess.PIPEなどを使用しない場合、スクリプトはコンソールに直接アタッチされます。これは、たとえば、sshからのパスワードプロンプトがある場合に非常に便利です。したがって、stdout、stderr、およびstdinをキャプチャするかどうかを制御するためにフラグを追加することができます。

29
Ian Bicking

です

import os
os.system ("bash -c 'echo $0'")

あなたのためにそれをするつもりですか?

編集:読みやすさについて

はい、もちろん、もっと読みやすくすることができます

import os
script = """
echo $0
ls -l
echo done
"""
os.system("bash -c '%s'" % script)

EDIT2:マクロに関して、pythonは私の知る限りではありませんが、

import os
def sh(script):
    os.system("bash -c '%s'" % script)

sh("echo $0")
sh("ls -l")
sh("echo done")

前の例では、基本的に必要なものが得られます(ただし、弁証法上の制限を少し考慮する必要があります)

5
Unreason

サブプロセスとos.system()は、bashコマンドが単純で、角かっこ、コンマ、引用符がない場合は正常に機能します。複雑なbash引数を埋め込む簡単な方法は、pythonスクリプトの末尾に一意の文字列コメントを付けてbashスクリプトを追加し、単純なos.system()コマンドを使用してbashファイルにテールおよび変換することです。

#!/usr/bin/python
## name this file  "file.py"
import os
def get_xred(xx,yy,zz):
    xred=[]
####gaur###
    xred.append([     zz[9] ,  zz[19] ,  zz[29]     ])
    xred.append([     zz[9] ,  xx[9]  ,  yy[9]      ])
    xred.append([     zz[10],  zz[20] ,  zz[30]     ])
    xred.append([     zz[10],  xx[10] ,  yy[10]     ])
###nitai###
    xred=np.array(xred)
    return xred
## following 3 lines executes last 6 lines of this file.
os.system("tail -n 6 file.py >tmpfile1")
os.system("sed 's/###123//g' tmpfile1>tmpfile2")
os.system("bash tmpfile2")
###### Here ###123 is a unique string to be removed
###123#!/bin/sh
###123awk '/###gaur/{flag=1;next}/###nitai/{flag=0} flag{print}' file.py >tmp1
###123cat tmp1 | awk '{gsub("xred.append\\(\\[","");gsub("\\]\\)","");print}' >tmp2
###123awk 'NF >0' tmp2 > tmp3
###123sed '$d' tmp3 |sed '$d' | sed '$d' >rotation ; rm tmp*
3
user2958481

コマンドがホストシステムでサポートされていると仮定します。

import os
os.system('command')

長いコマンドまたは一連のコマンドがある場合。変数を使用できます。例えば:

# this simple line will capture column five of file.log
# and then removed blanklines, and gives output in filtered_content.txt.

import os

filter = "cat file.log | awk '{print $5}'| sed '/^$/d' > filtered_content.txt"

os.system(filter)
3
waffleman

出力をより詳細に制御するcommandsモジュールもあります。 https://docs.python.org/2/library/commands.html

0
gander

私はあなたがやろうとしていることを正確に扱うためにスルタンを作りました。外部の依存関係はなく、できるだけ軽量になるように努めており、BashへのPythonicインターフェイスを提供します。

https://github.com/aeroxis/sultan

0
David Daniel

前述のように、os.system();を使用できます。それは速くて汚いですが、使いやすく、ほとんどの場合に機能します。これは、文字通りC system()関数へのマッピングです。

http://docs.python.org/2/library/os.html#os.system

http://www.cplusplus.com/reference/cstdlib/system/

0
stands2reason