shell编程

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 隐藏输入的数据,适用于机密信息的输入
bash 复制代码
#!/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

bash 复制代码
[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计算用于整数,有些运算符需要转译

bash 复制代码
xufan@cengdongdeiMac Documents % expr 3 \* 2
6
xufan@cengdongdeiMac Documents % expr 3 + 2
5

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

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

bash 复制代码
#!/bin/bash

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

bc命令

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

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

bash 复制代码
xufan@cengdongdeiMac Documents % re=`echo "$num*3" | bc`
xufan@cengdongdeiMac Documents % echo $re
9

awk计算

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

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

bash 复制代码
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 提前解释。

中括号运算

$[运算式]

bash 复制代码
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

相关推荐
奋斗吧程序媛3 分钟前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿13 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256562 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@2 小时前
HTML5适配手机
前端·html·html5
@解忧杂货铺4 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
F-2H6 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
gqkmiss6 小时前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247559 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255029 小时前
前端常用算法集合
前端·算法
真的很上进9 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html