如何为所有.sh脚本自动设置执行权限?(macOS环境)
针对.sh文件自动添加执行权限的解决方案
UMASK本身没法按文件扩展名设置权限——它只负责控制文件/目录创建时的基础权限掩码,完全不识别文件名后缀。针对你每次手动敲chmod u+x的麻烦,在macOS的zsh环境下,有几个实用的解决办法:
方案一:覆盖常用编辑/创建命令(即时生效,适合日常操作)
通过自定义zsh函数替换vim、touch这类常用工具,当你创建或编辑.sh结尾的文件时,自动加上所有者执行权限。
把下面的代码追加到你的~/.zshrc里:
# 自定义vim命令,编辑.sh文件后自动加执行权限 vim() { command vim "$@" local exit_status=$? for file in "$@"; do if [[ -f "$file" && "$file" == *.sh ]]; then chmod u+x "$file" fi done return $exit_status } # 自定义touch命令,创建.sh文件时直接赋予执行权限 touch() { command touch "$@" local exit_status=$? for file in "$@"; do if [[ "$file" == *.sh ]]; then chmod u+x "$file" fi done return $exit_status }
保存后执行source ~/.zshrc让设置生效,之后用vim写脚本或者touch创建空.sh文件时,权限会自动设置好。
方案二:后台全局监听文件创建(全目录生效)
如果需要让所有目录下新创建的.sh文件自动获得执行权限,可以用fswatch(macOS的文件变化监听工具)配合后台服务实现:
- 用Homebrew安装fswatch:
brew install fswatch
- 创建监听脚本
~/scripts/watch_sh_perms.sh,内容如下:
#!/usr/bin/env zsh # 监听根目录下的文件创建事件,可把/改成你需要的特定目录(比如~/work) fswatch -0 -r / | while read -d $'\0' file_path; do if [[ -f "$file_path" && "$file_path" == *.sh && ! -x "$file_path" ]]; then chmod u+x "$file_path" fi done
- 给脚本加执行权限:
chmod u+x ~/scripts/watch_sh_perms.sh
- 创建launchd配置文件
~/Library/LaunchAgents/com.user.watchshperms.plist,让脚本开机自动后台运行:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.user.watchshperms</string> <key>ProgramArguments</key> <array> <string>/Users/你的用户名/scripts/watch_sh_perms.sh</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/tmp/watch_sh_perms.log</string> <key>StandardErrorPath</key> <string>/tmp/watch_sh_perms.err</string> </dict> </plist>
记得把/Users/你的用户名替换成你实际的用户目录。
- 加载这个launchd服务:
launchctl load ~/Library/LaunchAgents/com.user.watchshperms.plist
之后不管你在哪个目录创建.sh文件,权限都会自动设置好,重启后服务也会自动启动。
内容的提问来源于stack exchange,提问作者todd_dsm
相关产品推荐
相关产品推荐

