4、Shell基础入门:Shell是什么、第一个Shell脚本、变量与引号、特殊字符

4.1 Shell到底是什么?

很多刚接触嵌入式的朋友问我:Shell到底是个啥?

说白了,Shell就是一个命令解释器。你敲一行命令,它帮你翻译给操作系统内核听。内核执行完了,它再把结果返回给你。

我刚开始做嵌入式开发时,总觉得Shell就是那个黑乎乎的终端窗口。后来才明白,终端只是外壳,Shell才是真正干活的家伙。

常见的Shell有几种:

  • bash:Linux上最常用,功能强大,我平时用的就是它
  • sh:最古老的Shell,很多嵌入式系统里只有它
  • dash:轻量级,启动快,Debian系系统的/bin/sh经常指向它
  • zsh:bash的增强版,macOS默认用这个

在嵌入式开发中,你大概率会遇到的是bashsh。我个人建议:写脚本时尽量用bash,兼容性好,功能也够用。

小提示:echo $SHELL 可以查看你当前用的是哪个Shell。试试看,说不定有惊喜。

4.2 第一个Shell脚本

光说不练假把式。咱们直接上手写一个。

创建一个文件,叫 hello.sh

#!/bin/bash
# 这是我的第一个Shell脚本
echo "Hello, 嵌入式世界!"

然后给它执行权限,再运行:

chmod +x hello.sh
./hello.sh

屏幕上就会打印出:Hello, 嵌入式世界!

这里有个细节要注意:#!/bin/bash 这行叫shebang(念作「希邦」)。它告诉系统:用哪个解释器来执行这个脚本。我见过有人漏掉这行,结果脚本跑不起来,折腾了半天。

注意:写shebang时,路径一定要写对。嵌入式系统里bash可能不在/bin下,而是在/usr/bin下。用 which bash 确认一下。

4.3 变量与引号

Shell里的变量,用起来很简单。直接赋值,前面加个美元符号就能取:

#!/bin/bash
name="嵌入式开发板"
echo "你好,$name"

输出:你好,嵌入式开发板

但引号这块,坑不少。我当年就吃过亏。

Shell里有三种引号:

  • 双引号 "":里面的变量会被解析。比如 "$name" 会变成具体的值。
  • 单引号 '':里面的内容原样输出,变量不解析。比如 '$name' 打印出来就是 $name 这个字符串。
  • 反引号 ``:执行里面的命令,返回结果。比如 `date` 会返回当前时间。

举个例子你就明白了:

#!/bin/bash
board="STM32F407"
echo "我的板子是 $board"    # 输出:我的板子是 STM32F407
echo '我的板子是 $board'    # 输出:我的板子是 $board
echo "今天是 `date`"        # 输出:今天是 2025年 01月 15日 星期三 ...

我在项目中遇到过一个问题:用单引号包了一个路径,结果变量没展开,程序死活找不到文件。排查了半天,才发现是引号用错了。

经验之谈:能用双引号就别用单引号,除非你确定不需要变量展开。反引号现在可以用 $() 替代,可读性更好。比如 $(date)`date` 清晰多了。

4.4 特殊字符

Shell里有些字符有特殊含义。用不好,脚本就会出幺蛾子。

字符 含义 示例
$ 变量取值 $HOME 表示用户家目录
# 注释 # 这是一行注释
* 通配符,匹配任意字符 ls *.txt 列出所有txt文件
? 通配符,匹配单个字符 ls ?.txt 匹配 a.txt, b.txt 等
| 管道,把前一个命令的输出传给后一个 ls | grep "log"
> 重定向输出到文件 echo "hello" > file.txt
>> 追加输出到文件 echo "world" >> file.txt
; 分隔多条命令 cd /tmp; ls
&& 前一条成功才执行后一条 make && make install
|| 前一条失败才执行后一条 ping -c 1 192.168.1.1 || echo "不通"

我曾经在编译脚本里用了 make; make install,结果make失败了,install照常执行,把旧文件覆盖了。从那以后,我写脚本都老老实实用 &&

避坑指南:文件名里如果包含特殊字符,比如空格、$*,一定要用引号包起来。否则Shell会把它当成特殊字符处理。我曾经因为文件名里有空格,导致一个备份脚本删错了文件……嗯,说多了都是泪。

4.5 小结

这一章我们聊了:

  • Shell就是个命令翻译官,bash是嵌入式里最常见的
  • 第一个脚本,别忘了shebang和执行权限
  • 变量用 $ 取,双引号展开变量,单引号原样输出
  • 特殊字符各有各的脾气,用之前先想清楚

你想想看,这些基础的东西,其实每个嵌入式工程师都会用到。写编译脚本、做自动化测试、部署固件……哪样离得开Shell?

下一章,咱们聊聊变量和参数展开,那才是真正体现Shell功底的地方。