Преобразование bash-скрипта в python (маленький скрипт) - PullRequest
10 голосов
/ 15 мая 2010

У меня есть bash-скрипт, который я использовал для среды Linux, но теперь я должен использовать его на платформе Windows и хочу преобразовать bash-скрипт в скрипт на python, который я могу запустить.

Скрипт bash довольно прост (я думаю), и я пытался конвертировать его через Google, но не могу конвертировать его успешно.

Скрипт bash выглядит так:

runs=5

queries=50

outfile=outputfile.txt

date  >> $outfile


echo -e "\n---------------------------------"
echo -e "\n----------- Normal --------------"
echo -e "\n---------------------------------"
echo -e "\n----------- Normal --------------" >> $outfile
for ((r = 1; r < ($runs + 1); r++))
do
    echo -e "Run $r of $runs\n"

    db2 FLUSH PACKAGE CACHE DYNAMIC

    python reads.py -r1 -pquery1.sql -q$queries -shotelspec -k6 -a5 >> $outfile
done

Основная команда, python read.py ... и т. Д. - это еще один файл python, который мне дали и у которого есть аргументы, как вы видите.

Я знаю, что об этом нужно просить, но мне бы очень помогло, если бы кто-то смог преобразовать это в скрипт на python, который я могу использовать, или, по крайней мере, дать мне несколько советов и указаний.

С уважением

Mestika

Добавлено по запросу:

Вот что я написал, но безуспешно:

runs=5
queries=50
outfile=ReadsAgain.txt
file = open("results.txt", "ab")

print "\n---------------------------------"
print "\n----------- Normal --------------"
print "\n---------------------------------"
file.write("\n----------- Normal --------------\n")
print "\n------------- Query without Index --------------"
file.write("\n------------- Query without Index --------------\n")
for r = 1; r < (%s + 1); r++ % runs
    print "Run %s of %s \n" % r % runs

    db2 FLUSH PACKAGE CACHE DYNAMIC

    output = python reads.py -r1 -pquery1.sql -q$queries -shotelspec -k6 -a5
    file.write(output)

file.close()

Ответы [ 3 ]

33 голосов
/ 15 мая 2010

Ответ

Давайте разбить его на куски. Особенно кусочки, которые вы ошиблись. :)


Назначение

outfile=ReadsAgain.txt

Неудивительно, что вам нужно заключать в кавычки строки. С другой стороны, у вас есть роскошь ставить пробелы вокруг = для удобства чтения.

outfilename = "ReadsAgain.txt"

Расширение переменной → str.format (или операция %)

python reads.py <snip/> -q$queries <snip/>

Итак, вы уже знаете, как выполнить перенаправление, но как вы можете расширить переменную? Вы можете использовать метод format (v2.6 +):

command = "python reads.py -r1 -pquery1.sql -q{0} -shotelspec -k6 -a5".format(queries)

Вы также можете использовать оператор % :

#since queries is a number, use %d as a placeholder
command = "python reads.py -r1 -pquery1.sql -q%d -shotelspec -k6 -a5" % queries

Цикл в стиле C → Цикл в объектно-ориентированном стиле

for ((r = 1; r < ($runs + 1); r++)) do done

Цикл в Python отличается от итерации в стиле C. В Python происходит то, что вы перебираете итерируемый объект, например, список. Здесь вы пытаетесь сделать что-то runs раз, поэтому вы должны сделать это:

for r in range(runs):
  #loop body here

range(runs) эквивалентно [0,1,...,runs-1], списку runs = 5 целочисленных элементов. Таким образом, вы будете повторять тело runs раз. На каждом цикле r назначается следующий элемент списка. Таким образом, это полностью эквивалентно тому, что вы делаете в Bash.

Если вы чувствуете смелость, используйте xrange. Он полностью эквивалентен, но использует более продвинутые возможности языка (поэтому его сложнее объяснить в терминах непрофессионала), но потребляет меньше ресурсов.


Перенаправление вывода → модуль subprocess

Более сложная часть, если хотите: выполнение программы и получение ее результатов. Гугл на помощь! Очевидно, что главным хитом является вопрос переполнения стека: этот . Вы можете скрыть всю сложность за этим с помощью простой функции:

import subprocess, shlex
def get_output_of(command):
  args = shlex.split(command)
  return subprocess.Popen(args,
                          stdout=subprocess.PIPE).communicate()[0]
  # this only returns stdout

Итак:

python reads.py -r1 -pquery1.sql -q$queries -shotelspec -k6 -a5 >> $outfile

становится:

command = "python reads.py -r1 -pquery1.sql -q%s -shotelspec -k6 -a5" % queries
read_result = get_output_of(command)

Не превышайте subprocess, батареи включены

По желанию, учтите, что вы можете получить почти такой же вывод date со следующим:

import time
time_now = time.strftime("%c", time.localtime()) # Sat May 15 15:42:47 2010

(Обратите внимание на отсутствие информации о часовом поясе. Это должно быть предметом другого вопроса , если он важен для вас.)


Как должна выглядеть ваша программа

Окончательный результат должен выглядеть следующим образом:

import subprocess, shlex, time
def get_output_of(command):
  #... body of get_output_of
#... more functions ...
if __name__ = "__main__":
  #only execute the following if you are calling this .py file directly,
  #and not, say, importing it
  #... initialization ...
  with file("outputfile.txt", "a") as output_file: #alternative way to open files, v2.5+
    #... write date and other stuff ...
    for r in range(runs):
      #... loop body here ...

Post scriptum

Это должно выглядеть довольно ужасно по сравнению с относительно простым и коротким скриптом Bash, верно? Python не является специализированным языком: он нацелен на то, чтобы делать все достаточно хорошо, но не предназначен для непосредственного запуска программ и получения их результатов.

Тем не менее, вы бы обычно не написали бы движок базы данных на Bash, верно? Это разные инструменты для разных работ. Здесь, если вы не планируете вносить какие-либо изменения, которые было бы нетривиальным для написания на этом языке, [Ba] sh был определенно правильным выбором.

8 голосов
/ 15 мая 2010

Должно быть довольно просто портировать вашу программу. Единственной сложной задачей будет запуск команды db2 и (возможно) рефакторинг reads.py, чтобы она могла быть вызвана как библиотечная функция.

Основная идея та же:

  • Установка локальных переменных одинакова.
  • Заменить echo на print.
  • Замените ваш цикл на for r in range(runs):.
  • Получите date с модулем datetime .
  • Заменить запись в файл модулем объекты .
  • Заменить вызов на db2 модулем подпроцесса .
  • Вам понадобится import reads.py для использования в качестве библиотеки (или вы можете использовать подпроцесс).

Но, как говорит Марсело, если вам нужна дополнительная помощь, вам лучше приложить некоторые усилия, чтобы задать прямые вопросы.

1 голос
/ 15 мая 2010

Как бы я ни предпочитал писать на Python, а не на bash, если единственная причина для его преобразования в Python - это то, что вы можете запустить его в Windows, имейте в виду, что вы можете установить bash в Windows и запустить его как есть. Cygwin.com имеет полную реализацию многих команд Unix.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...