当前位置:   article > 正文

Shell入门学习_shell在线学习

shell在线学习

:::danger
**推荐学习网站 **https://xukai.work/
中文版Bash脚本:https://linuxstory.gitbook.io/advanced-bash-scripting-guide-in-chinese/
:::

shell概述

:::warning
参考文章:https://zhuanlan.zhihu.com/p/452686607
:::
Shell是一种命令解释器,它不仅分离了用户层与操作系统内核,更是一门强大的编程语言。我们称为shell编写的程序为脚本(script)。脚本是一种易于使用的工具,它能够将系统调用、工具软件、实用程序(utility)和已编译的二进制文件联系在一起构建程序。实际上,shell脚本可以调用所有的UNIX命令、实用程序以及工具软件。如果你觉得这还不够,使用像test命令和循环结构这样的shell内建命令能够让脚本更加灵活强大。Shell脚本特别适合完成系统管理任务和那些不需要复杂结构性语言实现的重复工作。

在shell中,每个脚本的开头都使用 #! ,就是告知系统文件的执行都需要指定一个解释器。指定一个文件类型的特殊标记。占用 2 字节 。

脚本解释器

shell脚本都是以 **#! **开头,告知系统该文件的执行需要一个解释器。 常见的解释器类型如下:
image.png

#!/bin/sh
#!/bin/bash
#!/usr/bin/perl
#!/usr/bin/tcl
#!/bin/sed -f
#!/usr/awk -f
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

解释说明

  • #!/bin/sh linux系统上默认是bash,多数UNIX商业OS中也默认shell。

image.png

调用脚本

执行脚本的三种方式:

#方式1
sh helloworld.sh
#方式2
bash helloworld.sh
bash +x helloworld.sh
  • 1
  • 2
  • 3
  • 4
  • 5

第三种方式有一点特殊

./helloworld.sh             #需给文件授予执行权限

#实授予权限的方式如下
chmod +x helloworld.sh      #授予可执行权限
chmod +rx helloworld.sh     #授予任何人可执行可读和可执行权限
chmod u+rx helloworld.sh    #只给脚本的所有者可读和可执行权限
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

第一个脚本helloworld

#!/bin/bash

echo "helloworld"
  • 1
  • 2
  • 3

目前Linux/unix系统中,普遍的shell脚本的第一行是:#!/bin/sh 或者 #!/bin/bash。

#!/bin/bash

echo "全部参数:" $@
echo "命令行参数数量:" $#
echo '$0 = ' $0
echo '$1 = ' $1
echo '$2 = ' $2
echo '$3 = ' $3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行

chmod u+rx script.sh    #修改权限
./script.sh a b c       #执行脚本
  • 1
  • 2

image.png
用户可以输入任意数量的参数,利用for循环,可以读取每一个参数。

#!bin/bash
# for循环来读取输入的参数
for i in "$@";    #$@返回一个全部参数的列表,然后使用for循环遍历
    do echo $i
done
  • 1
  • 2
  • 3
  • 4
  • 5

使用“ ”包括起来的命令会被认为是一个命令
image.png
**注释 :**Bash 脚本中,以#开头的行就是注释,会被解释器忽略。

# 本行是注释
echo 'Hello World!'
echo 'Hello World!' #是注释
  • 1
  • 2
  • 3

多行注释还可以使用以下格式:

:<<EOF
注释内容...
注释内容...
注释内容...
EOF
  • 1
  • 2
  • 3
  • 4
  • 5

EOF也可以使用其他符号:

:<<'
注释内容...
注释内容...
注释内容...
'

:<<!
注释内容...
注释内容...
注释内容...
!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

命令执行结果

命令执行结束后,会有一个返回值。0表示执行成功,非0(通常是1)表示执行失败。环境变量$?可以读取前一个命令的返回值。利用这一点,可以在脚本中对命令执行结果进行判断。

cd /path/to/somewhere
if [ "$?" = 0 ]; then
  rm *
else
  echo "无法切换目录!" 1>&2
  exit 1
fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

cd /path/to/somewhere这个命令如果执行成功(返回值等于0),就删除该目录里面的文件,否则退出脚本,整个脚本的返回值变为1,表示执行失败。
image.png
由于if可以直接判断命令的执行结果,执行相应的操作,上面的脚本可以改写成下面的样子。

if cd /path/to/somewhere; then
  rm *
else
  echo "Could not change directory! Aborting." 1>&2
  exit 1
fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

更简洁的写法是利用两个逻辑运算符&&(且)和 ||(或)。

# 第一步执行成功,才会执行第二步
cd /path/to/somewhere && rm *
# 第一步执行失败,才会执行第二步
cd /path/to/somewhere || exit 1
  • 1
  • 2
  • 3
  • 4

常见指令

echo命令 – 打印到标准输出中

echo 通常用于 shell 脚本中,用于显示消息或输出其他命令的结果。

$ echo [-neE] [ARGUMENTS]
  • 1

:::danger

  • -n 选项,则取消尾随换行符
  • -e 选项,则将解释以下反斜杠转义字符:
    • \ 显示反斜杠字符
    • \a 警报(BEL)
    • \b 显示退格字符
    • \c 禁止任何进一步的输出
    • \e 显示转义字符
    • \f 显示窗体提要字符
    • \n 显示新行
    • \r 显示回车
    • \t 显示水平标签
    • \v 显示垂直标签
  • -E 项禁用转义字符的解释。这是默认值
    :::
echo "Hello, World!"
Hello, World!
  • 1
  • 2

若要打印双引号,请将其包含在单引号内,或用反斜杠字符进行转义。

$ echo "hello"
hello

$ echo 'hello "hel"'
hello "hel"
  • 1
  • 2
  • 3
  • 4
  • 5

模式匹配字符
echo 命令可以与模式匹配字符一起使用,比如通配符。 例如,下面的命令将返回所有。 工作目录中的 php 文件。

$ echo The PHP files are: *.php
The PHP files are: index.php contact.php functions.php2
  • 1
  • 2

image.png
显示变量
echo 还可以显示变量。在下面的示例中,我们将输出当前登录用户的名称:

$ echo $USER    #$USER 是一个保存用户名的 shell 变量。
admin
  • 1
  • 2

image.png
显示命令的输出
使用 $(command)表达式将命令输出包含在 echo 的参数中。

$ echo "The date is: $(date +%D)"
The date is: 04/01/20

$ echo "Today is : $(date +%D)"
Today is : 07/13/23
$ echo "Today is : $(date +%Y%m%d-%H%M%S)"
Today is : 20230713-145600
$ echo "Today is : $(date +%Y-%m-%d-%H:%M:%S)"
Today is : 2023-07-13-14:56:17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

image.png

env指令 —— 环境变量

env命令总是指向/usr/bin/env文件,或者说,这个二进制文件总是在目录/usr/bin。
:::danger
'!#/usr/bin/env NAME '这个语法的意思是,让 Shell 查找$PATH环境变量里面第一个匹配的NAME。如果不知道某个命令的具体路径,或者希望兼容其他用户的机器,这样的写法就很有用。

env命令的参数如下。

  • i, -ignore-environment:不带环境变量启动。
  • u, -unset=NAME:从环境变量中删除一个变量。
  • -help:显示帮助。
  • -version:输出版本信息。
    :::
    新建一个不带任何环境变量的 Shell:
$ env -i /bin/sh
  • 1

export指令——设置或显示环境变量

在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该次登陆操作。
语法

export [-fnp][变量名称]=[变量设置值]
-f  代表[变量名称]中为函数名称。
-n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。
-p  列出所有的shell赋予程序的环境变量。
  • 1
  • 2
  • 3
  • 4
  1. 输出系统环境变量
export -p  等同于 declare -x
  • 1

image.png

  1. 添加一个环境变量
export AA=2
export -p | grep AA
declare -x AA="2"
  • 1
  • 2
  • 3

image.png
3. 更改变量的值

export aa=5
export -p | grep aa
declare -x aa="5"
  • 1
  • 2
  • 3

image.png

export USER=LII
echo $USER    #LII
  • 1
  • 2

image.png
只在当前终端里有效,当退出后就重新恢复。
image.png

  1. 删除环境变量(无论变量是只存在该shell中还是环境变量)
unset aa
export -p | grep aa
  • 1
  • 2
  1. 从文件中添加环境变量
cat test.sh
export aaa=1
echo $aaa

source test.sh
1

export -p | grep aaa
declare -x aaa="1"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 在脚本中,export声明的变量可以为子脚本使用
/export.sh
export USER=LIU
/source.sh
source ./export.sh #LIU  
  • 1
  • 2
  • 3
  • 4

shift指令 —— 改变脚本参数

shift命令可以改变脚本参数,每次执行都会移除脚本当前的第一个参数($1),使得后面的参数向前一位,即$2变成$1、$3变成$2、$4变成$3,以此类推。
while循环结合shift命令,也可以读取每一个参数。

#!/bin/bash

echo "一共输入了 $# 个参数"
while [ "$1" != "" ]; do
    echo "剩下 $# 个参数"
    echo "参数: $1"
    shift  #shift指令,每次都会移除第一个参数,从而循环遍历所有输入参数
done
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

shift命令可以接受一个整数作为参数,指定所要移除的参数个数,默认为1。

shift 3
  • 1

上面的命令移除前三个参数,原来的$4变成$1。

注意:
如果shift的参数数量超过了原输入的参数个数,那么就会一直循环输出,而不停止。例如,将上面代码中的shift改成shift 20。重新运行,会发现一直在循环。
shift 20 || break #需加入break

echo "一共输入了 $# 个参数"
while [ "$1" != "" ]; do #可以没有[]
    echo "剩下 $# 个参数"
    echo "参数: $1"
    shift 20 || break      #shift指令,每次都会移除第一个参数,从而循环遍历所有输入参数
done
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

image.png

getopts 命令—解析复杂的脚本命令行参数

getopts命令用在脚本内部,可以解析复杂的脚本命令行参数,通常与while循环一起使用,取出脚本所有的带有前置连词线(-)的参数。

getopts optstring name
  • 1

:::danger
它带有两个参数。

  • 第一个参数optstring是字符串,给出脚本所有的连词线参数。比如,某个脚本可以有三个配置项参数-l、-h、-a,其中只有-a可以带有参数值,而-l和-h是开关参数,那么getopts的第一个参数写成lha:,顺序不重要。注意,a后面有一个冒号,表示该参数带有参数值,getopts规定带有参数值的配置项参数,后面必须带有一个冒号(:)。
  • 第二个参数name是一个变量名,用来保存当前取到的配置项参数,即l、h或a。
    :::
    例子:
#!/bin/bash

while getopts 'lha:' OPTION ; do
    case "$OPTION" in
    l)
        echo "linux config"
        ;;
    h)
        echo "h stands for h"
        ;;
    a)
        avalue="$OPTARG"
        echo "The value provided is $OPTARG"
        ;;
    ?)
        echo "script usage: $(basename $0) [-l] [-h] [-a somevalue]" >&2
        exit 1
        ;;
    esac
done
shift "$((($OPTIND - 1)))"

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

image.png
上面例子中,while循环不断执行getopts ‘lha:’ OPTION命令,每次执行就会读取一个连词线参数(以及对应的参数值),然后进入循环体。变量OPTION保存的是,当前处理的那一个连词线参数(即l、h或a)。如果用户输入了没有指定的参数(比如-x),那么OPTION等于?。循环体内使用case判断,处理这四种不同的情况。
:::danger

  • 如果某个连词线参数带有参数值,比如-a foo,那么处理a参数的时候,环境变量$OPTARG保存的就是参数值。
  • 注意,只要遇到不带连词线的参数,getopts就会执行失败,从而退出while循环。比如,getopts可以解析command -l foo,但不可以解析command foo -l。另外,多个连词线参数写在一起的形式,比如command -lh,getopts也可以正确处理。
  • 变量 O P T I N D 在 g e t o p t s 开始执行前是 1 ,然后每次执行就会加 1 。等到退出 w h i l e 循环,就意味着连词线参数全部处理完毕。这时, OPTIND在getopts开始执行前是1,然后每次执行就会加1。等到退出while循环,就意味着连词线参数全部处理完毕。这时, OPTINDgetopts开始执行前是1,然后每次执行就会加1。等到退出while循环,就意味着连词线参数全部处理完毕。这时,OPTIND - 1就是已经处理的连词线参数个数,使用shift命令将这些参数移除,保证后面的代码可以用$1、 2 等处理命令的主参数。个连词线参数带有参数值,比如 − a f o o ,那么处理 a 参数的时候,环境变量 2等处理命令的主参数。个连词线参数带有参数值,比如-a foo,那么处理a参数的时候,环境变量 2等处理命令的主参数。个连词线参数带有参数值,比如afoo,那么处理a参数的时候,环境变量OPTARG保存的就是参数值。
    :::

配置项参数终止符 --/-

-和–开头的参数,会被 Bash 当作配置项解释。但是,有时它们不是配置项,而是实体参数的一部分,比如文件名叫做f或–file。

$ cat -f
$ cat --file
  • 1
  • 2

上面命令的原意是输出文件-f和–file的内容,但是会被 Bash 当作配置项解释。
**这时就可以使用配置项参数终止符–,告诉 Bash,在它后面的参数开头的-和–不是配置项,只能当作实体参数解释。 **

$ cat -- -f
$ cat -- --file
  • 1
  • 2

** 如果要确保某个变量不会被当作配置项解释,就要在它前面放上参数终止符–。 **

$ ls -- $myPath   #--强制变量$myPath只能当作实体参数(即路径名)解释
  • 1

如果变量不是路径名,就会报错:

$ myPath="-l"
$ ls -- $myPath
ls: 无法访问'-l': 没有那个文件或目录
  • 1
  • 2
  • 3

如果想在文件里面搜索–hello,这时也要使用参数终止符–。

$ grep --hello example.txt  //报错,没有--hello

$ grep -- hello example.txt  //寻找hello
  • 1
  • 2
  • 3

declare 命令 — 声明一些特殊类型的变量

declare命令可以声明一些特殊类型的变量,为变量设置一些限制,比如声明只读类型的变量和整数类型的变量:

declare OPTION VARIABLE=value
  • 1

:::danger
declare命令的主要参数(OPTION)如下:

  • -a:声明数组变量。

  • -f:输出所有函数定义。

  • -F:输出所有函数名。

  • -i:声明整数变量。

  • -l:声明变量为小写字母。

  • -p:查看变量信息。

  • -r:声明只读变量。

  • -u:声明变量为大写字母。

  • -x:该变量输出为环境变量。
    :::
    declare命令如果用在函数中,声明的变量只在函数内部有效,等同于local命令。不带任何参数时,declare命令输出当前环境的所有变量,包括函数在内,等同于不带有任何参数的set命令。

  • -i 参数声明整数变量以后,可以直接进行数学运算 【注意:赋值的时候直接不能有空格】

$ declare -i val1=12 val2=5
$ declare -i result
$ result=val1*val2
$ echo $result
60
  • 1
  • 2
  • 3
  • 4
  • 5

如果变量result不声明为整数,val1*val2会被当作字面量,不会进行整数运算。另外,val1和val2其实不需要声明为整数,因为只要result声明为整数,它的赋值就会自动解释为整数运算。
注意,一个变量声明为整数以后,依然可以被改写为字符串。

$ declare -i var=12
$ var=foo
$ echo $var
0
  • 1
  • 2
  • 3
  • 4

上面例子中,变量var声明为整数,覆盖以后,Bash 不会报错,但会赋以不确定的值,可能输出0,也可能输出的是3。

  • -x参数等同于export命令,可以输出一个变量为子 Shell 的环境变量。
$ declare -x foo
# 等同于
$ export foo
  • 1
  • 2
  • 3
  • -r参数可以声明只读变量,无法改变变量值,也不能unset变量。
echo "-r 声明的变量是只读变量,不能修改----"
declare -r con=1
con=2
echo $?             #看上一个指令的值

unset con
echo $?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
./declare.sh: 行 2: con:只读变量
1
./declare.sh: 第 6 行: unset: con:无法取消设定: 只读 variable
1
  • 1
  • 2
  • 3
  • 4

上面例子中,后两个赋值语句都会报错,命令执行失败。

  • -u参数声明变量为大写字母,可以自动把变量值转成大写字母。
$ declare -u foo
$ foo=upper
$ echo $foo
UPPER
  • 1
  • 2
  • 3
  • 4
  • -l参数声明变量为小写字母,可以自动把变量值转成小写字母。
$ declare -l bar
$ bar=LOWER
$ echo $bar
lower
  • 1
  • 2
  • 3
  • 4
  • -p参数输出变量信息。
$ foo=hello
$ declare -p foo
declare -- foo="hello"

$ declare -p bar
bar:未找到
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

上面例子中,declare -p可以输出已定义变量的值,对于未定义的变量,会提示找不到。
如果不提供变量名,declare -p输出所有变量的信息。

$ declare -p
  • 1
  • -f参数输出当前环境的所有函数,包括它的定义。
$ declare -f
  • 1
  • -F参数输出当前环境的所有函数名,不包含函数定义。
$ declare -F
  • 1
#!/bin/bash

function hello()
{
    echo "hello" 
}

function alice() {
  echo "alice: $@"
  echo "$0: $1 $2 $3 $4"
  echo "$# arguments"    #2个参数

}

echo "--------------------f------------------------------"
declare -f          #显示函数的定义
echo "--------------------F------------------------------"
declare -F          #仅会显示函数名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

image.png

readonly 命令 — 声明只读变量

readonly命令等同于declare -r,用来声明只读变量,不能改变变量值,也不能unset变量。

$ readonly foo=1
$ foo=2
$ echo $?
  • 1
  • 2
  • 3
./declare.sh: 行 2: dd:只读变量
1
  • 1
  • 2

:::danger
readonly命令有三个参数。

  • -f:声明的变量为函数名。
  • -p:打印出所有的只读变量。
  • -a:声明的变量为数组。
    :::

let 命令—可以直接执行算术表达式

let命令声明变量时,可以直接执行算术表达式:

$ let foo=1+2
$ echo $foo   #3
  • 1
  • 2

let命令的参数表达式如果包含空格,就需要使用引号:

$ let "foo = 1 + 2"
  • 1

let可以同时对多个变量赋值,赋值表达式之间使用空格分隔:

$ let "v1 = 1" "v2 = v1++"  #let声明变量v1和v2,其中v2等于v1++,表示先返回v1的值,然后v1自增
$ echo $v1,$v2  #2,1
  • 1
  • 2
#!/bin/bash
# 未进行shellcheck检查
a=5

let a+=2
echo "plus : $a "       # a = 7 和

let a-=2
echo "minus : $a"       # a = 5 差

let a*=2
echo "multi : $a"       # a = 10 积

let a/=2
echo "div : $a"         # a = 5 商

let a%=2
echo "Modulo : $a"      # a = 1 余数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

expr 命令—支持算术运算

支持算术运算

expr命令支持算术运算,可以不使用((…))语法:

$ expr 3 + 2  #5
  • 1

expr命令支持变量替换:

$ foo=3
$ expr $foo + 2 #5
  • 1
  • 2

expr命令也不支持非整数参数:

$ expr 3.5 + 2
expr: 非整数参数
  • 1
  • 2

image.png

字符串操作

expr length – 求字符串长度
$ echo `expr length $str`
  • 1

expr index – 求字符串索引
$ expr index "$string" '$substring'
  • 1

expr match – 匹配字符串

expr substr – 截取子串

具体将在字符串操作篇细讲

exit 命令 — 终止当前脚本的执行

exit命令用于终止当前脚本的执行,并向 Shell 返回一个退出值。

exit
  • 1

上面命令中止当前脚本,将最后一条命令的退出状态,作为整个脚本的退出状态。
exit命令后面可以跟参数,该参数就是退出状态。

# 退出值为0(成功)
$ exit 0

# 退出值为1(失败)
$ exit 1
  • 1
  • 2
  • 3
  • 4
  • 5

退出时,脚本会返回一个退出值。
:::danger
脚本的退出值,

  • 0表示正常,
  • 1表示发生错误,
  • 2表示用法不对,
  • 126表示不是可执行脚本,
  • 127表示命令没有发现。
  • 如果脚本被信号N终止,则退出值为128 + N。
    :::
    简单来说,只要退出值非0,就认为执行出错。

source 命令 — 执行一个脚本

source命令用于执行一个脚本,通常用于重新加载一个配置文件。

$ source .bashrc
  • 1

source命令最大的特点是在当前 Shell 执行脚本,不像直接执行脚本时,会新建一个子Shell。所以,source命令执行脚本时,不需要export变量。

# 当前 Shell 新建一个变量 foo
$ foo=1

# 打印输出 1
$ source test.sh
1

# 打印输出空字符串
$ bash test.sh
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上面例子中,当前 Shell 的变量foo并没有export,所以直接执行无法读取,但是source执行可以读取。
**source命令的另一个用途,是在脚本内部加载外部库。 **

#!/bin/bash

$ source ./lib.sh

function_from_lib
  • 1
  • 2
  • 3
  • 4
  • 5

上面脚本在内部使用source命令加载了一个外部库,然后就可以在脚本里面,使用这个外部库定义的函数。
source有一个简写形式,可以使用一个点(.)来表示。

$ . .bashrc
  • 1

变量

变量表示数据的方法。是计算机为了保存数据项而在内存中分配的一个位置或一组位置的标识或名字。
变量名就是保存值的地方。shell变量有系统变量和自定义变量两种。
对于变量名的声明规则类似于其他编程语言。由字母、数字、下划线组成,但不能以数字开头。

hello_123       # 合法
123_hello       # 不合法
  • 1
  • 2

内部变量(系统变量)

主要记录实际工作中使用的,也不要记住。用到了再查即可。可以通过env指令显示所有的环境变量

$ env 或者
$ printenv
  • 1
  • 2
系统变量说明备注
$BASH_VERSION查看bash的版本
$BASHbash的二进制程序文件的路径
$USER当前用户一般是root
$EUID有效用户ID E U I D 不一定与 EUID 不一定与 EUID不一定与UID相同
$FUNCTION在函数中,可直接打印当前函数的名字
$GROUP当前用户所属的组一个组ID列表
$HOSTNAME当前主机名字
$HOSTTYPE当前主机类型
$PATH可执行文件的搜索路径以冒号分隔的目录列表
PWD当前工作目录
BASHPIDBash 进程的进程 ID
SHELLshell名字
DISPLAY图形环境的显示器名字,通常是:0,表示 X Server 的第一个显示器。
EDITOR默认的文本编辑器
HOME用户的主目录
HOST当前主机的名称

image.pngimage.png
很多环境变量很少发生变化,而且是只读的,可以视为常量。由于它们的变量名全部都是大写,所以传统上,如果用户要自己定义一个常量,也会使用全部大写的变量名。
:::danger
注:Bash变量名区分大小写,HOME和home是两个不同的变量。
:::
查看单个环境变量的值,可以使用printenv命令或echo命令。

$ printenv PATH   #printenv命令后面的变量名,不用加前缀$
# 或者
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  • 1
  • 2
  • 3
  • 4

自定义变量

:::danger
用户创建变量的时候,变量名必须遵守下面的规则:

  • 字母、数字和下划线字符组成
  • 第一个字符必须是一个字母或一个下划线,不能是数字
  • 不允许出现空格和标点符号
  • 定义变量:变量名=变量值,等号两侧不能有空格(与其它语言可设空格的区别之处)。变量名一般习惯使用大写。
  • 设置变量:set 变量名=变量值。
  • 删除变量:unset 变量名=变量值。
  • 声明静态变量:readonly 变量名,静态变量不能用unset
  • 使用变量$变量名
  • 变量赋值
    • 简单赋值:a=123 && echo $a
    • 命令行赋值给变量#使用反引号 str=cat helloworld.sh _#直接使用 ( . . ) 格 式 o s = (..)格式_ os= (..)os=(cat /etc/os-release)
  • 局部变量:只在代码块或函数中可见可用。外部不可用。
  • Bash变量:不区分类型,都是字符串,不允许进行数值计算,除非变量中包含数字。
  • 如果变量的值中间有空格,则使用引号(单引号或双引号均可)扩起来。
    :::

输出变量

会影响用户接口和shell的行为。环境变量是一个全局变量。 用户创建的变量仅可用于当前Shell,子 Shell 默认读取不到父 Shell 定义的变量。为了把变量传递给子Shell,需要使用export命令。这样输出的变量,对于子Shell来说就是环境变量。
通过 export 命令将变量声明为环境变量即可。

export 变量名=变量值
# 方式 1 :直接export导入,命令行窗口重启后失效
export LD_LIBRARY_PATH=/usr/local/cuda/lib

# 方式 2
# 加入到 root目录下的 .bashrc 中
# 使用 source ./bashrc 使修改后的配置信息生效,命令行窗口重启或者机器重启均不会失效
# 查看环境变量是否生效
echo $变量名
echo $LD_LIBRARY_PATH
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对于环境变量的查看

# 方式 1 :查看所有变量(包括环境变量和自定义变量)
set
# 方式 2 :只能查看环境变量
env
  • 1
  • 2
  • 3
  • 4

引用变量

引用:将字符串使用双引号""扩起来。作用:保护字符串的特殊字符(通配符)不被shell重新解释或者扩展。

[root@centos8 data]# var01=3
[root@centos8 data]# echo $var01
3
  • 1
  • 2
  • 3

在引用变量时,**需要使用 来进行引用变量的值 ∗ ∗ 。 : : : d a n g e r 变量在使用过程中,如果没有 来进行引用变量的值**。 :::danger 变量在使用过程中,如果没有 来进行引用变量的值:::danger变量在使用过程中,如果没有作为前缀,需要思考如下情况:

  • 被声明或被赋值。
  • 是否被unset
  • 被使用export 方式导入
  • 是否作为信号量。
  • 赋值的两种方式:
    • 使用 = 方式。
    • 直接使用read命令。
      :::
bash$ ls -l [Vv]*
-rw-rw-r--    1 bozo  bozo       324 Apr  2 15:05 VIEWDATA.BAT
-rw-rw-r--    1 bozo  bozo       507 May  4 14:25 vartrace.sh
-rw-rw-r--    1 bozo  bozo       539 Apr 14 17:11 viewdata.sh

bash$ ls -l '[Vv]*'
ls: [Vv]*: No such file or directory
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看到,提示不存在该文件。这里的’[Vv]*被当成了文件名。 在日常沟通和写作中,当我们引用一个短语的时候,我们会将它单独隔开并赋予它特殊的意义,而在bash脚本中,当我们_引用_一个字符串,意味着保留它的_字面量_。

:::danger
使用双引号可以防止字符串被分割。即使参数中拥有很多空白分隔符,被包在双引号中后依旧是算作单一字符。

  • 当字符分割或者保留空白符出现问题时,才需要在echo语句中用双引号包住参数。
    :::
List="one two three"

for a in $List     # 空白符将变量分成几个部分。
do
  echo "$a"
done

echo "---"

for a in "$List"   # 在单一变量中保留所有空格。
do #     ^     ^
  echo "$a"
done
# one two three
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

:::danger
单引号(’ ')与双引号类似,但是在单引号中不能引用变量,因为 $ 不再具有特殊含义。在单引号中,除’之外的所有特殊字符都将会被直接按照字面意思解释。可以认为单引号(“全引用”)是双引号(“部分引用”)的一种更严格的形式。
:::

删除变量

unset命令用来删除一个变量:

unset NAME
  • 1

这个命令不是很有用。因为不存在的Bash变量一律等于空字符串,所以即使unset命令删除了变量,还是可以读取这个变量,值为空字符串。
所以,删除一个变量,也可以将这个变量设成空字符串。

$ foo=''
$ foo=  #由于不存在的值默认为空字符串,所以可以在等号右边不写任何值
  • 1
  • 2

特殊字符变量

shell中参数: 0 、 0、 0?、 ! 、 !、 ! 、 、 *、KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲、@

字符符号功能(用途)
$0shell文件本身的文件名
1 ~ 1~ 1n添加到Shell的各参数值。$1是第1参数、 2 是第 2 参数、 … 、 2是第2参数、…、 2是第2参数、n表示第n个参数。⚠️注意:10以上要用大括号,如{10}。
$?最后运行命令的结束代码(返回值),执行成功返回0,不成功则返回非零值(一般解释为错误码)。
$$Shell本身的PID(ProcessID)
$!Shell最后运行的后台Process的PID
$-使用Set命令设定的Flag一览
$*所有参数列表。如 "$*“用「”」括起来的情况、以"$1 $2 … $n" 的形式输出所有参数。
$@所有参数列表。如 "$@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
$#添加到Shell的参数个数
;;&, ;&case条件语句终止符
"’在参数替换中进行小写字母转换
`反引号
空命令。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/676164
推荐阅读
相关标签