Shell脚本的学习心得和知识总结(二)| 变量、表达式和运算符

2020年2月27日19:19:30

shell变量

shell变量详解

同其他编程语言一样,变量也是其中必不可少的组成部分,变量用来存放各种数据。脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则。在 Bash shell 中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。
:Bash shell 在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同,需要我们加以注意。

定义变量

如下:variable_name是变量名,variable_value是赋给变量的值。如果 variable_value不包含任何空白符(例如空格、Tab缩进等),那么可以不使用引号;如果 value 包含了空白符,那么就必须使用引号包围起来。使用单引号和使用双引号也是有区别的。

[root@localhost myshell_study]# 
[root@localhost myshell_study]# name=songjinzhou
[root@localhost myshell_study]# variable_name=variable_value
[root@localhost myshell_study]# variable_name='variable_value'
[root@localhost myshell_study]# variable_name="variable_value"

[root@localhost myshell_study]# variable_name=variable value   #这里有空格
bash: value: command not found...

注:赋值号的周围不能有空格;定义变量也最好联系实义

Shell 变量的命名规范和大部分编程语言都一样:

  • 变量名由数字、字母、下划线组成
  • 必须以字母或者下划线开头(不可以是数字开头
  • 不能使用 Shell 里的关键字(通过 help 命令可以查看保留关键字)

变量使用

[root@localhost myshell_study]# name=songjinzhou
[root@localhost myshell_study]# echo $name
songjinzhou
# 使用一个定义过的变量,只要在变量名前面加 $即可。上面打印的是变量值

[root@localhost myshell_study]# echo ${name}
songjinzhou

:上面的这种变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

[root@localhost myshell_study]# SQL=Postgres
[root@localhost myshell_study]# echo "Song does well in $SQLSql"
Song does well in 
[root@localhost myshell_study]# echo "Song does well in ${SQL}Sql"
Song does well in PostgresSql

因此,如果不给上面的 SQL变量加花括号,写成echo “Song does well in $SQLSql”,解释器就会把 $SQLSql当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。推荐给所有变量加上花括号{ },这是个良好的编程习惯。

使用单引号和使用双引号也是有区别的,如下:

[root@localhost myshell_study]# 
[root@localhost myshell_study]# name = song
bash: name: command not found...
[root@localhost myshell_study]# name=song
[root@localhost myshell_study]# echo My name is $name
My name is song
[root@localhost myshell_study]# echo 'My name is $name'
My name is $name
[root@localhost myshell_study]# echo "My name is $name"
My name is song

如上:以单引号’ ’ 包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

:如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。


反引号的使用,如下:
# Shell 也支持将命令的执行结果赋值给变量,常见的有以下两种方式:
variable_name=`命令`
variable_name=$(命令)

上面第一种方式把命令用反引号包围起来,反引号和单引号非常相似,容易产生混淆,所以不推荐使用这种方式;第二种方式把命令用$()包围起来,区分更加明显,所以推荐使用这种方式。

[root@localhost myshell_study]# ll
total 8
-rw-r--r--. 1 root root 144 Feb 26 03:13 count_user.sh
-rw-r--r--. 1 root root 385 Feb 26 23:55 test1
[root@localhost myshell_study]# ll > test2
[root@localhost myshell_study]# cat test2
total 8
-rw-r--r--. 1 root root 144 Feb 26 03:13 count_user.sh
-rw-r--r--. 1 root root 385 Feb 26 23:55 test1
-rw-r--r--. 1 root root   0 Feb 27 20:18 test2
[root@localhost myshell_study]# vim test2
[root@localhost myshell_study]# vim test2
[root@localhost myshell_study]# content='cat test2'   #这是单引号
[root@localhost myshell_study]# echo $content 
cat test2
[root@localhost myshell_study]# content=`cat test2`   #这是反引号
[root@localhost myshell_study]# echo $content //上面是把命令执行的结果 赋值变量
total 8 
-rw-r--r--. 1 root root 144 Feb 26 03:13 count_user.sh 
-rw-r--r--. 1 root root 385 Feb 26 23:55 test1 
-rw-r--r--. 1 root root   0 Feb 27 20:18 test2
----------------------------------------------------------------------
# 下面这种用的比较多
[root@localhost myshell_study]# pwd
/root/myshell_study
[root@localhost myshell_study]# name=$(pwd)
[root@localhost myshell_study]# echo $name 
/root/myshell_study

以当前日期时间为文件名字的,如下

[root@localhost myshell_study]# touch `date "+%F_%T"`.txt
[root@localhost myshell_study]# ll
total 12
-rw-r--r--. 1 root root   0 Feb 27 20:33 2020-02-27_20:33:34.txt

[root@localhost myshell_study]# touch $(date "+%F_%T").txt   #也是可以的

删除变量

使用 unset 命令可以删除变量。语法:unset variable_name
变量被删除后不能再次使用;unset 命令不能删除只读变量

[root@localhost myshell_study]# echo $name
/root/myshell_study
[root@localhost myshell_study]# unset name 
[root@localhost myshell_study]# echo $name

[root@localhost myshell_study]# 
----------------------------------------------
[root@localhost myshell_study]# readonly name=song  #定义只读变量
[root@localhost myshell_study]# echo $name
song
[root@localhost myshell_study]# unset name          #不能删除只读变量
bash: unset: name: cannot unset: readonly variable

变量类型

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

  1. 局部变量:局部变量在脚本或命令中定义,在当前shell实例中有效,其他shell启动的程序不能访问局部变量。(即使在当前shell下 开启一个bash也不行)
  2. 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。 (在当前shell下 开启一个bash行)
  3. shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。如下所示:

特殊变量列表(shell变量)

变量  含义

$0  当前脚本的文件名

$n  传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如第一个参数是$1,第二个参数是$2。

$#  传递给脚本或函数的参数个数。

$*  传递给脚本或函数的所有参数。

$?  上个命令的退出状态,或函数的返回值。(非0 都是错误)

$$  当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
[root@localhost myshell_study]# cat test3.sh 
#!/bin/bash
echo $0 为当前脚本的文件名

echo $1 为传递给脚本或函数的第一个参数
echo $2 为传递给脚本或函数的第二个参数

echo $# 为传递给脚本或函数的参数个数

echo $* 为传递的参数
[root@localhost myshell_study]# bash test3.sh 1 2
test3.sh 为当前脚本的文件名
1 为传递给脚本或函数的第一个参数
2 为传递给脚本或函数的第二个参数
2 为传递给脚本或函数的参数个数
1 2 为传递的参数

:$? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。其中退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。不过,也有一些命令返回其他值,表示不同类型的错误。

条件表达式

所谓条件表达式就是一个判断注:括号中的表达式前后都有空格,否则会报错!

条件表达式详解
表达式形式 实例
[ expression ] [ 1 -eq 1 ]
[[ expression ]] [[ 1 -eq 1 ]]
test expression test 1 -eq 1 ,等同于[]

整数比较符

整数比较符 描述 实例
-eq, equal 等于 [ 1 -eq 1 ] 为true
-ne, not equal 不等于 [ 1 -ne 1 ] 为false
-gt, greater than 大于 [ 1 -gt 1 ] 为false
-lt, less than 小于 [ 1 -lt 1 ] 为false
-ge, greater or equal 大于或者等于 [ 1 -ge 1 ] 为true
-le, less or equal 小于或者等于 [ 1 -le 1 ] 为true
[root@localhost myshell_study]# [ 1 -eq 1 ] && echo "等于"
等于
[root@localhost myshell_study]# [ 1 -eq 1 ] && echo "等于为真"
等于为真
[root@localhost myshell_study]# [ 1 -eq 2 ] && echo "等于为真"
[root@localhost myshell_study]# [ 1 -eq 2 ] && echo "等于为真" || echo "等于为假"
等于为假
[root@localhost myshell_study]# [ 1 -eq 1 ] || echo "等于为假"
[root@localhost myshell_study]# [ 1 -eq 2 ] || echo "0" || echo "1" && echo "2"
0
2
[root@localhost myshell_study]# [ 1 -eq 1 ] || echo "0" || echo "1" && echo "2"
2
[root@localhost myshell_study]# [ 1 -lt 2 ] && echo "0" || echo "1" 
0
[root@localhost myshell_study]# [ 1 -gt 2 ] && echo "0" || echo "1" 
1
[root@localhost myshell_study]# [ 1 -le 2 ] && echo "0" || echo "1" 
0

字符串比较符

字符串比较符 描述 实例
== 等于 [ “a” == “a” ] 为true
!= 不等于 [ “a” != “a” ] 为false
-n 字符串长度不等于0为真 VAR1=1;VAR2=""。[ -n “$ VAR1” ]为 true; [ -n “$ VAR2” ]为 false
-z 字符串长度等于0为真 VAR1=1;VAR2=""。[ -z “$ VAR1” ]为false;[ -z “$ VAR2” ]为 true
[root@localhost myshell_study]# name=song
[root@localhost myshell_study]# [ $name == song ] && echo "0" || echo "1"
0
[root@localhost myshell_study]# [ $name != song ] && echo "0" || echo "1"
1
[root@localhost myshell_study]# [ -z $name ] && echo "0" || echo "1"
1
[root@localhost myshell_study]# [ -n $name ] && echo "0" || echo "1"
0

注:使用-n 判断字符串长度时,变量要加双引号,养成好习惯,字符串比较时都加上双引号。如下

[root@localhost myshell_study]# [ -n $surname ] && echo "0" || echo "1"
0
# 加了双引号才能正常判断是否为空,因为变量是未定义的
[root@localhost myshell_study]# [ -n "$surname" ] && echo "0" || echo "1"
1

文件测试

文件测试符 描述 实例
-e 文件或者目录存在为真 [ -e path ] path 存在为 true
-f 文件存在为真 [ -f file_path ] 文件存在为 true
-d 目录存在为真 [ -d dir_path ] 目录存在为 true
-r 有读权限为真 [ -r file_path ]file_path有读权限为真
-w 有写权限为真 [ -r file_path ]file_path有写权限为真
-x 有执行权限为真 [ -r file_path ]file_path有执行权限为真
-s 如果文件或路径存在且非空 [ -r file_path ]file_path存在且非空为真
[root@localhost myshell_study]# [ -f /etc/passwd ] && echo "0" || echo "1"
0
[root@localhost myshell_study]# [ -d /etc/passwd ] && echo "0" || echo "1"
1
[root@localhost myshell_study]# [ -e /etc/passwd ] && echo "0" || echo "1"
0

布尔运算符

布尔运算符 描述 实例
非关系,条件结果取反 [ ! 1 -eq 2 ]为true
-a 和关系,在[]表达式中使用 [ 1 -eq 1 -a 2 -eq 2 ]为true,两者都为真才为真
-o 或关系,在[]表达式中使用 [ 1 -eq 1 -o 2 -eq 1 ]为true,两者有一真则为真
[root@localhost myshell_study]# [ 1 -eq 2 -o 2 -ne 3 ] && echo "0" || echo "1"
0
[root@localhost myshell_study]# if [ $? -eq 0 ];then echo "上个命令执行成功"; else echo "上个命令执行失败";fi
上个命令执行成功

逻辑判断符

逻辑判断符 描述 实例
&& 逻辑和,在[[]]表达式中或判断表达式是否为真时使用 [[ 1 -eq 1 && 2 -eq 2 ]]为 true。[ 1 -eq 1 ] && echo ‘true’,如果&&前面的表达式为true则执行后面的
\ \站直 逻辑或,在[[]]表达式中。或判断表达式是否为真时使用 [[ 1 -eq 1 \ \ 2 -eq 1 ]]为 true。[ 1 -eq 2 ] \ \ echo ‘true’,如果\ \前面的表达式为false则执行后面的

注:[ ] 不支持以上两个逻辑判断符,应该使用布尔运算符!

shell计算

五种运算:+ - * / %。其中两种运算表达式如下(二选一即可):

$(())
$[]

具体实例如下:

[root@localhost myshell_study]# x1=$((1+1))
[root@localhost myshell_study]# echo $x1
2
[root@localhost myshell_study]# x2=$[1+2]
[root@localhost myshell_study]# echo $x2
3
[root@localhost myshell_study]# x3=$[7/2]
[root@localhost myshell_study]# echo $x3
3

其他运算工具

在这里插入图片描述

[root@localhost myshell_study]# echo $x3
3
[root@localhost myshell_study]# let x3++
[root@localhost myshell_study]# echo $x3
4
[root@localhost myshell_study]# let ++x3
[root@localhost myshell_study]# echo $x3
5

在这里插入图片描述

[root@localhost myshell_study]# ls
[root@localhost myshell_study]# touch {1..4}.txt
[root@localhost myshell_study]# ls
1.txt  2.txt  3.txt  4.txt

猜你喜欢

转载自blog.csdn.net/weixin_43949535/article/details/104542946