ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

chmod +x 实战指南:解决Linux脚本执行权限问题

chmod +x 实战指南:解决Linux脚本执行权限问题 1. 先搞懂“执行权限”到底是个什么东西1.1 Linux文件权限的三类主体和三类权限很多刚接触Linux的朋友都会遇到这样一个场景辛辛苦苦写完一个脚本高高兴兴执行./deploy.sh结果终端冷冷地回了一句Permission denied。你心想这文件就在我眼前凭什么不行因为你只看到了文件没有看到它身上挂着的“门禁牌”。在Linux系统里每一个文件都带着一组权限标记用ls -l一看就明白了$ ls -l deploy.sh -rw-r--r-- 1 root root 342 Mar 20 10:32 deploy.sh这一串字符拆开来看是三段信息第一位的-表示这是一个普通文件目录则显示d软链接显示l后面紧接着的rw-、r--、r--就是权限核心。从左到右分别是文件属主user、属主所在组group、其他用户other各自的权限。r代表可读readw代表可写writex代表可执行execute减号就是没有对应权限。说人话就是系统对每一个文件都发了三张独立门禁卡文件主人拿一张同一组的人拿一张外人再拿一张。每张卡上盖了三个章分别决定你能不能读、能不能改、能不能执行。你之所以报Permission denied十有八九就是因为“执行”那个章根本就没盖。1.2 为什么脚本一定要加执行权限这里要理解一个关键点脚本本质上就是一个普通文本文件真正读懂并执行它的是Shell解释器比如bash。Windows下双击.bat就能跑是因为系统直接根据文件扩展名关联了执行程序而Linux不干这事它只认权限位——你有x权限系统才允许解释器去帮你跑它。那为什么bash deploy.sh不需要执行权限也能跑因为你调用的bash本身是一个可执行程序脚本只是被当作参数“读”进去的所以在/tmp/xxx这种场景下只要脚本有读权限就能用bash script.sh的方式去跑。但如果你想像正常命令一样直接输入路径执行也就是./deploy.sh这种写法系统会先检查这个文件是否有x权限没有就一律拒绝。理解了这层关系后面的所有命令、所有报错、所有“为什么我改了权限还没用”的疑问就都能串起来了。记住一个原则Linux下能不能执行一个文件人家只看权限位不看你文件名后缀叫不叫.sh。这就是为什么chmod x几乎是每个Linux使用者必备的肌肉记忆。2. chmod x 的完整用法与数字模式2.1 符号模式从 ux、gx 到 axchmod是change mode的缩写作用就是修改文件的权限标记。最简单的用法就是你问的这句chmod x deploy.sh这里的x是给文件加上执行权限。直接用x其实等价于ax也就是给“所有人”——属主user、属组group、其他用户other——都加上执行权限。这样写简单粗暴在个人机器上完全够用但它其实是有讲究的因为权限是可以精细化控制的。常用的符号模式有这几组命令含义适用场景chmod x file给所有主体加执行权限个人快速操作最常用chmod ux file只给文件属主加执行权限自己用的私有脚本chmod gx file给同组成员加执行权限团队协作的共享脚本chmod ox file给其他用户加执行权限开放给所有人执行chmod -x file移除执行权限防止误执行安全回收chmod urwx,gorx file精确设置多组权限需要符模式组合的场景很多人只记了x就完事了其实chmod的符号模式支持u、g、o、a四个主体支持、-、三种操作支持r、w、x三种权限。组合起来的表达能力非常强。比如chmod urwx,gor就是把属主设为可读可写可执行组和其他人只保留读权限一条命令搞定不用分两步走。2.2 数字模式755、700、644到底怎么算另一个常见写法是数字模式比如chmod 755 deploy.sh。这套规则背后的逻辑也很简单每个权限位对应一个权重值r是4w是2x是1没有权限就是0。把三个数字加起来就得到这一组权限的数值。拿755举例三个数字分别是7、5、5第一位7 421表示属主权限是rwx第二位5 401表示组权限是r-x第三位5 401表示其他人权限是r-x这样看就清晰了755对应的是“文件主人拥有全部权限其他人能读能执行但不能修改”这是Linux世界里最经典的脚本权限配置之一。同理700rwx------只有属主能读、写、执行750rwxr-x---属主全权限组成员可读可执行644rw-r--r--能读不能执行适合配置文件数字模式的优点在于可以一次设置所有权限位不会出现“我明明只想加执行权限结果不小心把读权限也弄没了”这种尴尬。缺点是需要心算不过这个口诀特别简单4读2写1执行三个数一拼就是一张完整的权限表。2.3 什么时候用755什么时候用700很多教程讲完命令就完了从来不告诉你什么场景该用哪个。这里分享我自己的经验如果这个脚本只是你自己在服务器上备份数据、清理日志用的私有工具那就用700不给任何人多余权限最安全。如果这个脚本是放在团队公共目录里、同事也要执行那就用755或750让同组的人能读能执行。如果是部署到生产环境、对外开放的服务脚本也要配合账号体系做最小化授权用755是常规操作。千万别遇到权限问题就chmod 777甩过去那是给所有用户包括黑客开的门我后面会专门说这个问题。记住一个原则权限的本质是“最小够用”多给一分都是风险。3. 从写脚本到跑通的完整实操3.1 一个亲测的部署脚本示例光讲概念太虚了我们直接走一遍完整流程。假设你写了一个简单的运维脚本用来检查磁盘占用并输出告警信息。先用vim创建文件vim /opt/scripts/check_disk.sh脚本内容我故意用最朴素的写法方便看清执行过程#!/bin/bash # 检查根分区使用率超过80%输出告警 usage$(df / | awk NR2 {print $5} | tr -d %) echo 根分区当前使用率${usage}% if [ $usage -gt 80 ]; then echo 磁盘空间不足请及时清理 else echo 磁盘空间充足。 fi注意脚本第一行#!/bin/bash这个叫shebang读作“谢帮”它的作用是告诉系统当你执行这个脚本时用哪个解释器来跑。写成#!/bin/bash就是用Bash写成#!/usr/bin/python3就是用Python 3。这行写错了脚本就会报command not found或者干脆执行得很诡异。3.2 加执行权限的完整步骤与验证脚本写完先看看当前的权限状态$ ls -l /opt/scripts/check_disk.sh -rw-r--r-- 1 root root 200 Mar 20 10:32 check_disk.sh-rw-r--r--意味着有读权限、有写权限但没有执行权限。这时如果你直接试$ /opt/scripts/check_disk.sh bash: /opt/scripts/check_disk.sh: Permission denied不出意外报错了。接下来给它加执行权限chmod x /opt/scripts/check_disk.sh然后再看一眼$ ls -l /opt/scripts/check_disk.sh -rwxr-xr-x 1 root root 200 Mar 20 10:32 check_disk.sh权限位变成了rwxr-xr-x三个x全亮说明此时任何有访问权限的用户都能执行这个脚本。再运行一次$ ./check_disk.sh 根分区当前使用率42% 磁盘空间充足。完美跑通。整个过程就三步写文件、加权限、执行。很多教科书把这讲得很玄乎其实在Linux世界里干活的节奏就是这样加个权限是比吃饭还频繁的基础操作。3.3 脚本执行的三种方式对比执行脚本其实不止./script.sh一种方式我强烈建议新手把下面这三种方式彻底搞明白因为面试和工作中都常会遇到执行方式命令示例是否需要x权限执行环境典型场景直接路径执行./check_disk.sh需要新开的子Shell最常用最正经的“执行脚本”解释器调用bash check_disk.sh不需要新开的子Shell调试脚本不关心权限位source执行source check_disk.sh不需要当前Shell需要脚本影响当前环境变量bash script.sh的机制是把脚本当作文本喂给Bash解释器解释器负责逐行执行所以只要脚本有读权限就行。source执行也称为“点执行”你还会看到. script.sh的等价写法它是在当前Shell进程里执行最大的威力是脚本里定义的变量、函数、cd操作会直接留在当前环境里。比如你想临时改环境变量用source执行完立刻生效而用./或bash执行完改动随着子Shell退出就丢掉了。有一点要注意./check_disk.sh这种写法里的./不是装饰它的意思是“在当前目录下找这个文件”。Linux默认不会在当前目录搜索可执行文件这是出于安全考虑防止你在一个目录里不小心执行了恶意文件所以直接敲check_disk.sh回车会报command not found只有写了./或者用绝对路径/opt/scripts/check_disk.sh才找得到。这个坑新手几乎人人踩过一次。4. 常见问题与排查技巧实录4.1 Permission denied 的四种典型原因加了chmod x还是Permission denied这种问题我见得太多了原因可能不止一个按出现频率排序如下权限确实没加上。加了后请用ls -l确认别凭感觉。文件系统挂载参数带了noexec。比如有些服务器对/tmp分区挂载时禁止执行任何程序你脚本放在/tmp下就算有x权限也跑不了。解决方法是把脚本移到/home、/opt等正常分区或者调整挂载参数需要root权限修改/etc/fstab后重新挂载。文件系统是Windows格式挂载的。比如你把Windows下编辑的脚本放到U盘或者NTFS分区里通过Linux访问时权限映射可能不完全生效。脚本文件的所有者不是你。如果你用的是其他用户对文件只有r--权限属主的x权限跟你没关系要请文件主人执行chown或chmod处理。排查Permission denied的顺序建议是先ls -l看权限位再df -h看挂载点最后用id看当前用户身份三步基本锁定问题。4.2 经典报错/bin/bash^M: bad interpreter如果你在Windows上写好脚本再用FTP、网盘或编辑器的某些方式传到Linux上执行时很可能看到这个诡异的报错-bash: ./check_disk.sh: /bin/bash^M: bad interpreter: No such file or directory这不是权限问题是换行符捣鬼。Windows的文本文件每行结尾是\r\nLinux只认\n结果那个\r显示为^M被解释器当成了路径的一部分于是它去找一个叫/bin/bash^M的解释器自然找不到。解决办法很简单用sed把多余的\r全部干掉sed -i s/\r$// check_disk.sh或者装个工具一条命令搞定dos2unix check_disk.sh这个坑几乎每个从Windows转过来的Linux新手都会遇到记住症状长什么样下次秒懂。4.3 加了x权限还是提示 command not found还有一种常见迷惑行为文件明明就在当前目录权限也加好了但执行时报command not found。原因多半是你没有加./。前面说了Linux的PATH环境变量里默认不包含当前目录直接输入check_disk.sh系统会在PATH里到处翻根本不会看你当前目录。正确姿势是./check_disk.sh如果你实在想省事也可以把脚本放进PATH里的目录比如/usr/local/bin然后直接敲文件名就能执行cp check_disk.sh /usr/local/bin/ chmod x /usr/local/bin/check_disk.sh check_disk.sh但我的建议是个人临时脚本就老老实实用./别往系统目录里塞不然时间久了满地都是脚本文件管理起来反而乱。4.4 关于 chmod 777 的最大误区每次看到有人在问答平台回复“权限不够就chmod 777”我血压就上来了。777意味着任何用户都能读、写、执行这个文件这对个人笔记本上的测试脚本影响不大但放在服务器上简直就是在门口挂一块“欢迎入侵”的牌子。比如你的脚本里如果有登录数据库的密码、有删除日志的rm -rf操作任何被提权的普通用户或者碰巧猜到路径的人都有机会执行或篡改它。正确做法是始终遵循最小权限原则自己一个人用的工具脚本700需要团队成员执行但不让他们改750或755配置文件、密钥文件600甚至400只有确实需要开放给所有人执行的公共命令才用755你可以用这组命令对比一下权限变化感受不同数字带来的差异chmod 700 check_disk.sh ls -l check_disk.sh chmod 750 check_disk.sh ls -l check_disk.sh chmod 755 check_disk.sh ls -l check_disk.sh每次执行后观察权限位的差异比死记硬背数字有效得多。4.5 批量处理和目录权限的小技巧如果有一堆脚本都要加执行权限不用一个一个来。比如当前目录下所有.sh文件批量加chmod x *.sh递归目录处理chmod -R x /opt/scripts/但这里要提醒一个反向坑chmod -R x会把目录本身的执行权限也改了而目录的x权限含义不同——它表示“能否进入该目录”和“能否遍历该目录”。如果你给一个目录去了执行权限别人连cd进去都不行哪怕里面的文件设得再开放也白搭。所以对目录和文件要分开想清楚目的再操作。另外如果你要修改的是目录的进入权限一般设为755或700。这也是为什么你把脚本放在/root下别人即使知道路径也进不去因为/root目录默认就是700这个设计本身就是在保护你。最后分享一个我个人的习惯写完脚本的第一件事先chmod x然后立刻跑一遍再顺手打开ShellCheck一个脚本静态检查工具看看有没有明显的语法警告。这套流程看起来简单但能省掉后面所有的排错时间。我在实际使用中发现很多所谓“脚本跑不了”的求助帖散开来看基本都是权限、换行符、路径这三个问题学会了今天这些排查方法大部分场景你都能自己搞定。
返回列表