尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Shell脚本从入门到实战:变量、循环、后台执行与ADB调试

Shell脚本从入门到实战:变量、循环、后台执行与ADB调试 Shell 这东西说实话刚开始接触的人容易把它想得特别简单觉得不就是个黑乎乎的终端窗口敲几个命令嘛。但真正用起来你会发现它是整个 Linux 生态里最抗造、最省命的一块基石也是让你从“只会点鼠标”走向“能用一句话让电脑干一堆活”的分水岭。这篇东西不打算写成那种能查到但读不下去的官方文档而是想以我这些年拿 Shell 干活、踩坑、再爬起来的过程为底子把命令行、脚本、变量、循环、后台任务、ADB 调试这些高频场景一次讲透。先说清楚它解决什么Shell 本质是个命令解释器但你这个解释器四舍五入就是操作系统给你的一个遥控器。你自己写的一串命令组合在一起就可以把文件处理、日志分析、软件部署这种重复劳动变成一行脚本几秒钟跑完。无论你是刚入门想搞懂变量和循环的运维新手还是做测试经常要 adb shell 操作手机又或者想写点小工具解放双手的普通开发这篇内容都是按实战顺序给你排好的。1. Shell 是什么学它到底能解决什么问题1.1 一个命令解释器更是一把胶水很多人把 Shell 和终端混为一谈其实严格区分一下会更好理解终端是你看到的那块窗口Shell 是窗口背后真正去执行命令的翻译官。你敲下ls -lShell 会把这个字符串拆开、找到对应的可执行文件、把参数传进去再把结果回给你。这个过程听起来平平无奇但真正的价值在于它允许你把多个命令用管道、重定向、逻辑判断接起来形成流水线。举个例子我想找出当前目录下最大或者最占空间的三个文件。一条命令就够了du -ah . | sort -rh | head -3。这里du负责统计大小sort负责排序head负责截取前几行中间用竖线把数据从上一个命令嘴里直接灌给下一个命令。这种“每个小工具只干一件事但组合起来能干大事”的思路就是 Shell 作为胶水语言的最大魅力。你不需要写一个 500 行的 Python 程序去处理临时任务Shell 一行就搞定了。所以我一直觉得Shell 不是一个需要“精通”的编程语言它更像一个工具箱。你每多掌握一个命令或者一个语法就等于往工具箱里多放了一把趁手的家伙拿出来就能用。1.2 什么人最需要学 Shell顺着这个思路往下说学 Shell 最迫切的需求者大概分这几类你大概率是其中之一运维和系统管理员服务器批量部署配置、日志切割、定时任务全是 Shell 的天下。不会 Shell 基本没法独立维护一台 Linux 服务器。开发工程师本地构建、环境变量、git 钩子、容器里的启动命令哪怕你平时写的是 Java/Python/Go一旦进了服务器绕不开 Shell。测试工程师用adb shell操作 Android 设备、自动抓日志、自动跑稳定性测试这些脚本十有八九是用 Shell 拼出来的。普通办公族每天要把几十个文件改名、把表格导出成 CSV 再合并或者定期备份文件夹这些用 Shell 写个小脚本能省下大量时间。1.3 从热搜词里看大家到底在问什么每次我看这类热搜词的实时榜单其实就是在看大家究竟在哪个环节卡住了。比如shell脚本for循环、linux的shell脚本变量与输入、grep在shell脚本中的常见用法这几个词暴露的是一个典型路径已经会敲单个命令了但一旦要把多个命令揉进一个脚本里就遇到了变量作用域、循环写法、条件判断这些编程基础问题。再比如shell脚本要在后台执行还要交互式输入密码这个场景就更真实了脚本本身要跑很久你想放到后台去可它中途又要输密码、要交互两边打架不知道怎么处理。还有adb shell uiautomator dump 用不了这是在移动端调试的时候遇到的具体报错。这些热搜词合在一起几乎就是一枚新手从零爬到能独立写自动化脚本的地图。这章我先把地图给你铺开后面几节照着走就行。2. 从零开始的第一课环境、常用命令与第一个脚本2.1 环境准备Linux、macOS、Windows WSL 与 Android 调试桥学 Shell 的第一步不是背语法是先把能敲命令的环境搭好。要是你手头是 Linux 服务器或者 macOS 电脑直接打开终端就能干不用装任何东西。要是你用的是 Windows我不太建议你在 cmd 或者 PowerShell 里硬学因为命令和语法体系不完全一致学完容易乱。更推荐装一个 WSLWindows Subsystem for Linux把 Ubuntu 之类的发行版跑起来那样你得到的就是一个标准的 Linux 环境。这里有个容易犯迷糊的地方你可能会搜到“Windows 也有 PowerShell”“Windows 也能跑 shell”之类的说法。PowerShell 确实是一门功能很强的脚本语言但它不是这里的核心类 Unix 的 Bash 才是绝大多数教程里的默认 Shell。为了少走弯路先在 Linux 环境里把 Bash 玩明白其他的之后再接触也不迟。另外如果你做 Android 开发或者测试还需要准备好adb工具把它加到 PATH 里确保终端里直接敲adb devices能看到设备。后面第五部分会专门讲adb shell的实战现在你只需要知道这玩意儿是通往手机内部系统的另一个 Shell 入口。2.2 先掌握这几条高频命令cd、echo 与环境变量我不打算把ls、cp、mv这些最基础的命令从零讲起网上一搜一大把我重点说说那些看着简单但其实藏了不少细节的cd命令。它是切换目录用的但它有几个特殊用法值得记一下cd -返回上一次所在的目录cd ~回到当前用户的家目录cd ../..往上跳两级。在脚本里我还常用cd $(dirname $0)这句它的作用是把当前工作目录切到脚本自身所在的目录。为什么非要用它因为脚本被调用时当前目录不一定是你脚本存放的位置如果你在脚本里写相对路径很可能找错文件。echo命令很多人只拿它打印字符串但它对转义和变量的处理很容易踩坑。比如echo $HOME会打印家目录但echo $HOME就只会原样打印$HOME四个字符因为单引号会关掉变量展开。再比如你写echo -e a\tb-e 参数让\t被解析成制表符这在生成 CSV 之类的文件时特别好用。环境变量这个概念也不复杂它就是一组全局的键值对。你用export MY_VARhello设置之后当前 Shell 以及它启动的子进程都能读取到$MY_VAR。有一个最常见的坑变量赋值时等号两边不能有空格。你写MY_VAR helloShell 会认为要执行一个叫MY_VAR的命令然后给你报command not found。这个细节我不知道见过多少人摔过包括我自己。2.3 写出第一个可执行脚本环境有了命令也懂几条了接下来就是让脚本跑起来。第一步新建一个文件比如first.sh用你喜欢的编辑器写入#!/bin/bash # 这是一个注释 echo 当前目录: $(pwd) echo 当前用户: $USER echo 今天日期: $(date %Y-%m-%d)第一行#!/bin/bash叫 shebang它的意思是告诉系统这个脚本要用 Bash 解释器来执行。第二步给文件加可执行权限chmod x first.sh。第三步运行它注意这里要写成./first.sh前面的./表示在当前目录查找文件因为默认情况下 Shell 不会在当前目录搜索可执行文件这是出于安全考虑。如果你觉得每次都要chmod x很麻烦也可以退一步直接用bash first.sh来执行这样不要求文件有可执行权限完全看个人习惯。但我还是建议养成加权限的习惯因为写出来的脚本最终是要给别人在服务器上直接跑的依赖解释器名不如依赖 shebang 更稳定。2.4 变量和输入脚本从“死”变“活”的关键脚本真正开始有用一定是从支持变量和输入开始的。变量这块我建议你用三条规则给自己立个门槛变量名要用字母或下划线开头别用数字开头。引用变量时最好加花括号比如${var}尤其是在变量后面还要接字符串的情况下像${var}_backup不加花括号会被解析成var_backup。变量默认都是字符串别指望 Shell 帮你做算术运算想计算得用$(( ))比如echo $((12))。然后是输入。脚本里最常用的输入来源有三种位置参数、read 命令、命令替换。位置参数就是跟在脚本后面的那些值。假设你执行./backup.sh /data /backup那么脚本里$1就是/data$2就是/backup$#是参数个数$是所有参数的列表。处理多个参数时shift命令非常有用它能把参数整体左移一位原本的$2变成$1$3变成$2。这样你就可以用循环逐个消费参数写出来的脚本更像一个正经工具而不是一个写死的命令。read命令则是让脚本停下来等用户输入。写法很简单read -p 请输入你的名字: name echo 你好$name-p用来显示提示文字后面的name是接收输入的变量名。如果你不想在输入内容里允许反斜杠转义还可以加-r参数。这是个安全习惯处理用户输入时都会用到。3. 循环、文本处理与批量重命名脚本的硬功夫3.1 for 循环的三种常见写法循环是脚本编程里出镜率最高的语法而for循环的写法又最容易让人懵因为不同写法长得完全不像。我直接把三种常用的写法整理成表格方便对照写法示例适用场景列表循环for i in a b c; do echo $i; done遍历明确给出的列表序列生成for i in {1..10}; do echo $i; done固定范围的数字C 风格for ((i0; i10; i)); do echo $i; done需要复杂变量调整时用哪一种是看场景的但我的偏好是批量处理文件名时用列表循环例如for f in *.txt; do echo $f; done需要跑固定次数时用序列生成需要在循环体内修改循环变量时用 C 风格。这里必须提醒一个细节列表循环里*.txt这类通配符如果匹配不到任何文件它会原样保留*.txt这个字符串导致脚本把不存在的文件当真。稳妥做法是在循环开头判断一下for f in *.txt; do [ -e $f ] || continue; ...; done。3.2 shift处理命令行参数的一把好手单独把shift拎出来说是因为它在搜索引擎里出现的频率真心不低但很多初学者不知道它在干嘛。它的逻辑特别简单每执行一次shift所有的位置参数向左平移一位$1变成原来的$2$2变成原来的$3原来的$1就没了。如果执行shift 2就是一次平移两位。最常见的用法是在脚本里做选项解析。比如你希望脚本支持./run.sh -n 5 -v这种形式-n后面跟一个数字-v是开关。这时候可以写个while循环加case来处理while [ $# -gt 0 ]; do case $1 in -n) count$2; shift 2 ;; -v) verbose1; shift ;; *) echo 未知选项: $1; exit 1 ;; esac done这么做的好处是不管参数顺序怎么变脚本都能正确解析。处理完的剩余参数继续留在$里方便后续使用。很多弹跳脚本、部署脚本里你都会看到这种模式属于必须掌握的套路。3.3 grep 在脚本里的正确用法grep在命令行里和在脚本里用法其实不太一样。命令行里你可能希望过滤日志时顺便带上高亮颜色、行号但在脚本里你往往只想知道一件事“有没有匹配到”这时候grep -q是首选因为它会自动静默不输出任何内容只通过退出码告诉你结果if grep -q ERROR /var/log/app.log; then echo 日志里发现 ERROR else echo 一切正常 fi这个-q是我见过最实用的参数没有之一。其次常用的是-E它允许你用扩展正则表达式比如grep -E ^[0-9]{3}- file.txt匹配以三位数字加横杠开头的行。再就是-A和-Bgrep -A 2 关键词 file会把匹配行的后两行也带出来。写脚本时如果你需要频繁用某个匹配结果我建议用命令替换把结果存到变量里而不是反复执行 grep省下来的时间在跑大日志时非常可观。3.4 批量重命名文件摆脱鼠标的第一个理由“Linux 用 Shell 重命名文件”这个搜索词背后的真实场景八成是要给一批图片加前缀、给一批.txt文件改扩展名或者把一批2023-01-01.log改成20230101.log。手动逐个右键重命名二三十个还凑合几百个就得崩溃了。这时候循环加字符串处理一出手问题直接消失。最简单的场景——给所有当前目录的图片加前缀for f in *.jpg; do mv $f photo_$f done复杂一点的场景——把文件名里的日期格式从2023-01-01改成20230101。这里可以用sed加变量替换newname$(echo $f | sed s/-//g)然后再mv。如果想要一个现成的批量工具用rename命令会更省事# 把扩展名 .htm 改成 .html rename s/\.htm$/\.html/ *.htm这里最要命的一个细节是文件名千万要加引号。如果文件名里有空格不加引号的话mv会把一整句话拆成好几个参数命令直接执行失败。我当初在这上面吃过不少亏现在写任何涉及变量的路径都会习惯性加上双引号这个习惯能替你挡掉一半以上莫名其妙的报错。4. 后台执行与交互式输入从脚本到稳定运行4.1 让脚本在后台跑、nohup 与日志后台执行大概是每个从“跑通脚本”迈向“部署脚本”的人都会遇到的第一道坎。你以为脚本运行几秒就结束了结果它可能要跑半小时而你又不想一直占着终端。最简单的后台运行方式就是在命令最后加一个./long_task.sh 加了之后命令会在子 Shell 里后台运行终端会立刻返回给你。但这里有个坑如果你直接关掉终端这个后台进程有很大几率会被挂掉因为终端退出时会向进程发送挂断信号。解决办法是用nohupnohup ./long_task.sh run.log 21 这句话拆分一下nohup让进程忽略挂断信号把标准输出导入到run.log21表示把标准错误也合并到同一个文件里不然你看到的只有正确输出报错信息却在终端上随关随没末尾的让它后台运行。这个组合是生产环境里最稳的姿势四个元素缺一个都不保险。4.2 脚本里要交互式输入密码怎么办比后台跑更麻烦的是脚本运行到一半要停下来等你输密码。比如你写了个自动备份脚本里面要ssh到远程服务器而远程服务器需要密码认证。你要是直接后台跑密码就会一直等在那里没人输入脚本看起来就像卡死了。处理这个问题思路分两派。第一派是不交互优先考虑能不能用免密登录的方式比如配置 SSH 密钥这样压根不需要密码。我不太建议在脚本里明文写密码除非你明确知道风险、而且只是在内网临时用。第二派是自动化交互如果密码场景确实绕不开比如你是为了调试方便那就用expect来“装成一个真人”去回答密码提示。4.3 expect 自动化交互的基础写法expect是一个专门用来做交互自动化的小工具它的逻辑是“等待某个输出然后发送某个输入”。它的名字起得特别好它就是在“等”expect一个东西出现等到了就回一句话。一个最小可用的例子长这样#!/usr/bin/expect set timeout 10 spawn ssh user192.168.1.100 expect password: send MyPassWord123\r interactspawn启动一个外部命令这里是 ssh。expect password:表示等待输出中出现password:字样。send把你要输入的密码发出去注意结尾的\r是回车键。interact表示完成登录后把控制权交还给用户这时候你怎么操作都行。这套写法还能扩展比如超时时间可以配我可以处理掉第一次登录时的 “yes/no” 指纹确认问题。比如expect { yes/no { send yes\r; exp_continue } password: { send $password\r } }exp_continue的意思是“遇到这个情形处理完之后继续等待下一个期待的输出”非常实用。4.4 后台任务与交互输入结合时的小坑把这节连起来看最典型的组合场景就是一个脚本要在后台执行执行过程中还要交互式输入密码。很多人卡住是因为没理清楚后台和交互本质上是冲突的后台任务不需要人管而交互任务需要人参与。你非要同时干就相当于一边想看电影一边让电影等你选座最后两头都别扭。我的经验是先写一个expect脚本比如do_login.exp它专门负责处理所有交互把密码通过参数或者环境变量传进去然后把这个 expect 脚本本身扔到后台去跑。换句话说真正后台运行的应当是“已经包装好交互逻辑的自动化脚本”而不是裸的原始命令。这样既拿到了后台运行的好处又不会卡在密码输入上。另外后台任务跑完之后怎么知道它成没成我建议脚本里主动把退出码写进日志./task.sh run.log 21 echo exit code: $? run.log$?是上一条命令的退出状态0 表示成功非 0 表示出错。这个值在一步一步排查脚本问题时是判断故障位置的第一个灯塔。5. ADB Shell 实战移动端调试的常用命令5.1 adb shell 和 Linux Shell 是什么关系不少初学者搜adb shell的时候会疑惑这不是手机工具吗和前面说的 Shell 是同一个东西吗答案是adb shell本质上是把 Android 设备的控制台通过 USB 或者无线调试接回到你电脑上让你在电脑终端里直接敲 Android 系统底层的 Shell 命令。Android 系统底层也是 Linux 内核所以ls、ps、cat、grep这些命令在adb shell里全都适用语法和你在服务器上用的完全一致。有一点要注意Android 设备里的 Shell 环境跟完整版 Linux 还是有差别的它精简了很多命令且su权限超级用户权限能不能拿到直接决定了你能跑哪些命令。没有 root 的设备很多读系统文件、改系统配置的命令都会权限不足而纷纷报错。所以我的建议是先分清楚哪些命令不需要 root 也能用哪些必须依赖 root然后按需测试。这样就算命令报错你也不至于一头雾水。5.2 高频 ADB Shell 命令wm、locksettings、uiautomator dump在移动端调试这一块有几个命令几乎是天天要用到的我把它们和用途列成表格参考命令典型用途adb shell wm size查看或修改屏幕分辨率adb shell wm density查看或修改屏幕密度dpi常用于适配测试adb shell vm查看虚拟内存统计信息判断设备内存压力adb shell locksettings set-disabled true尝试禁用锁屏密码adb shell uiautomator dump导出当前界面的 UI 层级 XML自动化测试常用先说说锁屏那个命令adb shell locksettings set-disabled true它看着挺美好一执行就能把锁屏密码干掉省得每次测到一半设备锁屏、自动化脚本中断。但现实情况是这个命令在绝大多数设备上直接执行会提示权限不足因为 locksettings 服务需要系统级权限。我在测试机上反复试过只有具备 root 权限的设备能用它普通手机和平板建议别抱太大期望。想在自动化里绕过锁屏更常见的套路反而是唤醒设备加滑动解锁或者直接改系统的锁屏超时设置。adb shell wm size是真正值得掌握的它不仅能看分辨率还能临时改分辨率比如adb shell wm size 1080x1920。改完不影响系统真实参数重启之后会自动恢复非常适合做多分辨率适配测试。adb shell vm虽然热度不高但当你需要快速判断设备是不是内存吃紧时看它输出的内存统计比一个个猜强得多。5.3 uiautomator dump 用不了的常见原因uiautomator dump是 UI 自动化测试人员的常用工具它的作用是把当前界面的控件树、坐标信息导成一个 XML 文件方便后续用脚本读取和操作。它出问题的概率相当高最常见的表现是执行完没有任何输出或者报错提示 “ERROR: could not get idle state” 之类。结合我自己的排查经验原因基本集中在这么几个方向现象常见原因解决办法命令提示成功但找不到 dump 文件权限不足或默认路径写入失败指定输出路径如adb shell uiautomator dump /sdcard/ui.xml报错 idle state界面还在动画、加载中先等界面稳定或者加sleep 2再 dump输出文件为空或只有空白当前界面有 FLAG_SECURE 防截屏保护换一个非敏感页面或使用录屏替代方案一直在等待没有结果设备频繁刷新 UI 导致不稳定关掉动画或重启一次 uiautomator 服务还有一个很容易被忽略的坑在某些系统版本上uiautomator dump需要你先唤醒设备并确保屏幕处于亮着的状态屏幕熄灭时它会一直等。所以执行前先adb shell input keyevent KEYCODE_WAKEUP把屏幕点亮然后adb shell wm dismiss-keyguard解除锁屏整套下来成功率会明显提高。5.4 写一个自动化测试辅助小脚本既然命令都到手了我来拼一个真实可用的组合脚本。它的用途是自动点亮屏幕、解除锁屏、导出当前 UI 层级然后把 XML 拉到电脑本地adb shell input keyevent KEYCODE_WAKEUP adb shell wm dismiss-keyguard sleep 1 adb shell uiautomator dump /sdcard/ui.xml adb pull /sdcard/ui.xml ./ui_dump.xml如果uiautomator dump报错你可以在脚本里顺手加个判断失败时自动重试一次。这个小脚本就已经有了“先执行、再校验、后处理”的结构比一次性敲三条命令可靠得多。6. Shell 中的常见坑我踩过的你别再踩6.1 括号、空格和引号语法层面的三巨头Shell 脚本报错里最有意思的一点是很多错误并不是逻辑错了而是“长相”错了。首先是空格问题比如if [ $a $b ][和]两侧必须有空格写成[$a$b]就会被当成一个命令去执行同理变量赋值等号两边不能有空格。其次是括号问题()会启动子 Shell{}是代码块$()是命令替换$(( ))是算术运算长得都像但语义完全不同初学者最容易把$( )和$(( ))搞混。引号方面有一条铁律只要变量可能包含空格或特殊字符引用它就必须加双引号。单引号和双引号的差异前面提过双引号允许变量展开单引号是完全原文。我自己在排查别人脚本时十次里有七八次报错现场都有没加引号的变量。6.2 环境变量与 PATH 问题“明明装了某个软件脚本里执行却提示 command not found”这是命中最常见的坑之一。背后的原因通常是脚本启动时用的 PATH 环境变量和你当前终端里看到的不一样。比如你用 cron 定时跑脚本环境变量会退化到极简状态/usr/local/bin根本不在里面。解决方案有两条在脚本里写明全路径比如/usr/local/bin/python或者干脆在脚本开头重新定义 PATH比如export PATH/usr/local/bin:/usr/bin:$PATH。这里要插一个经验别在脚本里硬编码当前用户的 Home 路径。正确写法是用$HOME或者~比如backup_dir$HOME/backup。否则你把这脚本发给别人他用户名和你不一样脚本直接罢工。6.3 管道、变量作用域和命令找不到管道和变量的冲突也值得单独说说。你可能会写一条echo hello | read name; echo $name然后发现输出是空的。原因在于管道右边的命令是在子 Shell 里执行的子 Shell 里用 read 赋的变量不会回传到父 Shell。如果你需要在管道里修改变量建议改用进程替换 (命令)或者干脆把整个操作写进一个块级重定向里。再看一个command not found的隐蔽情形你写了一个叫test.sh的脚本执行./test.sh时报错bad interpreter。这通常是你脚本第一行 shebang 写错了比如写成了#!/bin/bash\r原因无他就是 Windows 编辑器换行符没关干净。解决办法是用sed -i s/\r$// test.sh把回车去掉。这种问题特别气人因为从内容上完全看不出哪里不对。6.4 常见坑速查表我把这些年碰到的高频坑浓缩成一张速查表建议你直接存下来症状根因对策变量赋值报command not found等号两边有空格去掉空格if判断报语法错误[两侧没留空格保持括号与内容有空格文件名带空格被拆成两个参数变量没加引号改成$var文件不存在时循环还在跑通配符没匹配到文件加 [ -e $f ]adb shell权限不足设备未 root 或系统服务限制确认命令是否需要 root后台任务随终端关闭而消失缺少nohup使用nohup cmd 脚本里 cron 跑不到命令PATH 环境变量不完整脚本内手动 export PATHuiautomator dump卡住屏幕熄灭/界面不稳定先唤醒屏幕等界面稳定这张表不追求面面俱到只把日常脚本中出现频率最高的情形列出来。你只要照着检查一遍大部分问题都能在五分钟内定位。7. 继续进阶从 100 例到身边的 Shell7.1 怎么用“Shell 脚本编程 100 例”这类资料网上流传着不少“Shell 脚本编程 100 例”“Shell 面试题合集”之类的资料很多人拿到手就从头开始刷刷到第 20 个就放弃了。我不建议这么干因为那些例子覆盖面很广但你真正用到的可能就集中在文件处理、进程管理、网络连通性这几个方向。我的用法是把它当成字典拿到一个不熟悉的脚本时先去里面查同类结构。比如你看到awk的用法不太熟就去例子里搜 awk 相关的例子对照着运行一遍再改改参数试一次。这种“按需检索动手改”的方式比顺着目录一个一个背要有效得多也更能把知识留在脑子里。7.2 那些名字里带 Shell 的东西GNOME、EDA 与 Windows 管理 Shell搜索热词里还有一些不那么“标准”的 Shell比如tiling shell 增强型平铺它其实是一个 GNOME 桌面扩展作用是让桌面窗口具备平铺式布局这里的 Shell 指的是桌面环境外壳不是我们前面一直在聊的命令解释器。再比如quest activeroles management shell for active directory这是 Windows 生态里用来管理 Active Directory 的命令环境名字里也带 Shell而且确实需要写命令、处理变量概念上和 Bash 有共通之处。还有一个我提过不少次的方向如何从零开始学 synopsys dc shell。如果你做数字 IC 设计DCDesign Compiler工具里的 DC Shell 虽然外表也是命令交互环境但它本质上是基于 Tcl 语法的工具壳。学这类工具型 Shell 时你最需要迁移的是“变量循环条件判断命令调用”这套思维语法细节则以官方手册为准。总之别因为都叫 Shell 就觉得全都会也别因为外形陌生就不敢碰底层逻辑是共通的。7.3 我的学习顺序建议到了这一节我给一个我自己带人时经常用的学习路线希望对你有参考价值。第一步先把ls、cd、cp、mv、rm、cat、less、grep、find、awk、sed这些高频命令混个脸熟不用全部精通但要做到看到名字能想象到它是干嘛的。第二步学会把两个命令用管道组合起来比如查某个进程ps -ef | grep java。第三步开始写 20 行以内的小脚本只做一件事批量处理文件名、输出一段日志、定时备份目录。第四步再把循环、变量、参数、函数揉进去试着写一个带选项的完整小工具。第五步去解决真实问题比如配合 ADB 做自动化、配合 SSH 做远程部署这时候你已经具备了“自学任何 Shell 变种”的底子。我现在做事情的习惯是能用一个 Shell 脚本解决的事绝不动手一步步做五分钟以内能临时手敲的命令也绝不多留垃圾文件。每次有同事惊讶地说“你刚才这几步怎么这么快”我心里想的就是这些快感都是被当初那些到处踩坑的夜晚换来的。你如果照着上面这几章的思路走该踩的坑我都替你列完了剩下的就只有一个任务打开终端真的去写它一遍。你会发现Shell 远比想象中直接、强大也远比想象中更好玩。
返回列表