Skip to content

Shell 变量、字符串与数组基础 ​

Github

helloworld ​

以下为 Bash 示例,未执行。先在独立目录创建 helloworld.sh,只保存下面源码:

bash
#!/bin/bash
# #! 指定直接执行时的解释器;# 开始 Bash 注释。
echo "Hello World !"

再执行(命令不是脚本源码的一部分):

sh
chmod +x ./helloworld.sh
./helloworld.sh

预期标准输出:

text
Hello World !

Shell 变量 ​

命名规则 ​

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。

操作 ​

  • 创建使用
    shell
    #!/bin/bash
    user_name="lcc"
    age=23
    sex="男"
    echo $user_name
    echo $age
    # 建议使用${变量名}
    # 为了帮助解释器识别变量的边界
    :<<EOF
    echo "I am good at ${skill}Script"
    EOF
    echo ${sex}
  • 只读
shell
#!/bin/bash
user_name="lcc"
readonly user_name
user_name="Cc"
echo ${user_name}

预期赋值行报 readonly variable;原值仍为 lcc。错误与标准输出分属不同流,不保证显示顺序一致。

  • 删除
shell
#!/bin/bash
user_name="lcc"
unset user_name
echo ${user_name}

运行结果 什么都不会输出,建议提示变量不存在

  • 变量类型 运行 shell 时,会同时存在三种变量:
  1. 局部变量 局部变量在脚本或命令中定义,仅在当前 shell 实例中有效,其他 shell 启动的程序不能访问局部变量。
  2. 环境变量 通过 export 导出的变量会传给之后启动的子进程;并非任意已运行程序都能访问当前 Shell 的变量,有些程序需要环境变量来保证其正常运行。必要的时候 shell 脚本也可以定义环境变量。
  3. shell 变量 shell 变量是由 shell 程序设置的特殊变量。shell 变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了 shell 的正常运行

字符串 ​

单引号与双引号 ​

  • 单引号
shell
#!/bin/bash
name='C\sadf@$@#!$@#@#!c\'
echo ${name}
url='"lichaoche's'ng.top"'
echo ${url}

预期输出(未执行):

text
C\sadf@$@#!$@#@#!c\
"lichaochesng.top"
  • 双引号
shell
#!/bin/bash
name='Cc'
str="Hello, I know you are \"${name}\"! \n"
printf '%b' "$str"

预期输出:

text
Hello, I know you are "Cc"!
  • 区别
    • 单引号
      • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
      • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
    • 双引号
      • 双引号里可以有变量
      • 双引号里可以出现转义字符

字符串操作 ​

  • 拼接
shell
    #!/bin/bash
    your_name="Cc"

    # 使用双引号拼接
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting  $greeting_1
    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3

预期输出(未执行):

text
hello, Cc ! hello, Cc !
hello, Cc ! hello, ${your_name} !
  • 获取长度

    shell
    #!/bin/bash
    name="CcAndHyperAndLccAndChaoChengLi"
    echo ${#name} #输出 30
    sex="Male"
    echo ${#sex} # 输出 4
  • 提取字符串

    shell
    #!/bin/bash
    name="lcc"
    # 0 开始计算
    echo ${name:0:2} #输出 lc
    echo ${name:1:2} #输出cc
    echo ${name::2} #输出 lc
  • 查找字符串

    #!/bin/bash
    name="lcc shell"
    # 哪个字母先出现就计算哪个
    echo `expr index "${name}" l`  #输出 1 ps:为什么查找从1开始计算
    echo `expr index "${name}" e`  #输出 7

ps:是 ` 不是 '

数组 ​

创建、查看、获取、修改、[二维数组....]

shell
    #!/bin/bash
    # 数组没有逗号分隔
    arrayName=("lcc" "Cc" "Hyper" 10)
    arrayAge=(
    23
    18
    6
    )
    # 下面查看数组
    echo ${arrayName[1]}	 #输出 Cc
    echo ${arrayAge[1]}		#输出 18
    # 获取所有元素
    echo ${arrayName[@]}	#输出 lcc Cc Hyper 10
    # 数组长度
    length=${#arrayName[@]}
    echo ${length}	#输出 4
    echo ${#arrayAge[*]}	#输出 3
    # 通过下标修改元素
    arrayName[0]="yes"
    echo ${arrayName[@]}	#yes Cc Hyper 10
    #--------
    # 二维数组
    # https://www.jianshu.com/p/543fa9df3469
    # https://www.cnblogs.com/wyf-349/p/11236939.html
    #--------

传递参数 ​

shell
#!/bin/bash
echo "运行时参数传递";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "参数个数:$#"
echo "传递的参数作为一个字符串显示:$*"

echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done

运行 ./demo1.sh lcc 23 M,以下为原记录输出(非本轮执行):

text
运行时参数传递
执行的文件名:./demo1.sh
第一个参数为:lcc
第二个参数为:23
第三个参数为:M
参数个数:3
传递的参数作为一个字符串显示:lcc 23 M
-- $* 演示 ---
lcc 23 M
-- $@ 演示 ---
lcc
23
M

区别 ​

  • #$* 与 $@ 区别:
    • 相同点:都是引用所有参数。
    • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

运算符 ​

以下用就地 Bash 例说明运算符,未执行;原图片与历史仓库文件仍保留。

算术运算符 ​

printf '%s\n' "$((2 * 3))" 预期输出 6。

算术运算符

原仓库代码路径:operator/t2.sh,位于页首 GitHub 链接;本页未包含其源码。 注意:

  • 外部 expr 的乘号需引用或转义,避免 Shell 先展开为文件名;Bash 算术展开 $((2 * 3)) 中无需转义。
  • if...then...fi 是条件语句,后续将会讲解。
  • $((表达式)) 是 Shell 算术展开,与操作系统是否为 macOS 无关,不是另一种 expr 语法。

关系运算符 ​

[ 3 -gt 2 ] 比较整数大小,预期状态 0;它不输出 true 字符串。

关系运算符

原仓库代码路径:operator/t3.sh,位于页首 GitHub 链接;本页未包含其源码。

布尔运算符 ​

[ -n "$value" ] 检查非空;! 可以对一个命令的成功状态取反。

算术运算符

原仓库代码路径:operator/t4.sh,位于页首 GitHub 链接;本页未包含其源码。

逻辑运算符 ​

cmd1 && cmd2 仅在前者成功时执行后者;cmd1 || cmd2 仅在前者失败时执行后者。

逻辑运算符

原仓库代码路径:operator/t5.sh,位于页首 GitHub 链接;本页未包含其源码。

字符串运算符 ​

[ "$name" = "Cc" ] 比较两个字符串,参数须引用。

字符串运算符

原仓库代码路径:operator/t6.sh,位于页首 GitHub 链接;本页未包含其源码。

文件检测运算符 ​

[ -f "$path" ] 检查是否指向普通文件;这不证明所有者、权限或路径没有链接。

文件检测运算符

原仓库代码路径:operator/t7.sh,位于页首 GitHub 链接;本页未包含其源码。

继续阅读