将一个小的bash脚本转换为python

12 投票
3 回答
53589 浏览
提问于 2025-04-15 22:44

我有一个在Linux环境下使用的bash脚本,但现在我需要在Windows平台上使用它,所以想把这个bash脚本转换成可以运行的python脚本。

这个bash脚本其实挺简单的(我觉得),我试着在网上找资料转换,但一直没成功。

这个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 个回答

2

我很支持用Python来写代码,而不是用bash。不过,如果你只是想把它转换成Python是为了能在Windows上运行,那你要知道其实可以在Windows上安装bash,直接运行原来的代码也可以。Cygwin.com提供了很多Unix命令的完整实现。

38

回答

我们来把这个问题拆开,特别是你搞错的部分。:)


赋值

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模块

这部分相对“难”一些:执行一个程序并获取它的输出。谷歌来帮忙!显然,搜索结果的第一条是一个StackOverflow的问题:这个。你可以用一个简单的函数来隐藏所有复杂性:

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 ...

后记

和相对简单短小的Bash脚本相比,这看起来一定很糟糕,对吧?Python并不是一种专门的语言:它的目标是尽可能好地完成各种任务,但并不是专门为运行程序和获取输出而设计的。

不过,你通常不会用Bash来写数据库引擎,对吧?不同的工具适合不同的工作。在这里,除非你打算做一些用Bash写起来非常复杂的修改,否则[Bash]绝对是正确的选择。

11

把你的程序移植过去应该比较简单。唯一有点麻烦的地方是运行db2命令,还有可能需要调整一下reads.py,让它能作为一个库函数来调用。

基本的思路是一样的:

  • 设置本地变量的方式是一样的。
  • echo换成print
  • 把你的循环改成for r in range(runs):
  • datetime模块来获取date
  • 文件对象模块来替换写文件的方式。
  • subprocess模块来替换对db2的调用。
  • 你需要import reads.py来作为库使用(或者你也可以用subprocess)。

不过,正如Marcelo所说,如果你想要更多帮助,最好自己多花点力气,提出一些具体的问题。

撰写回答