bash是现在很多Linux的发行版中默认的shell,它来自于 BSD Unix,语法非常类似于C语言,所以通常有 C/C++ 编程背景的开发人员最喜欢使用。不过我在工作中,一个主要系统的默认 shell 却是 csh 。因此我总结一下两种 shell 的语法特点。

变量

用户变量

项目 bash csh
变量定义 变量名称="变量值" set var
变量引用 $var
${var}
$var
${var}
内置用法 $%x 表示变量的值的长度
$?x 来判断变量x是否设置,如设置则为1,否则为0。
示例 a="abc"
echo $a
set x = 7
echo $x
注意事项 = 的两边不能有空格,否则shell解释成名称和命令参数。
bash变量默认都是字符串类型的。
使用 setenv var value 方式可以定义环境变量,所有子 shell 继承其变量值
  • Bash 变量名区分大小写,HOME和home是两个不同的变量。
  • 字母、数字和下划线字符组成。
  • 第一个字符必须是一个字母或一个下划线,不能是数字。
  • 不允许出现空格和标点符号。如果变量的值包含空格,则必须将值放在引号中。
  • 如果变量不存在,Bash 不会报错,而会输出空字符。

同一行定义多个变量或执行多个语句,必须使用分号 ; 分隔。

系统变量

  • env命令或printenv命令,可以显示所有环境变量;而且命令后面的变量名,不用加前缀$。如 printenv PATH 等同于 echo $PATH
  • set 命令可以显示所有变量(包括环境变量和自定义变量),以及所有的 Bash 函数。
变量 定义 备注
$BASH Bash 程序的路径
$BASH_VERSION 系统Bash 版本号
$EUID “有效” 用户 ID
$UID 用户 ID $UID 是一个只读变量,不能在命令行或者脚本中修改它,在 /etc/passwd 文件中定义。
$GROUPS 用户组名 在 /etc/passwd 文件中定义。
$HOME 用户主目录 在 /etc/passwd 文件中定义。
$PWD 工作目录(当前目录) 这与内置命令 pwd 的作用相同。
$HOSTNAME 主机名
$IFS 内部域分隔符 $IFS 默认为空白(空格, 制表符,和换行符),可以通过赋值改变。 $* 就是使用的 $IFS 的第一个字符来分隔位置参数的。
$PATH 可执行文件的搜索路径
$PS1 主提示符 普通用户默认提示符是 $,超级用户(root 用户)默认提示符是 #
$PS2 第二提示符 默认值为 >
$PS4 第二提示符 使用 -x 选项来调用脚本时,这个提示符会出现在每行输出的开头,默认为 +
  • 在 GNU 指令中,如果单独使用 - 符号,不加任何该加的文件名称时,代表 标准输入 的意思。
    • cat -
      • cat - > test.txt 表示在屏幕里输入什么,都会在test.txt中输出。
      • (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -) :压缩/source/directory下的文件,输出作为下一个命令的输入;更改当前目录到/dest/directory,解压文件
    • tar xpvf -:标准输入读取资料并解压
    • cd -:切换到上次的工作目录

函数的参数变量

变量 定义 备注
$0 脚本的名称
$1, $2,…,${n} 位置 参数 n> 9 时,必须使用花括号 {} 包围数字 n。
$# 位置参数的个数
$*, $@ 位置参数数组 "$*" 表示的是所有参数拼接成一个字符串,与 $*"$@"$@ 表达的数组概念是不同的。
$! 运行在后台的 最后一个 作业的 PID
$$ 当前 bash 脚本的 PID
$PPID 当前 bash 脚本父进程的 PID
$- 当前 Shell 的启动参数
$_ 命令的 最后一个 参数的值
$? 命令的退出状态码 一般表示命令执行成功或失败: 0 ** 表示成功,其它值** 表示错误。
比如 cp 命令,退出状态码 1 表示文件没有找到,2 表示文件不可读,3 表示目标目录没有找到,4 表示目标目录不可写,5 表示一般性错误。

在为shell脚本传递的参数中如果包含空格,应该使用单引号或者双引号将该参数括起来,以便于脚本将这个参数作为整体来接收。

变量特性

  • readonly: 只读变量
  • local: 局部变量(仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。)。
  • unset:删除变量,如 unset variable_name。变量被删除后不能再次使用。unset 命令不能删除只读变量。
  • let:整数变量。

参考文献

  1. 脚本之家网.csh的基本语法介绍[EB/OL].https://www.jb51.net/article/57770.htm, 2020/12/21.

  2. iTech.csh 语法实例参考[EB/OL].https://www.cnblogs.com/itech/archive/2012/08/15/2640811.html, 2020/12/21.

  3. 菜鸟教程.Shell 变量[EB/OL].https://www.runoob.com/linux/linux-shell-variable.html, 2020/12/24.

  4. sparkdev.常见 Bash 内置变量介绍[EB/OL].https://www.cnblogs.com/sparkdev/p/9934595.html, 2020/12/24.

  5. 361way.com.ssh几个超时参数[EB/OL].http://www.361way.com/ssh-autologout/4679.html, 2020/12/24.

  6. 13070026王志东.3种shell自动交互的方法[EB/OL].https://www.cnblogs.com/evi10032/p/5455990.html, 2021/02/12.

  7. Mykola Ulianytskyi.Expect Download for Linux[EB/OL].https://pkgs.org/download/expect, 2021/02/12.

姊妹篇

  1. csh 、 bash 的基础语法对照:变量

  2. csh 、 bash 的基础语法对照:判断表达式

  3. csh 、 bash 的基础语法对照:循环表达式