1. shell 变量与常见符号

变量

运行shell时,会同时存在三种变量:

  1. 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

  2. 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

  3. shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

声明即用

a=2
b="123"

调用 ${varName}或者 $varName

echo $b
echo ${a}

只读变量

param=123
readonly param
param=1

运行

./1.sh:行3: param: 只读变量

删除变量

unset varName
  • unset不能删除只读变量

  • 删除后不能再次使用

a=123
unset a
echo $a

运行

没有任何输出内容

传递参数

常见变量

  • $?:判断上一个语句是否成功

  • $0:执行脚本文件名称

  • $1:第1个参数

  • $n:第n个参数

  • $*:参数分别是什么

  • $@:与 $*相同,但是使用时加引号,并在引号中返回每个参数。

  • $#:参数个数

  • $$:脚本当前的进程号

传递参数示例

demo1.sh

echo "脚本文件名称:$0"
echo "第1个参数:$1"
echo "所有的参数:$*"
echo "参数个数:$#"

赋予执行权限

chmod u+x demo1.sh

执行

./demo1.sh param2 1 2 3

输出结果

脚本文件名称:./demo1.sh
第1个参数:param2
所有的参数:param2 1 2 3
参数个数:4

符号

常见符号

> :向目标文件写入内容

  • 会覆盖掉原来的内容

  • 例子:向文件1.txt写入hello world字符串

      # 直接在bash中可运行
      echo hello world > 1.txt

>> :向目标文件尾部插入内容

  • 在源文件尾部追加内容

  • 例子:向文件1.txt增加一行hello world字符串

      # 直接在bash中可运行
      echo hello world >> 1.txt

; :执行多条指令

  • 例子:追加一行内容,然后显示文件当前的内容

      # 直接在bash中可运行
      echo hello world >> 1.txt ; cat 1.txt

| :管道符

  • 将上一条命令的处理结果传给下一个命令处理

  • 例子:将cat结果传给wc命令统计行数

      # 直接在bash中可运行
      # 最后一个字母为小写的L
      cat 1.txt | wc -l

&& :执行多条命令

  • 前一条命令出错,会阻塞后续命令执行

  • 例子:向1.txt追加一行内容 再查看其行数

      # 直接在bash中可运行
      echo str >> 1.txt && wc -l 1.txt

|| :执行多条命令

  • 前一条命令出错才会执行后续指令

  • 例子:向1.txt追加一行内容出错 ,再查看其内容

      # 直接在bash中可运行
      echo3 str >> 1.txt || cat 1.txt

"" :能够输出变量值

  • 能够解析字符串中的 $varName 变量

  • 例子:输出hello

    # 编写demo3.sh
    
      a="hello"
      echo "$a"

'' :不能够输出变量值

  • 不够解析字符串中的 $varName 变量

  • 例子:不能输出hello

    # 编写demo3.sh
    
      a="hello"
      echo '$a'

    输出结果为:$a

`` :输出命令结果

  • 例子:输出当前的日期

  • date命令可获取当前日期

    echo `date`

2>/dev/null :错误输出到无底洞

  • 命令执行错误则不会出现错误提示

  • 执行正确才会有输出结果

  • 例子

    # 执行
    echo1 123
    # 正常错误输出
    bash: echo1: 未找到命令
    # 使用无底洞
    echo1 123 2>/dev/null
    # 没有任何内容输出

1>/dev/null :正确输出到无底洞

  • 命令执行正确则不显示执行结果

  • 执行错误才会有错误提示内容

  • 例子

    # 执行
    echo 123
    # 正常输出
    123
    # 使用无底洞
    echo 123 1>/dev/null
    # 没有任何内容输出

字符串

字符串可以用单引号,也可以用双引号,也可以不用引号

单引号

str='hello world $$ $a'
echo $str

输出

hello world $$ $a
  • 单引号里的任何字符都会原样输出

  • 变量无效

  • 不能单独出现一个引号(加上反斜杠转义也不行),只能成对出现

  • 可用于字符串拼接

双引号

str='sugar'
echo "my name is $str"

输出

my name is sugar
  • 双引号里可以有变量

  • 双引号里可以出现转义字符

字符串拼接

name="sugar"
str1="hello, "$name" !"
str2="hello, $name !"
str3='hello, '$name' !'
str4='hello, $name !'
echo $str1
echo $str2
echo $str3
echo $str4

输出

hello, sugar !
hello, sugar !
hello, sugar !
hello, $name !

获取字符串长度

str="abcdefg"
echo "${#str}"

输出

7

截取字符串

str="hello world"
echo ${str:2:4}

输出

llo

数组

  • 只支持一维数组

  • 没有限定数组大小

  • 可以不使用连续的下标,而且下标的范围没有限制。

数组声明格式

arrName=(v0 v1 v2 v3)

等价

arrName=(
  v0
  v1
  v2
  v3
)

等价

arrName[0]=v0
arrName[1]=v1
arrName[2]=v2
arrName[3]=v3

数组调用格式

${arrName[index]}

读取所有元素

${arrName[@]}

数组长度

length=${#arrayName[@]}
# 或者
length=${#arrayName[*]}

数组使用示例

arr1=(1 2 3 4 5)
arr2=("A" 'b' 'c' 3)
arr3=(
 1
 2
 3
)

echo "${arr1[0]}"
echo ${arr2[1]}
echo ${arr3[2]}

echo  "arr1长度为:${#arr1[*]}"
echo  "arr2长度为:${#arr2[@]}"

运行输出

1
b
3
arr1长度为:5
arr2长度为:4

Last updated