shell编程

发布时间:2023年12月28日

shell变量

  • 变量定义与赋值,变量与值之间不得有空格

name="ni"

变量名

变量类型:bash默认把所有的变量都认为是字符串

bash变量是弱类型,无需事先声明类型,是将声明和赋值同时进行。?

  • 变量替换/引用

[root@localhost ~]# name="ni"
[root@localhost ~]# echo ${name}
ni
[root@localhost ~]# cho $name ? #可以省略花括号

ni?

  • 变量命名规则
  1. 名称定义要做到见名知意,切按照规则来,切不得引用保留关键字(help检查保留字)
  2. 只能包含数字、字母、下划线
  3. 不能以数字开头
  4. 不能用标点符号
  5. 变量严格区分大小写
  • 变量的作用域?

单引号:不识别特殊符号

双引号:可以识别特殊符号?

反引号:会将命令的执行结果返回给变量

无引号:连续的符号可以不加引号,有空格则有歧义,最好使用双引号

本地变量,只针对当前的shell进程?

?pstree检查进程树

?

环境变量:也称为全局变量,针对当前shell以及其任意子进程,环境变量也分自定义、内置两种环境变量

局部变量:针对shell函数或是shell脚本中定义

位置参数变量:用于shell脚本中传递的参数。

特殊变量:shell内置的特殊功效变量

$?? ?:? 用于判断上一条命令是否执行成功

? ? ?0:成功

? ? ?1-255:错误码

自定义变量

  • 变量赋值: name=ni
  • 变量引用:${name}、$name?

? ? ? ? ? ? ? 双引号,会识别特殊符号

[root@localhost ~]# echo $name
ni
[root@localhost ~]# name2="$name"
[root@localhost ~]# echo $name2
ni?

?不同的执行方式,不同的shell环境

解答:

1.每次调用bash/sh都会开启一个子shell,因此不保留当前shell变量,通过pstree命令检查进程树

2.调用source是在当前shell环境加载脚本,因此保留变量。

?环境变量设置

环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。

环境变量可以在命令行中临死创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件

? ?用户个人配置文件 ~/.bash_profile、~/.bashrc远程登录用户特有文件

? ?全局配置文件 /etc/profile、/etc/bashrc,且系统建议最好创建在/etc/profile.d/,而非直接修改主文件,修改全局配置文件,影响所有登录系统用户

检查系统环境变量的命令?

  • set:输出所有变量,包括全局变量、局部变量
  • env:只显示全局变量
  • declare:输出所有的变量,如同set
  • export: 显示和设置环境变量的值

撤销环境变量?

  • unset 变量名,删除变量或函数

设置只读变量

reaonly name="ni"

?readonly:不能修改变量的值,只有shell结束,只读变量失效。

bash多命令执行?

[root@localhost ~]# ls; cd /? #使用;号来分隔

特殊变量?

shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量

$0? ? ? ? 获取shell脚本文件名,以及脚本路径

$n? ? ? ? 获取shell脚本的第n个参数,n在1-9之间,如$1,$2,$9,大于9则需要写,${10},? ? ? ? ? ? ? 参数空格隔开。?

$#? ? ? ? 获取执行的shell脚本后面的参数总个数

$*? ? ? ? 获取shell脚本所有参数,不加双引号等同于$@作用,加上引号"$*"作用是:接收所? ? ? ? ? ? ? ? 有参数为一个字符串(即所用参数都在一个字符串中)

$@? ? ? 不加引号,效果同上,加引号,是接收所有参数为独立字符串(一个参数是一个字? ? ? ? ? ? ? ? 符串),如"$1" "$2" "$3" ..., 空格保留

特殊状态变量?

$?? ? ? ? 上次命令执行状态返回值,0正确,非0失败

$$? ? ? ? 当前shell脚本的进程号

$!? ? ? ? ?上一次后台进程的PID

$_? ? ? ? 再次之前执行的命令,最后一个参数?

Shell子串?

bash一些基础的内置命名

echo

eval

exec

export

read

shift?

echo命令

-n? ?不换行输出

-e? ?解析字符串中的特殊符号

\n? ?换行

\r? ? 回车

\t? ? ?制表符? 4个空格

\b? ? 退格

eval命令

执行多个命令

[root@localhost ~]# eval cd /;ls
backup ?bin ?boot ?data ?dev ?etc ?home ?lib ?lib64 ?media ?mnt ?opt ?proc ?root ?run ?sbin ?srv ?sys ?tmp ?usr ?var
[root@localhost /]# ls
backup ?bin ?boot ?data ?dev ?etc ?home ?lib ?lib64 ?media ?mnt ?opt ?proc ?root ?run ?sbin ?srv ?sys ?tmp ?usr ?var?

exec命令

不创建子进程,执行后续命令,且执行完毕后,自动exit。

read命令

[root@localhost ~]# read[选项][变量名]

选项

-p "提示信息“在等待read输入时,输出提示信息
-t 秒数read命令会一直等待用户输入,使用此选项可以制定等待时间
-n 字符数read命令值接受指定的字符数,就会执行
-s隐藏输入的数据,适用于机密信息的输入
#!/bin/bash
#Author: mlz
 
read -t 30 -p "Please input your name:" name
#提示“请输入姓名”并等待30秒,把用户的输入保存入变量name中
 
echo "Name is $name"
 
read -s -t 30 -p "Please enter your ege: " age
#年龄是隐私,所以我们用“-s”选项隐藏输入
 
echo "Age is $age"
echo -e "\n"
 
read -n 1 -t 30 -p "Please select your gender[M/F]: " gender
#使用“-n l”选项只接收一个输入字符就会执行(都不用输入回车)
 
echo -e "\n"
echo "Sex is $gender"

?shell子串的花式用法

${变量}? ? ? ? ? ? ?返回变量值

${#name}? ? ? ? ?返回变量长度,相当于java中的String.length()方法

${变量:start}? ? ?返回变量start数值之后的字符串,且包含start的数字(下标从0开始,类似于? ? ? ? ? ? ? ? ? ? ? ? ? ?java中的substring()方法)?

${变量:start:length}? ?返回变量start数值之后的字符串直到这个字符串长度等于length,且包? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 含start的数字(下标从0开始,类似于ava中的substring()方法) .

${变量#word}? ? ? 从变量前缀删除最短匹配的word子串

${变量##word}? ? 从变量前缀删除最长匹配的word子串

${变量%word}? ? ? 从变量结尾删除最短匹配的word子串

${变量%%word}? ? 从变量结尾删除最长匹配的word子串

${变量/pattern/string}? ? 用string代替第一个匹配的pattern

${变量//pattern/string}? ?用string代替所有的pattern

[root@localhost /]# name=abcAHHIOac
[root@localhost /]# echo $name
abcAHHIOac
[root@localhost /]# echo ${name#a*c}
AHHIOac
[root@localhost /]# echo ${name##a*c}

[root@localhost /]# 

?特殊shell拓展变量

这4个扩展变量,都属于对变量的值进行判断、处理

如果parameter变量值为空,返回word字符串,赋值给result变量(即将word的值返回给result),如果不为空则把parameter赋值给result

result=${parameter:-word}

如果parameter变量为空,则word代替变量值,且返回其值。(即word值赋给parameter,然后将word的值返回给result),如果不为空则把parameter赋值给result

result=${parameter:=word}

如果parameter变量为空,word当作stder输出,否则输出变量值

用于设置变量为空导致错误时,返回的错误信息

${parameter:?word}

如果parameter变量为空,什么都不做,否则Word返回

${parameter:+word}

shell的特殊符号整理

${变量}? ? ? ?取出变量结果

$()? ? ? ? ? ? ? ?在括号中执行命令,且拿到命令的执行结果。

``? ? ? ? ? ? ? ? ?在括号中执行命令,且拿到命令的执行结果。

()? ? ? ? ? ? ? ? 开启子shell执行命令结果

$变量? ? ? ? ??取出变量结果

shell数学运算

expr模式匹配

expr命令也支持模式匹配功能

2个特殊符号

:冒号,计算字符串的字符数量

.*? 任意的字符重复0次或者多次。

语法

expr 字符串 ":" ".*"

求长度:expr length

expr计算用于整数,有些运算符需要转译?

xufan@cengdongdeiMac Documents % expr 3 \* 2
6
xufan@cengdongdeiMac Documents % expr 3 + 2
5

expr命令判断文件名后缀是否合法?

执行脚本,传入一个文件名,然后判断该文件是否是jpg图片文件。?

#!/bin/bash

#从参数1中匹配一个字符串以.jpg结尾,并返回匹配上的字符串的长度,并且将输出写入到黑洞文件中
if expr "$1" ":" ".*\.jpg" &> /dev/null
   then
   	   echo "这的确是以jpg结尾的文件~"
else
	echo "这不是jpg文件"
fi

bc命令

bc命令当做计算器来用的,命令行的计算器

把计算式子通过管道符传给bc命令

xufan@cengdongdeiMac Documents % re=`echo "$num*3" | bc`
xufan@cengdongdeiMac Documents % echo $re
9

awk计算

awk既支持整数也支持小数计算

awk支持if条件判断,数组等等

xufan@cengdongdeiMac Documents % echo "3.2 2.2" | awk '{print $1+$2}'
5.4

?注意:

当你使用?echo "3.2 2.2" | awk '{print $1+$2}'?这个命令时,你实际上是将字符串 "3.2 2.2" 传递给?awk?命令来处理。在这个上下文中,单引号和双引号的使用是有特定的意义的。

  1. 双引号 (" "): 在双引号内的内容会被 shell 解释,这意味着其中的变量和特殊字符(如?$)会被扩展或解释。
  2. 单引号 (' '): 在单引号内的内容不会被 shell 解释,而是被当作纯文本。

在你给出的命令中,awk?命令是用单引号包围的,这意味着其中的内容({print $1+$2})会被?awk?解释,而不是 shell。这个?awk?脚本的意思是:取第一列($1,即 "3.2")和第二列($2,即 "2.2"),然后将它们相加。

如果你使用双引号来包围?awk?命令,如?awk "{print $1+$2}",这可能会导致问题,因为 shell 会尝试解释?$1?和?$2,而在这个上下文中,它们并没有定义。所以,为了避免这种解释,我们通常使用单引号来包围?awk?的脚本部分。

总之,单引号在这里确保?awk?脚本被正确地传递给?awk?命令,而不是被 shell 提前解释。

中括号运算?

$[运算式]

xufan@cengdongdeiMac Documents % echo $[4*2]
8

?shell的条件测试

条件测试常用的语法

test条件测试?

test命令评估一个表达式,他的结果是真,还是假,如果条件为真,那么命令执行状态码结果就为0,否则就是不为0,通过$?取值

test的语法参数大全

语法

. 关于某个文件名的「类型」侦测(存在与否),如test -e filename

1.针对文件类型判断真假

2.关于文件的权限侦测,如 test -r filename?

3.两个文件之间的比较, 如:test file1 -nt file2

4.关于两个整数之间的判定,例如 test n1 -eq n2?

5.判断字符串的数据

6.多重条件判定,例如:test -r filename -a -x filename

在shell中,对于真假判断的逻辑,提供&& 与运算? ||或运算

A条件 && B条件:当A条件成立,并且执行B条件

A条件||B条件:当A条件不成立的时候,才会执行B条件。

?中括号的条件测试[ ]

脚本中经常进行条件测试,用的最多的,都是中括号[ ]

test和[ ]的作用是一样

注意的点:

1.中括号,前后的空格必须有

2.在条件测试中取变量必须添加双引号

[ -f "$filename" ]

单中括号与双中括号区别

  1. 字符串比较:在单中括号中,字符串比较使用=!=,而在双中括号中,字符串比较也支持其他操作符,如-eq,?-ne,?-gt,?-lt,?-ge,?-le等。
  2. 模式匹配:双中括号允许使用正则表达式进行模式匹配,而单中括号不支持。
  3. 扩展性:双中括号会对shell元字符进行扩展,而单中括号不会。这意味着在双中括号中,如果字符串值含有shell元字符,Bash会对它进行扩展。(像在双中括号中就不需要对>、<等符号j进行转译)
  4. 变量扩展:单中括号的TEST命令会对变量进行单词分离,当变量值包含空白符时,要用引号将变量括起来。而双括号的TEST命令不会对变量进行单词分离。

shell中if判断?

单分支if

if? <条件表达式>

? ?then

? ? ? ?代码...

fi

简化

if? <条件表达式>;then

? ? 代码..

fi?

文章来源:https://blog.csdn.net/weixin_54401017/article/details/135203720
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。