Embed bash in python

2019-02-03 06:37发布

I am writting a Python script and I am running out of time. I need to do some things that I know pretty well in bash, so I just wonder how can I embed some bash lines into a Python script.

Thanks

9条回答
祖国的老花朵
2楼-- · 2019-02-03 07:03

You can use IPython as a shell. Search the web for: "ipython bash replacement", or look here: stackoverflow.com/questions/209470/can-i-use-python-as-a-bash-replacement. You can call IPython from a script:

#!/usr/bin/ipython --profile=pysh
查看更多
劳资没心,怎么记你
3楼-- · 2019-02-03 07:07

If you want to call system commands, use the subprocess module.

查看更多
爷的心禁止访问
4楼-- · 2019-02-03 07:11

Is

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

going to do it for you?

EDIT: regarding readability

Yes, of course, you can have it more readable

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

EDIT2: regarding macros, no python does not go so far as far as i know, but between

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

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

and previous example, you basically get what you want (but you have to allow for a bit of dialectical limitations)

查看更多
可以哭但决不认输i
5楼-- · 2019-02-03 07:14

The ideal way to do it:

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')

You might also add a nice __str__ method to ScriptException (you are sure to need it to debug your scripts) -- but I leave that to the reader.

If you don't use stdout=subprocess.PIPE etc then the script will be attached directly to the console. This is really handy if you have, for instance, a password prompt from ssh. So you might want to add flags to control whether you want to capture stdout, stderr, and stdin.

查看更多
一纸荒年 Trace。
6楼-- · 2019-02-03 07:16

As aforementioned, you could use os.system(); it's quick and dirty, bu it's easy to use and works for most cases. It's literally a mapping on to the C system() function.

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

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

查看更多
混吃等死
7楼-- · 2019-02-03 07:20

subprocess and os.system() works fine when bash commands are simple and does not have brackets, commas and quotes. Simple way to embed complex bash argument is to add bash script at the end of python script with a unique string comments and use simple os.system() commands to tail and convert to bash file.

#!/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*
查看更多
登录 后发表回答