☰
claude 默认授权启动,读写git权限
2026/10/14 4:08:37 网站建设 项目流程

目标:仅当前工作目录读写,不允许碰系统/外部目录;普通用户运行,不用 sudo,避开--dangerously‑skip‑permissionsroot 报错

核心:不要 sudo,进入你的项目目录,创建项目本地配置.claude/settings.local.json(加入.gitignore,不提交版本库)

1、在你的项目目录创建配置

mkdir-p.claudevim.claude/settings.local.json

写入下面配置:

{"permissions":{"defaultMode":"acceptEdits","allow":["Read","Write","Glob","Grep"],"deny":["Bash(sudo *)","Bash(rm -rf / *)","Bash(curl *)","Bash(wget *)"],"additionalDirectories":[]},"sandbox":{"enabled":true,"filesystem":{"allowWrite":["./"],"denyRead":["//etc","//usr","//home/*/.ssh","//root","~/.*"]}}}
  • defaultMode: acceptEdits:当前目录内文件读写自动放行,不再弹窗确认;shell 命令依然需要你确认
  • additionalDirectories: []:禁止访问任何项目外目录
  • sandbox.filesystem.allowWrite: ["./"]:OS 沙盒强制只允许写入当前目录,子进程也遵守该限制
  • denyRead:禁止读取系统目录、ssh密钥等敏感路径

⚠️不能加 sudo 运行 claude,保持普通用户账号执行:

# 正确:进入项目目录,普通用户启动cd/your/project claude

2、会话内快速切换(不用改配置文件)

进入 claude 交互终端后输入:

/permissions

菜单选择:acceptEdits(接受编辑),效果:本会话内当前目录读写自动放行,shell命令仍询问。

3、如果你需要非交互脚本运行(无终端交互)

不能用--dangerously‑skip‑permissions,改用--permission-mode acceptEdits

claude --permission-mode acceptEdits-p"你的任务描述"

限制:Bash shell 命令依然会阻塞等待确认,非交互脚本如果有 shell,会卡住。如果脚本需要自动跑 shell,要在allow白名单显式添加允许的 bash 模式,例如"Bash(git *)"。

4、关键限制回顾

  1. --dangerously‑skip‑permissions只要检测到 effective uid=0(root/sudo),直接硬报错,无解,官方安全锁死,不能绕过。
  2. acceptEdits≠ dangerously‑skip‑permissions:
    • ✅ acceptEdits:文件读写自动放行;shell命令仍然弹窗确认;沙盒目录限制生效
    • ❌ dangerously‑skip‑permissions:文件+shell全部跳过确认,且禁止root下使用

5、如果你必须执行 shell 也自动放行(风险上升)

在allow增加 bash 通配,仅允许安全命令,禁止危险命令:

"allow":["Read","Write","Glob","Grep","Bash(git *)","Bash(npm *)","Bash(pytest *)"]

排错

  • 如果 claude 还试图访问外面文件:确认运行时 CWD 是你的项目目录,不要在$HOME根目录运行。
  • 检查配置是否生效:
claude debug settings

会打印合并后的完整权限配置,确认 sandbox、permissions 读取的是你项目下.claude/settings.local.json。

完整配置(当前目录读写 + Git权限)

.claude/settings.local.json,务必加入.gitignore,普通用户运行 claude,不要 sudo。

两种方案:

方案A(推荐,安全优先)

常用git操作自动放行;push / merge / push‑force仍然弹窗确认,防止误推送代码到远程仓库。

{"permissions":{"defaultMode":"acceptEdits","allow":["Read","Write","Glob","Grep","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git add *)","Bash(git commit *)","Bash(git stash *)","Bash(git branch *)","Bash(git checkout *)"],"ask":["Bash(git push *)","Bash(git merge *)","Bash(git rebase *)"],"deny":["Bash(git push --force *)","Bash(sudo *)","Bash(rm -rf *)","Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)"],"additionalDirectories":[]},"sandbox":{"enabled":true,"filesystem":{"allowWrite":["./"],"denyRead":["//etc","//usr","//home/*/.ssh","//root","~/.*"]}}}

方案B(宽松,全部git自动放行)

⚠️风险:claude可以直接执行git push,不会弹窗确认。

{"permissions":{"defaultMode":"acceptEdits","allow":["Read","Write","Glob","Grep","Bash(git *)"],"deny":["Bash(git push --force *)","Bash(sudo *)","Bash(rm -rf *)","Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)"],"additionalDirectories":[]},"sandbox":{"enabled":true,"filesystem":{"allowWrite":["./"],"denyRead":["//etc","//usr","//home/*/.ssh","//root","~/.*"]}}}

关键要点

  1. defaultMode: acceptEdits:当前目录文件读写自动放行,shell命令看allow/ask/deny规则,不等于--dangerously‑skip‑permissions。
  2. 规则优先级:deny>ask>allow> defaultMode,命中即停止匹配。
  3. sandbox强制限定只允许写入当前目录,claude无法读写项目外路径。
  4. 禁止sudo运行claude,否则--dangerously‑skip‑permissions直接报错,这套配置不需要该参数。

验证配置是否生效

进入claude交互终端执行:

/config

会打印合并后的完整权限规则,确认你的git规则被加载。

命令行临时一次性会话(不写配置文件)

claude --permission-mode acceptEdits--allowedTools"Read,Write,Glob,Grep,Bash(git *)"

仅本次会话生效,退出失效。

.claude/settings.local.json是项目本地配置文件;想要等价效果全部放到命令行参数,claude CLI 通过--allowed-tools、--asked-tools、--denied-tools、--permission-mode实现。
注意:sandbox 文件系统限制目前没有命令行参数,只能靠配置文件,命令行只能控制 permissions 工具权限。

对应你这份 JSON 的完整命令行

claude\--permission-mode acceptEdits\--allowed-tools"Read,Write,Glob,Grep,Bash(git status *),Bash(git diff *),Bash(git log *),Bash(git add *),Bash(git commit *),Bash(git stash *),Bash(git branch *),Bash(git checkout *)"\--asked-tools"Bash(git push *),Bash(git merge *),Bash(git rebase *)"\--denied-tools"Bash(git push --force *),Bash(sudo *),Bash(rm -rf *),Bash(curl *),Bash(wget *),Read(.env),Read(.env.*)"

重要限制

  1. sandbox 块(allowWrite/denyRead)没有 CLI 参数
    命令行无法复现「只允许写当前目录、禁止读/etc、.ssh」这部分,必须依赖.claude/settings.local.json文件。
    👉 如果你只跑上面这条命令,claude 依然可以读取项目外文件,少了沙盒隔离。

  2. additionalDirectories: []同样无命令行参数,配置文件专属。

  3. 不要加sudo,不要加--dangerously-skip-permissions。

简短封装成别名(放到 ~/.bashrc / ~/.zshrc)

aliasclaude-proj='claude \ --permission-mode acceptEdits \ --allowed-tools "Read,Write,Glob,Grep,Bash(git status *),Bash(git diff *),Bash(git log *),Bash(git add *),Bash(git commit *),Bash(git stash *),Bash(git branch *),Bash(git checkout *)" \ --asked-tools "Bash(git push *),Bash(git merge *),Bash(git rebase *)" \ --denied-tools "Bash(git push --force *),Bash(sudo *),Bash(rm -rf *),Bash(curl *),Bash(wget *),Read(.env),Read(.env.*)"'

source 之后直接:

claude-proj

最佳实践建议

  • 权限工具白名单(allow/ask/deny):用命令行/别名,方便临时切换;
  • 目录沙盒隔离(sandbox.filesystem):保留项目目录下.claude/settings.local.json,命令行做不到。

调试查看最终生效工具列表:

claude debug tools

如果你要做非交互一次性任务(-p 传入prompt):

claude --permission-mode acceptEdits\--allowed-tools"Read,Write,Glob,Grep,Bash(git status *),Bash(git diff *),Bash(git log *),Bash(git add *),Bash(git commit *),Bash(git stash *),Bash(git branch *),Bash(git checkout *)"\--asked-tools"Bash(git push *),Bash(git merge *),Bash(git rebase *)"\--denied-tools"Bash(git push --force *),Bash(sudo *),Bash(rm -rf *),Bash(curl *),Bash(wget *),Read(.env),Read(.env.*)"\-p"你的任务"

⚠️ 非交互模式下命中--asked-tools(例如 git push)会阻塞等待输入,脚本场景避开会触发 ask 的操作。
用jq一行命令直接生成/覆盖.claude/settings.local.json,输出完整你上面那套 JSON,单条 shell 语句,直接写入文件。

cat
mkdir-p.claude&&cat>.claude/settings.local.json<<'EOF' { "permissions": { "defaultMode": "acceptEdits", "allow": ["Read","Write","Glob","Grep","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git add *)","Bash(git commit *)","Bash(git stash *)","Bash(git branch *)","Bash(git checkout *)"], "ask": ["Bash(git push *)","Bash(git merge *)","Bash(git rebase *)"], "deny": ["Bash(git push --force *)","Bash(sudo *)","Bash(rm -rf *)","Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)"], "additionalDirectories": [] }, "sandbox": { "enabled": true, "filesystem": { "allowWrite": ["./"], "denyRead": ["//etc","//usr","//home/*/.ssh","//root","~/.*"] } } } EOF

或者需要先安装 jq:apt install jq/brew install jq

mkdir-p.claude&&jq-n'{ "permissions": { "defaultMode": "acceptEdits", "allow": ["Read","Write","Glob","Grep","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git add *)","Bash(git commit *)","Bash(git stash *)","Bash(git branch *)","Bash(git checkout *)"], "ask": ["Bash(git push *)","Bash(git merge *)","Bash(git rebase *)"], "deny": ["Bash(git push --force *)","Bash(sudo *)","Bash(rm -rf *)","Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)"], "additionalDirectories": [] }, "sandbox": { "enabled": true, "filesystem": { "allowWrite": ["./"], "denyRead": ["//etc","//usr","//home/*/.ssh","//root","~/.*"] } } }'>.claude/settings.local.json

执行完直接落地文件,无需手动编辑。

校验是否写对

cat.claude/settings.local.json

如果想追加到 .gitignore(一并一行)

echo".claude/settings.local.json">>.gitignore

如果你是想修改已有json,而不是覆盖

覆盖是上面;如果已有 settings.local.json,只想更新权限字段,用这个(不会清空其他已有key)

mkdir-p.claude&&jq'. |= ( .permissions.defaultMode = "acceptEdits" | .permissions.allow = ["Read","Write","Glob","Grep","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git add *)","Bash(git commit *)","Bash(git stash *)","Bash(git branch *)","Bash(git checkout *)"] | .permissions.ask = ["Bash(git push *)","Bash(git merge *)","Bash(git rebase *)"] | .permissions.deny = ["Bash(git push --force *)","Bash(sudo *)","Bash(rm -rf *)","Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)"] | .permissions.additionalDirectories = [] | .sandbox.enabled = true | .sandbox.filesystem.allowWrite = ["./"] | .sandbox.filesystem.denyRead = ["//etc","//usr","//home/*/.ssh","//root","~/.*"] )'.claude/settings.local.json>.claude/settings.local.json.tmp&&mv.claude/settings.local.json.tmp .claude/settings.local.json

第一条是新建/完整覆盖,绝大多数场景用第一条就够。

mkdir -p .claude

  • -p参数核心行为:
    1. 如果.claude目录不存在 → 创建它
    2. 如果.claude已经存在 → 不报错、不覆盖、不改动原有内容,直接静默成功

mkdir本身永远不会覆盖文件/目录,-p只是防止“目录已存在”抛出错误。

对比
mkdir.claude# 目录已存在:报错 mkdir: cannot create directory ‘.claude’: File existsmkdir-p.claude# 目录已存在:啥也不干,返回0;不存在就新建

真正会覆盖的是后面的> .claude/settings.local.json

jq-n'{...}'>.claude/settings.local.json

>是输出重定向:如果文件已存在,直接清空覆盖原有内容;这才是覆盖点,不是mkdir‑p。

如果你不想覆盖旧配置,想合并更新,就要用我上一条给的 tmp 文件方式,不能直接>。

完整拆解整条命令

mkdir-p.claude&&jq-n'{ ... }'>.claude/settings.local.json
  1. mkdir -p .claude:确保目录一定存在,存在就跳过;
  2. &&:前面成功才执行后面;
  3. jq -n:生成全新 json;
  4. > .claude/settings.local.json:覆盖写入该文件,旧内容全部丢失。

小坑提醒

  • .claude是目录;settings.local.json是目录里面的文件。
  • 万一你错误提前创建了一个名叫.claude的普通文件(不是文件夹),mkdir -p .claude会报错,这是异常情况。

安全变体:不直接覆盖,先备份旧文件

mkdir-p.claude&&[-f.claude/settings.local.json]&&cp.claude/settings.local.json .claude/settings.local.json.bak&&jq-n'{...}'>.claude/settings.local.json

检测旧配置存在就自动备份一份.bak,再写入新配置。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询