首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用python模块创建安装bash脚本

使用python模块创建安装bash脚本
EN

Stack Overflow用户
提问于 2014-07-22 23:51:56
回答 2查看 268关注 0票数 0

下面的代码应该给我一个“正在工作的bash脚本”

代码语言:javascript
复制
box_category=GET_COMBOBOX_value(self,self.combobox_category2,False)
list_path=Data_Location+"/program-data/programs_to_install.csv"
list=csv.reader(open(list_path),delimiter='|')

bash_file=path+"/install_programs"
if os.path.exists(bash_file):
    os.remove(bash_file)

with open(bash_file, "ab") as f:
    bash_list=csv.writer(f,delimiter='|')   
    bash_list.writerow(["#!/bin/bash"])
    bash_list.writerow([" "])
    string="if [ \"$(id -u)\" != \"0\" ]; then echo \"You need root permission for installing programs.\" 1>&2; exit 1; fi"
    print string        
    bash_list.writerow([string])

    for row in list :
        bash_list.writerow(["apt-get --yes install "+row[0]])

time.sleep(0.2)
os.system("chmod a+x '"+bash_file+"'")

首先,它“几乎”正确地生成了这个bash文件:

代码语言:javascript
复制
#!/bin/bash

"if [ ""$(id -u)"" != ""0"" ]; then echo ""You need root permission for installing programs."" 1>&2; exit 1; fi"
apt-get --yes install 0ad
apt-get --yes install audacity
apt-get --yes install banshee
apt-get --yes install barrage
..etc..

但是:

  • 当我执行bash文件时,我会得到错误bash: ./install_programs: /bin/bash^M: bad interpreter: No such file or directory

如果我删除所有内容直到第一个apt-get ..行,并添加bash扩展".sh“,解释器就会识别它。

  • csv模块写得不好

"if [ \"$(id -u)\" != \"0\" ]; then echo \"You need root permission for installing programs.\" 1>&2; exit 1; fi"

它应写明:

if [ "$(id -u)" != "0" ]; then echo "You need root permission for installing programs." 1>&2; exit 1; fi

  • 我的最后一个谜团是,即使我手动修复了所有这些东西,一旦我执行了脚本,它就不会安装任何程序,即使命令是正确的,如果我在一段时间内使用它们,也可以工作。

我得到了这样的输出:

代码语言:javascript
复制
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package 0ad
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package audacity
Reading package lists... Done
Building dependency tree       
Reading state information... Done
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-22 23:58:01

CSV的全部要点是用于逗号分隔的值,即每行上有多个列,用逗号分隔。这意味着,如果您的值中有一个逗号,则必须引用该值(或转义)。这些引用规则意味着,如果您的值中有一个引号字符,则必须引用该值来处理这个问题。所以,代替这个:

代码语言:javascript
复制
if [ "$(id -u)" != "0" ]; then echo "You need root permission for installing programs." 1>&2; exit 1; fi

…你最后的下场是:

代码语言:javascript
复制
"if [ ""$(id -u)"" != ""0"" ]; then echo ""You need root permission for installing programs."" 1>&2; exit 1; fi"

这当然不是一个有效的bash命令。

简单的解决方案是不使用csv模块;只需将行写到文件中,而不是试图将每个行转换为csv模块编写的一个列的列表,希望得到您想要的行。

代码语言:javascript
复制
with open(bash_file, "a") as f:
    f.write("#!/bin/bash\n")
    f.write(" \n")
    string="if [ \"$(id -u)\" != \"0\" ]; then echo \"You need root permission for installing programs.\" 1>&2; exit 1; fi"
    print string        
    f.write(string + "\n")
    for row in list:
        f.write("apt-get --yes install " + row[0] + "\n")

如果您厌倦了所有这些显式换行符的输入,可以将write函数包装起来:

代码语言:javascript
复制
def writeline(f, line):
    f.write(line + '\n')

然后,无论你做什么,

代码语言:javascript
复制
f.write(string + "\n")

…您可以这样做:

代码语言:javascript
复制
writeline(f, string)

这可能是个好主意;否则,您将忘记一行中的"\n“--或者更糟糕的是,错误地键入它--并花费一个小时来调试您的代码,不管您盯着它看了多少,但仍然无法运行…。

此错误:

代码语言:javascript
复制
bash: ./install_programs: /bin/bash^M: bad interpreter: No such file or directory

…也是由使用csv模块造成的。

默认的CSV方言使用Windows风格的换行符,即每一行以'\r\n'结尾。(请参阅文档中的Dialect.lineterminator。)但是bash需要Unix风格的换行符,也就是说,每一行都以'\n'结尾。因此,它将额外的'\r'视为实际行的一部分。因此,在shebang行上,它不认为需要'/bin/bash'作为解释器,而是认为'/bin/bash\r'-which是一个完全有效的文件名,但是没有这个名称的文件。

你的最后一个问题很可能就是同样的问题。一个额外的不可见的'\r'字符可能会阻止fi\r匹配if,或者导致您尝试安装一个名为'0ad\r'的包,而不是'0ad'等等。

几个边注:

  • 永远不要调用变量list;它隐藏了您可能想要使用的同名的内置类型/函数。而且,尽管出现的次数较少,但string是stdlib模块的名称,因此通常也要避免这种情况。
  • 如果您用单引号而不是双引号来编写字符串文字,则不需要转义其中的每个双引号。或者只使用三倍(单引号或双引号),您不需要转义任何一种引号,甚至换行符:"""if [ "$(id -u)" != "0" ]; then echo "You need root permission for installing programs." 1>&2; exit 1; fi"""
票数 1
EN

Stack Overflow用户

发布于 2014-07-23 00:03:01

第一条线索可能在"^M"中。这是一个回车,并且被shebang执行机制视为可执行路径的一部分。不要在其他环境中使用在Windows中创建的文本文件,除非进行适当的清理。您可以通过使用sh来运行脚本来克服这一点。正如@abarnert在他/她的回答中指出的那样,csv模块并不是输出所必需的,而且确实阻碍了它的实现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24899693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档