变量与基本语法

定义变量

定义变量时,千万不要在等号的两边加空格,否则会报错。正确的做法是:

a=1
echo $a

引用变量

正如上面代码所示,用 $ 加上变量名就可以引用变量,有时候我们还会看到另一种写法:

a=1
echo $a
# 下面这种写法也是一样的,而且更推荐
echo ${a}

一般来说,用大括号把变量名括起来是多此一举,两者作用相同。但如果我们要做字符串拼接,可以这样写:

a=hello
echo ${a}wrold  # 输出 helloworld
echo $awrold    # 变量 awrold 并不存在

在 bash/zsh 的语法中,不需要使用专门的字符串拼接函数,只要把两个变量写在一起即可。

引号

bash/zsh 中有单引号和双引号之分,区别在于单引号中的内容完全是字面量,甚至单引号中都无法使用转义字符再打印出单引号。

双引号中,如果遇到变量,将会自动转换为变量的值。

echo "\"\""    # 输出 ""
echo '\'\''    # 没有输出,因为单引号内部都是字面量

a=1
echo "$a"      # 输出 1
echo '$a'      # 输出 $a,因为单引号不支持变量的展开

注意!!!在 bash 中,如果变量是一个字符串,而且字符串中含有空格,用双引号括起来的字符串将会被解析为一个独立的单词,直接用 $ 则会被 bash 解析为多个参数。

假设当前目录下有个名叫 a b 文件夹:

p="a b"
cd $p    # bash: cd: a: No such file or directory
# 这是因为上述命令等价于 cd a b
# 字符串 "a b" 的值被拆开传到 cd 命令中,但是 cd 只接收一个参数,导致路径错误
# 正确的做法如下
cd "$p"
# 等价于 cd "a b",路径正确

再次强调,这个问题只在 bash 中存在,如果我们平时在终端中使用 zsh,但是脚本用 bash 执行,就会遇到这个问题。

*nix 系统下任何文件夹、文件名严禁留空格,严禁带中文,利人利己!

变量作用域

默认情况下,变量的作用域是当前的 Shell,即使变量定义在函数中也是如此:

function t() {
    temp=111
}

echo $temp   # 没有输出,变量 temp 未定义
t            # 调用函数,函数内部会定义变量
echo $temp   # 输出 111

因此函数内部的变量要加上 local 关键字才不会污染全局作用域:

function t() {
    local temp=111
}

t            # 调用函数
echo $temp   # 没有输出

环境变量

bash/zsh 中的变量分为普通变量和环境变量两种,区别就在于,当我们从当前的 shell 中打开一个新的 subshell 时,环境变量会被 subshell 继承,普通变量则不会。

a=1        # 定义一个普通变量 a
bash       # 打开一个新的 
echo $a    # 没有输出,因为 subshell 只会继承父 shell 的环境变量

我们可以验证下变量 a 确实是普通变量,而不是环境变量:

# 单独运行 set 命令可以打印出所有普通变量
set | grep 'a=' # 能看到变量 a 的定义

# 单独运行 env 命令可以打印出所有的环境变量
env | grep 'a=' # 没有输出,说明变量 a 不是环境变量

因此,如果想让某个变量的作用域延伸到 subshell 中,就需要把它定义为环境变量。有两种写法都可以做到:

 export a=1
 declare -x a=1

除了在定义时导出为环境变量,也可以把已经定义过的普通变量导出为环境变量:

export a
declare -x a

默认全局变量

PWD

记录当前所在的目录,通过 echo $PWD 查看

OLDPWD

表示上一次所在的目录,输入减号 - 可以快速跳转到上一次所在的目录

特殊变量

bash/zsh 中还有一些约定好的只读变量,它们的值在脚本的运行过程中动态确定,常见的有:

  1. $0:表示脚本名字,可能是相对路径,当我们执行 bash a/b/c/d.sh 是,$0 的值是 a/b/c/d.sh
  2. $1、$2、……、$10:用来表示参数,$1 表示第一个参数,以此类推
  3. $#:表示参数个数
  4. $?:表示上一个命令的执行结果,0 表示正常结束,非 0 表示出现错误

第 2、3 条规则在函数内部同样适用。

results matching ""

    No results matching ""