使用Python替换shell脚本字符串时执行replace.py后launch.sh为空或无变化的问题咨询
问题排查与修复
代码层面的核心bug
- 边读边用写入模式打开同一文件,直接触发内容清空
你在遍历原文件每一行的循环内部,就用"wt"模式重新打开了launch.sh。wt写入模式的特性是:只要打开文件,就会立刻清空文件里所有原有内容,根本等不到你读完所有行。这也是你观察到“要么文件为空、要么没有任何修改”的直接触发原因:触发wt模式清空逻辑时文件就会变空;如果文件没有正常关闭导致写入缓存没刷盘,就会看起来文件完全没有改动。 fout.close未加括号,没有实际执行文件关闭操作
写fout.close只是引用了关闭方法本身,没有加括号调用,相当于这行代码完全没生效,进一步加剧了文件读写的流程混乱。- 循环结构设计逻辑完全错误
把打开写入文件、写入内容的操作放在逐行遍历的循环体内,从逻辑上就不可能完成全文件替换,哪怕没有清空问题,也只会反复覆盖写入当前遍历到的单行内容。
执行流程的bug
- SSH命令引号截断,路径识别错误
你写的ssh命令'chmod u+x ~/'replace.py' && exit'存在引号嵌套错误:字符串在~/位置就提前闭合了,实际执行时系统根本找不到replace.py文件。 - 只加执行权限,没有实际运行replace.py
chmod操作完成后直接执行了exit,从来没有调用python3 ~/replace.py执行脚本,就算权限设置正确,脚本也根本没跑起来——你观察到的文件变化,大概率是之前测试时的残留操作导致的。
关于“修改txt文件看似正常”的说明
这是操作错觉。按你当前的脚本逻辑,不管是sh还是txt文件,只要内容超过1行,都会触发同样的清空、覆盖问题。你测试txt时大概率用的是单行内容的文件,刚好没有触发逐行遍历的清空bug,误以为脚本逻辑是正常的。
修复方案
修正后的replace.py
改用“先全量读入内存、统一替换、一次性写入”的逻辑,搭配上下文管理器自动处理文件开关,从根源上避免读写混乱:
def replace(): # 先把原文件全量内容读到内存,全程不修改原文件 with open("launch.sh", "rt", encoding="utf-8") as f_read: old_content = f_read.read() # 统一完成字符串替换 new_content = old_content.replace('chromium-browser', 'chromium-browser --kiosk ') # 一次性把处理后的内容写回文件 with open("launch.sh", "wt", encoding="utf-8") as f_write: f_write.write(new_content) replace()
修正后的SSH执行命令
解决引号嵌套问题,增加实际执行脚本的步骤:
# 传输脚本到树莓派 python3 paswd.py | scp replace.py pi@192.168.1.$i: # 远程操作:配置执行权限、运行脚本、退出连接 python3 paswd.py | ssh -tt pi@192.168.1.$i "chmod u+x ~/replace.py && python3 ~/replace.py && exit"
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

