gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 09:37:35 24 4
gpt4 key购买 nike

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

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 文件:

#!/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"];然后回显“您需要 root 权限才能安装程序。” 1>&2;导出 1; fi

  • 我的最后一个谜是,即使我手动修复了所有这些问题,一旦我执行了脚本,它也不会安装任何程序,即使命令是正确的,如果我在终端中使用它们,它也不会工作..

我得到这样的输出:

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

最佳答案

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"

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

简单的解决方案就是不使用 csv 模块;只需将您的行写入文件,而不是试图将每一行都变成一列的列表以供 csv 模块写入以希望获得您想要的行。

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 函数包装起来:

def writeline(f, line):
f.write(line + '\n')

然后,无论你在哪里这样做:

f.write(string + "\n")

……你可以这样做:

writeline(f, string)

这可能是个好主意;否则,您将忘记一行中的“\n”——或者,更糟的是,将其打错——并花一个小时调试您的代码,无论您如何盯着它看,它显然是正确的,但仍然无法正常工作……


这个错误:

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\r' 而不是认为你想要 '/bin/bash' 作为你的解释器 - 这是一个完全有效的文件名,但不存在具有该名称的文件。


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


一些旁注:

  • 永远不要调用变量list;它隐藏了您可能想要使用的同名内置类型/函数。此外,虽然它出现的频率较低,但 string 是 stdlib 模块的名称,因此通常也应避免使用它。
  • 如果您使用单引号而不是双引号编写字符串文字,则无需转义其中的每个双引号。或者你可以只使用三重引号(单引号或双引号),你不需要转义任何一种引号,甚至换行符: """if [ "$(id -u)"!= "0 "]; then echo "安装程序需要root权限。"1>&2; exit 1; fi"""

关于python - 使用 python csv 模块创建安装 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24899693/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com