【Shell 编程】变量详解 | 特殊变量与标准变量 | 基本语句介绍
创始人
2025-05-29 12:24:35

 

💭 写在前面:Shell 是一个命令行解释器,它可以用于自动化任务、脚本编写和系统管理等多种场景。本章我们将学习 Shell 编程基础,介绍变量和一些基础语句。本篇文章旨在为初学者提供 Shell 编程的基础知识,我们希望本篇文章能够帮助读者更好地理解 Shell 编程的核心概念和语法,并且能够在实践中运用它们(在讲解时会提供示例)。


Ⅰ. Shell 变量

0x00 基本变量

在 Shell 编程中,变量是一个非常重要的概念,因为它们可以用于存储和操作数据,以及传递值给函数和脚本。命令行解释器 (Bourne Shell) 无需声明变量即可使用,变量的名称默认使用 大写字母

$ name=foxny
$ echo $name      # 打印变量,变量前要加 $
foxny$ name=牛魔酬宾    # 修改变量内容
$ echo $name
牛魔酬宾

📌 注意定义规则:

$ name=my computer
bash: computer: command not found$ name="my computer"
$ echo $name
my computer$ ux=UNIX
$ echo ${ux}tm
UNIXtm$ echo "$ux"tm
UNIXtm$ echo $uxtm
bash: uxtm: unbound variable$ set -u
$ echo Suxtm

0x01 只读变量:readonly

定义只读变量 readonly:

$ flower = tulip
$ readonly flower    # 定义flower变量未只读变量
$ flower=rose
bash: flower: readonly variable   

0x02 环境变量设置:export

变量只在声明的 shell 内使用,但是使用 export 命令,可使变量也可以在其他地方使用:

$ cat kfc
echo $day V me 50!$ day=FuckingCrazyThursday   # 定义变量day
$ ./kfc
V me 50!       # 此时环境变量未导出$ export day   # 我们用 export 来导出
$ ./kfc
FuckingCrazyThursday V me 50!   # 此时再运行,变量起效了

0x03 特殊变量(Automatic shell variables

特殊 shell 变量,即 "Automatic shell variables",是指由 Shell 自动设置和维护的一组特殊变量,它们用于在 Shell 脚本中处理命令行参数、脚本执行状态等信息。这些变量可以在脚本中 直接使用,而无需自己声明和定义。 

  • $? :返回上一个命令的退出状态码。如果命令 执行成功,则状态码为 0,否则为非零值。

这里执行成功状态码是 0!“在C语言中,都是0为假,1为真; 而在Shell脚本语言中,状态码0表示成功(可以理解为真),其他状态码(包括1)表示错误(可以理解为假);

$ ls /nonexistent
ls: cannot access '/nonexistent': No such file or directory  # 失败
$ echo $?        # 返回上一个命令退出码
2                # 返回非0值# 这里的 ls /nonexistent 命令执行失败,其退出状态码为 2。
  • $$ :返回当前 Shell 进程的 \textrm{pid}, $$ 是一个常量,只要脚本在执行,它的值就不会改变:
$ echo $$    # 返回进程pid
24085
  • $! 返回最近一个后台运行的进程的 \textrm{pid},与 $$ 不同的是, $? 是一个变量,其值随着后台作业的启动和结束而改变:
$ sleep 10 &
[1] 1234
$ echo $!
1234# 这里的sleep 10 &命令被放到后台运行,并输出了进程ID1234,然后使用 $! 获取该进程ID
  • $# 获取脚本传入的参数个数,获取传递给当前 Shell 脚本(或函数)的参数个数。
$ myscript.sh arg1 arg2 arg3
3# 在 myscript.sh 脚本中可以通过 $# 获取到传递给它的参数个数,即3。
  • $*$@ :它们功能相似,都是包含所有传递给当前 Shell 脚本或函数的参数的变量。不同的是,$* 是将所有参数视为一个单词,而 $@ 则将每个参数视为一个单独的单词。

注意:当 $* 和 $@ 不被双引号 " " 包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。但是当它们被双引号 " " 包含时,就会有区别了:

$* 将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。(*普遍代表所有,*(星号) 是 Linux 中的通配符,代表一个或一个以上的所有字符)

$@ 将每个参数都看作一份数据,彼此之间是独立的。(这就像我们单独艾特某个人一样,理解!)

$ echo "Using \$* : $*"
Using $* : arg1 arg2 arg3
$ echo "Using \$@ : $@"
Using $@ : arg1 arg2 arg3# $* 把三个参数视为单个单词,并将它们连接起来,
# 使用空格作为分隔符。而 $@ 则将每个参数视为一个单独的单词。# 比如传递了 3 个参数:那么对于 $*来说,这 3 个参数会合并到一起形成 1 份数据,它们之间是无法分割的。
# 而对于 $@ 来说,这 3 个参数是相互独立的,它们是 3 份数据。

0x04 标准 Shell 变量(Standard shell variable)

标准 Shell 变量 (Standard shell variable) 是指在 Shell 中预先定义好的一组标准变量,它们的名称和含义都是固定的。这些变量通常用于在 Shell 脚本中传递参数、保存状态和结果等。

下面我们来介绍几个常用的标准变量:

  • $ HOME:当前用户的家目录。
  • $ PATH:搜索可执行文件的路径。
  • $ IFS:输入字段分隔符,用于分割输入字符串。
  • $ CDPATH:指定 cd 命令在搜索目录时的搜索路径。
  • $ LOGNAME:登陆的用户名
  • $ SHELL:登陆时展现的路径位置(默认 Shell 路径)
  • $ PS1:登录时命令提示符的格式,用于显示当前 shell 的状态和提示用户输入 ($ #)
  • $ TERM:接收的 terminal,用于指定当前终端的类型
  • $ PWD:当前工作目录。
  • $ OLDPWD:上一个工作目录。
  • $ USER:当前用户名。
  • $ GROUPS:当前用户所属的组。
  • $ HOSTNAME:当前主机名。
  • $ OSTYPE:当前操作系统类型。

 

0x05 特殊引用字符

斜杠(\):转义字符,将其视为一个字符。
单引号(' '):按原样处理单引号内的字符串。
双引号(" "):将双引号内的变量替换为变量值进行处理。

$ echo $HOME   
/home/foxny $ echo '$HOME'   # 将单引号内的内容看作字符串。我就想打印 $HOME
$HOME            # 没触发 $HOME,而是老老实实打印出了 $HOME$ echo \$home    # \ 转义,这里把 $ 看成字符
$HOME            # $ 被当做字符看待了,所以不会触发HOME$ echo "$home"   #
/home/foxny

如果不希望解析变量,直接按照字符原样输出内容,就可以使用单引号。

而双引号会首先解析变量的内容,单引号则是不触发解析!

Ⅱ. Shell 基本语句介绍

0x00 脚本运行

一种方式是 ./ 的方式,一般要 chmod 给执行权限:

vim test.sh       # 打开脚本
chmod -x test.sh  # 添加权限
./test.sh         # 运行脚本

当然,也可以使用 bash 直接运行:

bash test.sh

0x01 if 语句

if 条件
then语句
else语句
fi           # 结尾用fi结尾(finish)

如果条件为真,则执行 then 后面的命令;否则执行 else 后面的命令。

if [ "$FILE1" = "$FILE2" ]
then
...
fi
if test "$FILE1" = "$FILE2"
then
...
fi

举个例子:

if [ "$1" == "hello" ]
thenecho "Hello, world!"
elseecho "Goodbye, world!"
fi# 如果在脚本执行时传递了参数 "hello" 则输出 "Hello, world!"
# 否则输出 "Goodbye, world!"

如果想并行,就需要加分号,就像这样:

if [ "$1" == "hello" ]; thenecho "Hello, world!"
elseecho "Goodbye, world!"
fi

0x02 while 语句

while 条件
do语句
done

如果条件为真,则执行 语句 中的命令,并继续测试条件;如果条件为假,则跳出循环。

举个例子:计算 1 到 4 之间的整数的平方,并输出结果。它使用一个 while 循环,将 $int 变量从 1递增到 4,并在每次循环中计算平方。在每个循环迭代中,它使用 expr 命令计算平方值,然后将其存储在变量$sq中,并使用 echo 命令将 $sq 的值输出到控制台。

int=1
while [ $int -lt 5 ]
dosq=`expr $int \* $int`echo $sq int=`expr $int + 1`
done
echo "Job complete"

0x03 for 语句

for 变量 in 列表
do语句
done

列中可以是用空格或换行符分隔的多个值。每次循环中,变量会依次取值列表中的每个值,并执行语句。当列表中的值都遍历完毕时,for 循环结束。

举个例子:

IFS=:for dir in $PATH
dols -ld $dir
done

0x04 until 语句

与 while 语句类似,但条件的测试方式相反,是 while 的否定形式。

* 相当于 Python 中的 while not,C/C++ 中 while (! ) 

until 条件
do语句
done

如果条件为假,则执行语句中的命令,并继续测试条件;如果条件为真,则跳出循环。

int=1
until [ $int -ge 5 ]
dosq=`expr $int \* $int`echo $sq int=`expr $int + 1`
done
echo "Job complete"

 0x05 case 语句

case 表达式 in 匹配模式1 )语句 ;;匹配模式2 )语句 ;;...* )语句 ;;
esac   # 结尾要加 esac(就倒过来的 case,这很有趣)

举个例子:

echo "It is morning? yes or no"
read timeofday
case "$timeofday" in yes | y | Yes | YES ) echo "Good Morning" ;;n* | N* ) echo "Good Afternoon" ;;* ) echo "What The Fuck?" ;;
esac

0x06 函数

在 Shell 脚本中,函数是一段可以重复使用的代码块,可以接受参数,并返回一个值。定义函数的基本语法如下:

函数名()
{语句
}

💭 举个例子:计算两个数的和的函数

add() {sum=$(($1 + $2))return $sum
}

📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2023.3.17
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

比特科技. Linux[EB/OL]. 2021[2021.8.31 xi

相关内容

热门资讯

高考作文素材:博迪眨眼写作(... 高考作文素材:博迪眨眼写作 篇一博迪眨眼写作:激发创造力的奇妙之旅博迪眨眼写作是一种独特的写作方式,...
高考作文高分句子【精简3篇】 高考作文高分句子 篇一:爱与责任爱是一种伟大的情感,它能够让人们变得更加善良和宽容。然而,爱也需要责...
高考优秀作文【精选6篇】 高考优秀作文 篇一:如何合理利用高考复习时间高考作为每个学生人生中的重要节点,备考期间的复习时间显得...
湖北卷高考作文题:上善若水任... 湖北卷高考作文题:上善若水任方圆 篇一上善若水,任方圆。这是一句古语,它告诉我们善良就像水一样,可以...
高考话题作文素材:规律(优选... 高考话题作文素材:规律 篇一规律存在于高考中的每一个环节,从备考到阅卷都离不开规律。掌握这些规律,可...