Я пишу Python script, и у меня заканчивается время. Мне нужно сделать некоторые вещи, которые я хорошо знаю в bash, поэтому мне просто интересно, как вставлять некоторые строки bash в Python script.
Спасибо
Я пишу Python script, и у меня заканчивается время. Мне нужно сделать некоторые вещи, которые я хорошо знаю в bash, поэтому мне просто интересно, как вставлять некоторые строки bash в Python script.
Спасибо
Если вы хотите вызвать системные команды, используйте модуль subprocess.
Идеальный способ сделать это:
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')
Вы также можете добавить хороший __str__
метод к ScriptException
(вам обязательно нужно его отладить ваши скрипты), но я оставляю это читателю.
Если вы не используете stdout=subprocess.PIPE
и т.д., то script будет прикреплен непосредственно к консоли. Это очень удобно, если у вас есть, например, запрос пароля от ssh. Таким образом, вы можете добавить флаги, чтобы контролировать, хотите ли вы записывать stdout, stderr и stdin.
Есть
import os
os.system ("bash -c 'echo $0'")
собирается сделать это за вас?
EDIT: относительно читаемости
Да, конечно, вы можете сделать его более читаемым
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")
и предыдущий пример, вы в основном получаете то, что хотите (но вы должны учитывать некоторые диалектические ограничения)
Предполагая, что команда поддерживается хост-системой:
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)
subprocess и os.system() отлично работают, когда команды bash просты и не имеют скобок, запятых и кавычек. Простым способом встраивания сложного аргумента bash является добавление bash script в конец python script с уникальными строковыми комментариями и использование простых команд 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*
Как уже упоминалось, вы можете использовать os.system(); он быстрый и грязный, он прост в использовании и работает в большинстве случаев. Это буквально отображение на функцию C system().
Существует также модуль commands
чтобы дать больше контроля над выводом: https://docs.python.org/2/library/commands.html
Вы можете использовать IPython в качестве оболочки. Поиск в Интернете: "ipython bash replacement", или посмотрите здесь: fooobar.com/questions/27471/.... Вы можете вызвать IPython из script:
#!/usr/bin/ipython --profile=pysh
Я создал Султана, чтобы точно решить, что вы пытаетесь сделать. Он не имеет внешних зависимостей и пытается быть как можно более легким и обеспечивает интерфейс Pythonic для Bash.