首席数据官

Hi, 请登录

微信文件变成「只读」?我用 ChatGPT 找到了解决方法

编注:本文记录了作者在没有过多终端脚本基础的情况下,通过「咨询」ChatGPT 从无到有实现自动修复微信文件权限的过程。如果你对终端环境比较熟悉,文中提到的步骤和方法可能有些基础,解决方案也不一定是最优的。但我们认为这个探索过程是很有意义的,也体现了生成式 AI 与自动化结合的应用场景,值得推荐。

如果你需要本文方案的最简化、一次性实现,可以在终端运行:

find "$HOME/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat" -type f -path '*/*/Message/MessageTemp/*/File/*' -exec chmod 644 {} \;

▍引言

不知道从什么时候开始,在 macOS 上微信收到的文件都变成了只读,每次打开新文件,都需要另存一份。对于每天都需要用微信收发大量 Word 文档的我,这个改动非常折磨人。当然,最好的办法是不用微信,但这显然不是打工人可以决定的。

看到这行字就难受

好在,经过一些研究,我发现这个问题还是能够简单解决的,这里也将探索的过程分享给大家。需要说明的是,我不是相关方面的专业人士,本文所展示的几种方法未必是最合适的解决方案,特别是相关脚本是否存在风险还请自行判断。

▍一、自动操作

此前,我曾经在网上学过一个将 Word 文档保存为 PDF 文件的快速操作(Quick Action)指令,用途是批量将 Word 转换为 PDF 文档。因此,这次我首先也想到通过 macOS 系统里自带的自动操作(Automator)来实现这个目标。

修改 Word 文档等文件的权限,至少有三种方法。第一种是打开文档然后复制或另存文件;第二种是对文档右键选择「显示简介」,拉至下方将用户的权限修改为读和写(Read & Write)。

第三种方法看起来更像是适合批量操作的,用到的是 chmod 命令,具体而言,打开终端(Terminal.app),输入

chmod 644 /path/to/ file

即可赋予用户读写的权限。

其中,644 三个数字分别对应用户(所有者)、用户组和其他(所有人)的权限。4 代表读的权限,2 代表写的权限,1 代表执行权限。用二进制写出来的话,就不难想象 6(二进制 110)可以表示读(4,二进制 100)加上写(2,二进制 010)的权限。至于文件路径,把需要的文件拖进终端就可以,注意 chmod、644 与文件路径之间均有空格。

批量数据上传业务意思_亚马逊批量上传图片_美国亚马逊批量上传90003

图片来自网络

知道这个命令以后,我开始写快捷操作。一开始,我按照之前 Word 文档转 PDF 文件的经验使用了 AppleScript,告诉(tell)终端(Terminal.app)去运行这行 chmod 命令。问题是,不仅运行时候会有个终端弹出,运行结束后终端也不会关闭,一直保留在 dock 栏上,即使按照网上的说法,使用 exit 命令加上修改 profiles 也不能完全解决。

奇怪于网络上为什么几乎没有人遇到相似问题,我才在检索中发现,根本没有必要使用 AppleScript 打开终端,在自动操作中运行一个 Shell 脚本就可以了。完整的操作过程如下:

• 打开 macOS 自带的应用程序「自动操作(Automator)」,在弹出的新建窗口中双击选择「快速操作(Quick Action)」。

• 在左侧的工具中找到,或者直接搜索「Shell」找到「运行 Shell 脚本(Run Shell Script)」并双击或将其拖至右侧窗口。

• 在右侧窗口设置为收到「文件或文件夹(files or folders)」,位于「访达(Finder.app)」,下方传递输入修改为「作为自变量(as arguments)」,然后在下方自动生成的模板中,将echo "$f"这一行替换为chmod 644 "$f"就可以了。整体如下图所示:

美国亚马逊批量上传90003_亚马逊批量上传图片_批量数据上传业务意思

Shell 中引用变量需要加 $,就写下面那点东西的时间里我可能就忘了 50 次吧

• 最后,保存并命名(比如:「修改权限」)。此外,也可以在上面的设置中修改图标和颜色。之后,在访达中,对任意文件右键选择「快速操作(Quick Action)」,点击刚才添加的「修改权限」操作,就能够立即将文件权限变更为读和写。

到这一步,问题得到了初步解决,在每次保存微信文件后,我只需要通过右键点击目标文件,再从快捷操作中选择上面创建的内容,就可以让随后打开的文档不再是「只读」。只不过,这样仍然有点麻烦,特别是忘记这一操作径直打开文档时,仍然有不通畅的感觉。

二、监控文件变动:认识 fswatch 工具

我的想法是,当我将微信中的文件保存到某个文件夹,如果这个文件夹里发生的变化能够被监测到,而发生变动后系统就自动运行一次上面的授权脚本,那么就不需要我手动点击快速操作按钮。

从这一步开始,我想到了 ChatGPT。过去,我拿 ChatGPT(GPT3.5 版本)测试回答工作中遇到的法律问题,得到的结果并不令人满意。但考虑到 ChatGPT 在分析代码方面的能力,我非常期待它在帮助我这样外行人时的效果。结果是,ChatGPT 的表现令我感到惊喜,在很多时候比搜索得到的结果更贴合我的问题,也更详细和耐心。

不过,在部分问题中,ChatGPT 仍然会犯错,需要自行甄别或通过网络去检索更多和更新(尤其是在 ChatGPT 数据集截止日期以后)的解决方法。

(一)fswatch 工具的安装

我询问 ChatGPT 的第一个问题是在 macOS 中是否有监控文件夹内文件发生变动就运行脚本的方法,ChatGPT 告诉我 fswatch 工具可以实现这个目标。

ChatGPT 告诉我 fswatch 需要通过 Homebrew 安装,fswatch 的 GitHub 页面也给出了其他安装方法。在安装 Homebrew 后,在终端中输入brew install fswatch即可安装 fswatch。

只是,在对话过程中,ChatGPT 偶尔会忘记我在使用 macOS 这一前提,比如给我推荐 inotifywait 工具,在我尝试失败并检索后才发现,这是一个 Linux 上的命令。

美国亚马逊批量上传90003_亚马逊批量上传图片_批量数据上传业务意思

欺骗了我的一些感情和一点时间

(二)选择被监控的文件范围

在脚本中,只需要输入fswatch 文件路径就可以监控指定文件夹,同时,也可以添加一些更细化的参数以选择监控文件的范围。在这方面问题上,可能由于 fswatch 自身的版本更新,ChatGPT 有时候能够迅速解决了我的问题,但有时候也会犯错导致我走弯路。

比如,我希望只在添加文件时触发事件,ChatGPT 明确告诉我可以使用--event Create参数来实现。

美国亚马逊批量上传90003_批量数据上传业务意思_亚马逊批量上传图片

但在我想要使用 -i 参数将添加的文件类型限制于 .docx 等文档时,ChatGPT 就明显弄反了 -i(include,包含)和 -e(exclude,排除)两个参数。

批量数据上传业务意思_亚马逊批量上传图片_美国亚马逊批量上传90003

这个回答有不止一处错误

考虑到授权陌生文件可能带来的风险,如何只监控特定文件恰恰是我比较关注的事项(当然,都监控然后加一个文件名判断也不是难事)。ChatGPT 在这个问题上没有给我什么帮助。这里需要特别记录一下的是,fswatch 命令中,只写 -i 并不意味着可以只监控符合规则的文件,必须首先写上 -e 并排除一切文件,再写一个 -i 包含需要的文件,才能够实现监控符合条件文件的目标。

上图的另一个错误在于,fswatch 使用的匹配规则并非通配符,而是正则表达式(regex),当然这也可能是由于 ChatGPT 使用过时资料库导致的。在正则表达式中,匹配任意单字符的不是 * 而是 .,任意数量字符则是 .*。在学习和测试后,我将匹配部分写成如下形式:

# 文件类型,可随意修改添加

types=("doc" "docx" "ppt" "pptx" "xls" "xlsx")

# 生成正则表达式

re=""

for i in ${types[*]};do re="$re|$i$";done

re=${re:1}

# 监控满足条件的文件变动

fswatch -e ".*" -EIi $re --event Created $path

其中,re 经过循环后生成的值为doc$|docx$|ppt$|pptx$|xls$|xlsx$,表示匹配以 doc、docx 等结尾的文件名。顺便一提,Shell 在赋值的时候,= 左右侧不能加空格,这写起来也太难受了。

fswatch 的参数中,-e ".*"表示排除所有(.*)文件。-EIi $re表示包含上述文件类型的文件,E(extended)和 I(insensitive)的含义分别为使用扩展的正则表达式(否则无法使用或逻辑|),以及不区分大小写。$path则是目标文件夹,我事先定义了文件路径。

(三)对监控的文件做出修改

监控文件发生变化后,在如何修改变动文件权限的问题上,我一开始又使用了笨方法。我询问 ChatGPT 如何找到最后添加到文件,它在两次提问中分别给了我使用 ls 命令和 find 命令的方法,但我测试后发现这似乎找到的是最后修改文件,而非最后添加文件,这与我的需求不太符合。于是我使用了find $path -type f -perm 444来查找整个文件夹内权限为「444」(只读)的文件并批量进行修改。

但当我返回查看 ChatGPT 最初给我的示例时,我意识到我可能把事情想复杂了。

批量数据上传业务意思_美国亚马逊批量上传90003_亚马逊批量上传图片

这个例子帮了大忙

虽然暂时不知道 | 的具体作用,但上面这行示例代码的意思显然是,fswatch 发现变动后,通过 while 循环和 echo 命令显示变动的文件,这看起来很符合我的要求。为此,我认真学习了管道 | 的用法……才怪咧,并没有那么多时间。显然,这里我只需要把echo $file修改为chmod 644 $file就可以了。

在read file的过程中遇到了一个小问题,就是读取的文件名中如果有空格那么就会截断为两个变量。通过检索,将环境变量IFS修改为$'\n'(换行)就能够让read变为逐行读取,解决这个问题。

整个脚本的代码展示如下:

# ChatGPT 说,这是一个称为 shebang 的特殊注释,用于指定脚本解释器的路径

# 如果该注释不存在或指定的路径不正确,则操作系统将尝试使用默认的解释器来执行脚本

# !/bin/bash

# 自定义路径,这里以 download 文件夹为例

# 实际上应该也可以直接修改为微信的缓存文件夹(可以通过右键点击微信内接收到的文件查看路径)

path="/Users/用户名/Downloads"

# 生成正则表达式,用于匹配文件

types=("doc" "docx" "ppt" "pptx" "xls" "xlsx")

re=""

for i in ${types[*]};do re="$re|$i$";done

re=${re:1}

# 修改环境变量,让后面的 read 能够逐行读取

IFS=$'\n'

# 监控添加文件的事件,将变动文件传递至下面的 chmod 命令

fswatch -e ".*" -EIi $re --event Created $path |

while read file;do

# 额外增加一个文件存在和不可写的判断,排除打开 Word 文档时产生的临时文件,避免报错

if [ -f $file ] && ! [ -w $file ];then

chmod 644 $file

fi

done

最后,将文件保存为wxpermfix.sh(名称可以自己选择,保存路径按照惯例,可以放在自己主目录下的bin目录,即~/bin);并在终端里用chmod命令赋予其执行权限:chmod +x ~/bin/wxpermfix.sh。

然后,就可以将它拖入终端中回车运行。

三、添加启动项文件:认识 launchd

问题和麻烦从此刻开始不断涌现。

在写完以上脚本后,我打算让脚本自己跑起来,并在开机自动启动,ChatGPT 推荐使用launchd工具。

亚马逊批量上传图片_美国亚马逊批量上传90003_批量数据上传业务意思

注意修改 Label 和 ProgramArguments 下 和 包围的内容即可

可在我模仿上面的文件修改完毕(实际上只需要复制文件夹内随便一个其他文件就可以)后,出现了各种问题,包括但不限于:

• 以为需要反复重启/登出用户来测试效果——实际上只需要launchctlunload卸载 plist 文件后launchctl load重新加载文件即可。

• 加载时告诉我没有足够的权限——修改脚本和 plist 文件的权限,比较奇怪的是,似乎 plist 文件权限修改为744是不可以的,必须得644。

• 放在什么位置——在 ChatGPT 提到的两个目录中,一开始我放在了/Library/LaunchDaemons,但那是系统级别的守护进程所在位置,放在那里会提示权限不足,实际上应该放在 ~/Library/LaunchAgent,以当前用户身份运行就行了。

• 通过launchd启动不生效,但在终端中启动就可以——原因是launchd启动的进程的环境变量 PATH 与交互式终端下不同,无法找到fswatch,解决方式是找到fswatch命令的绝对路径,放在脚本里。

亚马逊批量上传图片_美国亚马逊批量上传90003_批量数据上传业务意思

我早就把在脚本、plist 文件中使用的目录都设置为绝对路径,所以一直没有理解 ChatGPT 发出的有关要使用绝对路径的提示,直到这里我才意识到是 fswatch 要使用绝对路径

•chmod报错权限不足——一开始我听信了 ChatGPT 的说法,以为需要在脚本中加上sudo,可那就意味着每次都需要输入密码,这显然是不符合我自动运行脚本需求的。

亚马逊批量上传图片_批量数据上传业务意思_美国亚马逊批量上传90003

好在我最后在一个论坛里发现了解决方法,通过赋予 bash 完全磁盘访问权限(full disk access),可以让通过 launchctl 运行的脚本中的chmod命令有权限修改其他文件的权限。具体步骤还是可以问到:

美国亚马逊批量上传90003_批量数据上传业务意思_亚马逊批量上传图片

至此,我终于有了一个可以自动启动的,不断监控目标文件夹的脚本。让我在微信自己解决这个问题以前,免受只读文件之苦。

如后文所述,因为不太想设置自动启动,我自己最后没有用这套方案。但如果有人想要用这套方案,请参考下列步骤,并请特别注意各处权限设置,否则会无法生效:

1. 按照上面所示步骤赋予 bash 完全访问磁盘权限。

2. 进入~/Library/LaunchAgents文件夹,创建一个内容如后附的wxpermfix.plist文件(除扩展名外名称可以自定)。打开后参照上面 ChatGPT

试看结束,如继续查看请付费↓↓↓↓
打赏0.5元才能查看本内容,立即打赏

来源【首席数据官】,更多内容/合作请关注「辉声辉语」公众号,送10G营销资料!

版权声明:本文内容来源互联网整理,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 jkhui22@126.com举报,一经查实,本站将立刻删除。

相关推荐

评论

  • 昵称 (必填)
  • 邮箱
  • 网址
二维码
评论