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

相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试