Liunx高级程序设计-Shell

引入

完成以下任务 :
判断用户家目录下( ~ )下面有没有一个叫 test 的文件夹
如果没有,提示按 y 创建并进入此文件夹,按 n 退出
如果有,直接进入,提示请输入一个字符串,并按此字符串创建一个文件,如果此
文件已存在,提示重新输入,重复三次自动退出,不存在创建完毕,退出
简单的进行命令堆积无法完成以上任务,这就需要学习相应的 shell 脚本语法规则了
简介
Shell 的概念
是一种应用程序 , 也是一种设计语言
作为应用程序
系统分为 , 硬件层 ,Liunx 系统层 ,Shell, 应用程序层 , 如图 1
此时 Shell 的作用是沟通应用程序层与 Liunx 系统层 , Shell 解析器
Shell 解析器常用的有三种 , 分别是 sh,ash,bash, 一般情况下使用 bash
可以使用 echo $SHELL 查看使用的那种解析器 , 如图 2
作为设计语言
概念 :shell 脚本语言 , 不需要编译 , 直接解析执行 ( 批处理 )
优点 : 简化我们对系统的管理与应用程序的部署过程
名词 :
批处理 : 大量的循环的数据处理 , 如扫描当前根目录下是否存在 a.txt, 此时需要在
当前根目录所有文件夹中一一寻找
脚本语言 : 我们只需使用任意文本编辑器,按照语法编写相应程序 , 增加可执行权
, 即可在安装 shell 命令解释器的环境下执行的代码语言 , python,html,css
Shell 脚本的分类
系统调用
这类脚本无需用户调用,系统会在合适的时候调用,如: /etc/profile
~/.bashrc
/etc/profile:
此文件为系统的每个用户设置环境信息 , 当用户第一次登录时 , 该文件被执行 ,
系统的公共环境变量在这里设置
开机自启动的程序,一般也在这里设置
注意 : 如果在该文件中配置 , 需要从新登录用户才可生效
~/.bashrc
用户自己的家目录中的 .bashrc
登录时会自动调用,打开任意终端时也会自动调用
这个文件一般设置与个人用户有关的环境变量,如交叉编译器的路径等等
/etc/profile ~/.bashrc 的关系 , 如下图
用户编写
需要手动调用
注意 : 无论是系统调用的还是需要我们自己调用的,其语法规则都一样

第一个Shell脚本

1, 创建 Hello.sh 文件
2, 编写以下代码
#!/bin/bash
echo "Hello Shall"
3, 执行 hello.sh 文件
./Hello.sh
说明:
#! 用来声明脚本由什么 shell 解释,否则使用默认 shell
# 表示注释本行
注意:
创建文件时 :
如果是在 windows 中创建编写的 Shell 脚本文件 , 拖拽到 Liunx 下无法运行 , 因为
Windows Liunx \ 表示的含义不同 , 所以导致程序无法被识别
解决方案 1:
Liunx 中使用 vim 编辑器 , 在最后一行模式输入 set ff=unix
解决方案 2:
Linux 中安装 dos2unix, 使用 dos2unix 转换
步骤 :
1, 命令行输入 :sudo apt-age install dos2unix
2, 命令行输入 :dos2unix 文件地址
编写代码 :
# 注释
#! 用来声明脚本由什么 shell 解释,否则使用默认 shell
echo 输出
执行脚本方式 :
方式 1: 使用 sh bash
sh 文件路径
bash 文件路径
方式 2:./ 文件路径
需要可执行权限 , 添加权限命令 :chmod +x 文件路径
+ 增加权限
- 减少权限
x: 可执行
以上方式会开启子 Shell
:
chmod +x hishell.sh
方式 3:source 文件名或 . 文件名
source 文件路径 借鉴 cshell
. 文件路径 借鉴 bash
以上方式不会开启子 Shell
开启子 Shell 与不开启的区别
开启子 Shell , Shell 中的变量父 Shell 不可见
区别 :
./ bash 执行过程基本一致,
bash 明确指定 bash 解释器去执行脚本,脚本中 #! 指定的解释器不起作用
./ 前者首先检测 #! ,使用 #! 指定的 shell ,如果没有使用默认的 shell
./ bash 去执行会在后台启动一个新的 shell 去执行脚本
. 去执行脚本不会启动新的 shell, 直接由当前的 shell 去解释执行脚本

变量

分类

按是否为系统提供分类
系统变量
自定义变量
按作用范围分类
全局变量 : 当前 Shell 中的所有 Shell 都可使用 ( 自己与其中的子 Shell)
局部变量 : 当前 Shell 中使用 ( 自己使用 )
系统预定义变量
常用系统变量
:HOME,PWD,SHELL,USER
查看系统变量的值
语法 :
echo 变量名
:
echo $HOME
显示系统中的全局变量
语法 :
env printenv
:
env
printenv
显示当前 Shell 中的所有变量
语法 :
set
:
set

自定义变量

基本语法
定义变量 :
变量名 = 变量值 ;
注意 :
= 号前后不能有空格
声明的变量为局部变量
撤销变量
unset 变量名
声明只读变量
语法 :
readonly 变量
注意 :
只读变量不能撤销 , 不能修改值
示例 :
#!/bin/bash
readonly num=10
#unset num
num=100
echo $num
引用变量
$ 变量名
注意 : 如果变量不存在返回空
导出变量
作用 :
将当前变量导入到系统变量中
语法 :
export 变量名
注意 :
只在当前终端有效
需要使用 source . 执行
示例 :
代码
export DATA=1000
运行
source 文件路径
查看变量
env
declare -i: 将变量强制转换为数字
#!/bin/bash
# 注意 : 必须使用 ./ 运行
declare -i DATA=1
DATA=$DATA+1
echo $DATA
定义规则
1, 变量名由字母 , 数字 , 下划线组成 , 能不能使用数字开头 , 环境变量名不建议大写
2,= 号两侧不能有空格
3, bash , 变量默认类型为都是字符 , 无法直接进行数值运算
4, 变量值如果有空格 , 需要使用双引号或单引号包裹
注意 :"" '' 的区别
"" 会解析变量值
'' 不会解析变量值
示例 :
#!/bin/bash
num=1000
echo "num=$num"
echo 'num=$num'

预设变量

$# :传给 shell 脚本参数的数量
$* :传给 shell 脚本参数的内容
$1 $2 $3 ... $9 :运行脚本时传递给其的参数,用空格隔开
$? :命令执行后返回的状态
"$?" 用于检查上一个命令执行是否正确 ( Linux 中,命令退出状态为 0 表示该命令
正确执行,任何非 0 值表示命
令出错 )
$0 :当前执行的进程名
$$ :当前进程的进程号
"$$" 变量最常见的用途是用作临时文件的名字以保证临时文件不会重复
示例
#!/bin/bash
# 执行命令sh ./07_code.sh a b c
echo "参数个数:$#"
echo "参数内容:$*"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "第三个参数:$3"
#ps是用来查看系统进程的命令 -A
#常用参数
#-A 显示所有进程(同-e)
#-a 显示当前终端的所有进程
#-u 显示进程的用户信息
#-o 以用户自定义形式显示进程信息
#-f 显示程序间的关系
ps -A | grep bash
echo "指令结果:$?"
echo "进程名称:$0"
echo "进程号:$$"

脚本变量的特殊用法

"": 包含的变量会被解释
'': 包含的变量会作为字符串处理
``: 反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量
\: c 语言 \n \t \r \a echo 命令需加 -e 转义 (bash 解析器需求 )
( 命令 ): 由子 shell 来完成 , 不影响当前 shell 中的变量 , 命令前后必须有空格
{ 命令 }: 在当前 shell 中执行 , 会影响当前变量 , 命令前后必须有空格
示例
#!/bin/bash
num=100;
echo "num=$num"
echo 'num=$num'
echo "当前时间:`date`"
echo '当前时间:`date`'
echo -e "abc\n123"
echo -e "##\n##"
(
num=1000
echo "()内打印num变量:$num"
)
echo "()外打印num变量:$num"
{
num=1
echo "{}内打印num变量:$num"
}
echo "{}外打印num变量:$num"

键盘录入

输入

read 变量名
read -p 提示内容 变量名
#!/bin/bash
num=0
# echo "请输入一个数:"
# read num
# 或
read -p "请输入一个数:" num
echo "num=$num"

条件测试语句

语法

语法 1:test 条件
语法 2:[ 条件 ]、
注意 : 条件前后必须有空格

文件测试

文件测试:测试文件状态的条件表达式
-e 是否存在
-d 是否为目录
-f 是否为文件
-r 是否可读
-w 是否可写
-x 是否可执行
-L 是否连接
-c 是否字符设备
-b 是否块设备
-s 文件非空
#!/bin/bash
read -p "请输入文件名:" fileName
#-e:测试文件是否存在
test -e $fileName
echo "是否存在:$?"
#-f是否为文件
test -f $fileName
echo "是文件吗:$?"
#-d是否为文件夹
test -d $fileName
echo "是文件夹吗:$?"
#-r是否可读
[ -r $fileName ]
echo "是否可读:$?"
#-w是否可读
[ -w $fileName ]
echo "是否可写:$?"
#-x是否可执行
[ -x $fileName ]
echo "是否可执行:$?"

字符串测试

= 两个字符串相等
!= 两个字符串不相等
-z 空串
-n 非空串
注意 := != 前后要有空格
#!/bin/bash
str01="hello"
str02="world"
str03="hello"
[ $str01 = $str02 ]
echo "str01等于str02:$?"
[ $str01 = $str03 ]
echo "str01等于str03:$?"
test $str01 != $str02
echo "str01不等于str02:$?"
test $str01 != $str03
echo "str01不等于str03:$?"
[ -z $str01 ]
echo "str01是否是空串:$?"
[ -n $str01 ]
echo "str01是否不是空串:$?"

数值测试

-eq 数值相等
-ne 数值不相等
-gt 1 大于数 2
-ge 1 大于等于数 2
-le 1 小于等于数 2
-lt 1 小于数 2
#!/bin/bash
num01=10
num02=3
# -eq 数值相等
test $num01 -eq $num02
echo "num01等于num02:$?"
# -ne 数值不相等
test $num01 -ne $num02
echo "num01不等于num02:$?"
# -gt 数 1 大于数 2
test $num01 -gt $num02
echo "num01大于num02:$?"
# -ge 数 1 大于等于数 2
[ $num01 -ge $num02 ]
echo "num01大于等于num02:$?"
# -le 数 1 小于等于数 2
[ $num01 -le $num02 ]
echo "num01小于等于num02:$?"
# -lt 数 1 小于数 2
[ $num01 -lt $num02 ]
echo "num01小于num02:$?"

扩展

#${num:-val} 如果num存在,返回num,否则返回val
echo ${x:-10}
#${num:=val} 如果num存在,返回num,否则返回val,并将val赋值给num
echo ${y:=10}
echo $y

复合测试

&&
command1 && command2
&& 左边命令( command1 )执行成功 ( 即返回 0 shell 才执行 && 右边的命令
command2
||
command1 || command2
|| 左边的命令( command1 )未执行成功 ( 即返回非 0 shell 才执行 || 右边的命令
command2
#!/bin/bash
#输入一个数判断是否在0~100之间
read -p "请输入一个数" num
test $num -gt 0 && test $num -lt 100
echo "$num 是否在0~100之间:$?"

多重条件

-a:
-o:
!:
#!/bin/bash
#输入文件名称,判断文件是否可读可写可执行
read -p "请输入文件名称" fileName
test -r $fileName -a -w $fileName -a -x $fileName
echo "文件可读可写可执行:$?"
test -r $fileName -o -w $fileName
echo "文件可读或可写:$?"
test ! -x $fileName
echo "文件是否不可执行:$?"

控制语句

if语句

if[条件一];then

        执行第一段程序

else
        执行第二段程序

fi

num01=10
num02=16
#获取两数最大值
if [ $num01 -gt $num02 ];then
echo $num01
else
echo $num02
fi
if [ 条件1 ];then
执行第1段程序
elif [ 条件2 ];then
执行第2段程序
elif [ 条件3 ];then
执行第3段程序
...
else
执行第n段程序
fi
#!/bin/bash
read -p "请输入考试成绩" score
if [ $score -lt 0 -o $score -gt 100 ];then
echo "成绩不应小于0,或大于100"
elif [ $score -lt 60 ];then
echo "D"
elif [ $score -lt 70 ];then
echo "C"
elif [ $score -lt 85 ];then
echo "B"
else
echo "A"
fi
#!/bin/bash
#键盘输入一个文件名,判断是否存在改文件,
#如果存在显示文件内容
#如果不存在 创建该文件,并输入内容且输出文件内容。
read -p "请输入文件名称" fileName
#-e:是否存在
if [ -e $fileName ];then
#-d:是否为文件夹
#-o:或
#-s:是否为空文件
if [ -d $fileName -o -s $fileName ];then
echo "是文件夹或空文件"
else
cat $fileName
fi
else
#touch 创建文件
touch $fileName
read -p "请输入内容" info
#echo 输出的内容 >> 输出的地方,默认为控制台
echo $info >> $fileName
#cat 读取文件内容
cat $fileName
fi

case语句

语法:
case $ 变量名 in
" 1")
语句 1
;;
" 2")
语句 2
;;
*)
语句 3
;;
esac
扩展 :
exit 1 # 退出 shell
#!/bin/bash
read -p "是否继续" tag
case $tag in
"yes" | "YES")
#y* 以小写y开头
echo "继续"
;;
"no" | "NO")
echo "退出"
;;
*)
echo "输入有误"
;;
esac
#!/bin/bash
read -p "是否继续" tag
case $tag in
y* | Y*)
#y* 以小写y开头
echo "继续"
;;
n* | N*)
echo "退出"
;;
*)
echo "输入有误"
;;
esac

for语句

语法:
for (( 初始值 ; 限制值 ; 执行步阶 ))
do
程序段
done
#!/bin/bash
#计算100以内数之和
#declare -i s强制将s作为int型数值,需要使用./运行
declare -i s=0
declare -i sum=0
for (( s=0; s<=100; s++ ))
do
sum=$sum+$s;
done
echo $sum

语法2:

for var in con1 con2 con3 ...
do
程序段
done
#!/bin/bash
str01="A"
str02="B"
str03="C"
for v in $str01 $str02 $str03
do
echo $v
done
#!/bin/bash
#遍历文件夹
for fileName in `ls`
do
if [ -d $fileName ];then
echo "$fileName 是文件夹"
elif [ -f $fileName ];then
echo "$fileName 是文件"
fi
done

while语句

语法:
while [ 条件 ]
do
程序段
done
#!/bin/bash
declare -i i=0
declare -i sum=0
while [ $i -le 100 ]
do
sum=$sum+$i
i=$i+1
done
echo $sum

扩展:

变量名 =$(( 1 + 2 ))
变量名 =$(( 1 - 2 ))
变量名 =$(( 1 * 2 ))
变量名 =$(( 1 / 2 ))
变量名 =$(( 1 % 2 ))
变量名 =$(( 变量名 -- ))
变量名 =$(( -- 变量名 ))
变量名 =$(( 变量名 ++ ))
变量名 =$(( ++ 变量名 ))
变量名 =$(( -10 > 1 ? 10 : 1 ))

until语句

语法
until [ condition ]
do
程序段
done
这种方式与 while 恰恰相反,当 condition 成立的时候退出循环,否则继续循环。
#!/bin/bash
declare -i i=100
declare -i sum=0
#lt小于
until [ $i -lt 0 ]
do
sum=$sum+$i;
i=$i-1
done
echo $sum

函数

语法:

1, 定义
2, 调用
定义:
语法 1
函数名 (){
程序段
}
语法 2
function 函数名 (){
程序段
}
调用:
语法
函数名 参数 1 参数 2
#!/bin/bash
#函数定义
add(){
declare -i num=0
num=$1+$2
return $num
}
#函数调用
add 10 2
#获取结果输出
echo "返回值为:$?"

注意:
 

当函数定义与函数调用不在一个文件中需要在函数调用所在的文件中使用 source 引用函
数定义的文件
#myfun.sh定义函数
#!/bin/bash
function add(){
declare -i num=0
num=$1+$2
return $num
}
#24_code.sh调用函数
#!/bin/bash
#导入函数所在的文件
source myfun.sh
add 1 2
echo $?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/196387.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仅 CSS 阅读进度条

为了构建一个阅读进度条&#xff0c;即显示用户向下滚动时阅读文章的进度&#xff0c;很难不考虑 JavaScript。但是&#xff0c;事实证明&#xff0c;您也可以使用纯 CSS 构建阅读进度条。 从本质上讲&#xff0c;一个名为 animation-timeline 的新实验性 CSS 属性可以让你指定…

Metasploit的网络流量分析和嗅探

预计更新 第一章 Metasploit的使用和配置 1.1 安装和配置Metasploit 1.2 Metasploit的基础命令和选项 1.3 高级选项和配置 第二章 渗透测试的漏洞利用和攻击方法 1.1 渗透测试中常见的漏洞类型和利用方法 1.2 Metasploit的漏洞利用模块和选项 1.3 模块编写和自定义 第三章 Me…

Pytest 使用及调用方法

使用python -m pytest调用pytest 2.0版本新增 你可以在命令行中通过Python编译器来调用Pytest执行测试: python -m pytest [...] 通过python调用会将当前目录也添加到sys.path中,除此之外,这几乎等同于命令行直接调用pytest [...]。 可能出现的执行退出code 执行pytest可能…

在UVM验证平台加入transaction

transaction是一个抽象的概念。一般来说&#xff0c;物理协议中的数据交换都是以帧或者包为单位的&#xff0c;通常在一帧或者一个包中要定义 好各项参数&#xff0c;每个包的大小不一样。很少会有协议是以bit或者byte为单位来进行数据交换的。transaction就是用于模拟这种实际…

S32K116新建工程Debug可以运行,冷启动无法运行问题分析

S32K116使用IAR建立工程后&#xff0c;软件debug可以运行&#xff0c;断电冷启动无法运行。 这种现象基本上都是RAM未初始化导致&#xff0c;由于Debug时&#xff0c;调试器会自动初始化芯片&#xff0c;很多问题都不会暴露处理。 大家可以开一下Startup的汇编文件&#xff0c;…

Rpg游戏地形生成

rpg游戏中的地形一般使用高度图的形式来绘制。写了几个随机生成高度图的算法。 最常见的是基于分形算法生成高度图&#xff0c;网上有很多资料&#xff0c;这里不再介绍。 一种生成断层效果高度图的算法 //!生成断层效果的高度图 void TerrainData::FillFaultSurface(float …

全网最新最全的自动化测试教程:python+pytest接口自动化-requests发送post请求

简介 在HTTP协议中&#xff0c;与get请求把请求参数直接放在url中不同&#xff0c;post请求的请求数据需通过消息主体(request body)中传递。 且协议中并没有规定post请求的请求数据必须使用什么样的编码方式&#xff0c;所以其请求数据可以有不同的编码方式&#xff0c;服务…

初试占比7成!只考一门数据结构+学硕复录比1:1的神仙学校,大连交通大学考情分析

大连工业大学 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、24专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1014字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 大连工业…

SpringCloud笔记

一、SpringCloud初阶篇 1、从面试题开始 1.1什么是微服务&#xff1f; 1.2微服务之间是如何独立通讯的&#xff1f; 1.3SpringCloud和Dubbo有哪些区别&#xff1f; 1.4通信机制&#xff1a;Dubbo是通过RPC远程过程调用&#xff0c;微服务Cloud是基于rest调用 1.5SpringBo…

【vue】vue-slick-carousel插件,实现横向滚动列表手动左右滚动(也可设置为自动滚动)

需求&#xff1a;图片列表横向滚动的时候&#xff0c;隐藏原始滚动条&#xff0c;通过左右箭头控制滚动条往左右按一定的步长移动。 el-carousel走马灯一滚动就是一屏&#xff0c;不适合我的需求 在npm官网搜vue-slick-carousel&#xff0c;查看更详细的配置 vue-slick-caro…

GO基础之运算符

运算符 Go 语言内置的运算符有&#xff1a; 1.算术运算符 2.关系运算符 3.逻辑运算符 4.位运算符 5.赋值运算符 算术运算符 注意&#xff1a; &#xff08;自增&#xff09;和–&#xff08;自减&#xff09;在Go语言中是单独的语句&#xff0c;并不是运算符。 关系运算符 …

Pico VR眼镜(XR) Unity开发环境部署及打包教程

创建项目 我这里选择的是URP项目。URP对移动端性能比较友好&#xff0c;另外VR平台也不支持HDRP渲染管线。 然后进入unity工具栏->File -> Build Settings 点击 Android后&#xff0c;点就Switch Platform将项目转为Android项目 安装依赖包 在unity的工具栏中点击Wi…

12.4作业

#include <iostream>using namespace std;class Sofa { private:string sit;int *nub; public:Sofa(){cout << "Sofa::无参构造函数" << endl;}Sofa(string sit,int nub):sit(sit),nub(new int(nub)){cout << "Sofa::有参构造函数"…

前缀和例题:子矩阵的和AcWing796-Java版

//前缀和模板提,在读入数据的时候就可以先算好前缀和的大小 //计算前缀的时候用:g[i][j] g[i][j-1] g[i-1][j] - g[i-1][j-1] Integer.parseInt(init[j-1]); //计算结果的时候用:g[x2][y2] - g[x1 - 1][y2]- g[x2][y1-1] g[x1 -1][y1 - 1] "\n" //一些重复加的地…

拼多多股价为什么可以创下两年新高并一举超越阿里巴巴?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 拼多多再次证明了它是全球电商领域中不可忽视的力量 过去两年&#xff0c;由于某些众所周知的原因&#xff0c;很多中概股的股价都很疲软&#xff0c;甚至半死不活的&#xff0c;很多投资中概股的朋友也一直承受着很大的…

浅谈Django之单元测试

一、什么是单元测试 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。如果测试通过则说明我们这个函数或功能能够正常工作&#xff0c;如果失败要么测试用例不正确&#xff0c;要么函数有bug需要修复。 二、如何使用单元测试 from django.test imp…

练习十二:利用SRAM设计一个FIFO

利用SRAM设计一个FIFO 1&#xff0c;任务目的2&#xff0c;设计要求3&#xff0c;FIFO接口的设计思路4&#xff0c;FIFO接口的测试&#xff0c;top.v5&#xff0c;FIFO接口的参考设计&#xff0c;fifo_interface.v6&#xff0c;SRAM模型&#xff0c;sram.v代码7&#xff0c;viv…

Linux下快速创建大文件的4种方法

1、使用 dd 命令创建大文件 dd 命令用于复制和转换文件&#xff0c;它最常见的用途是创建实时 Linux USB。dd 命令是实际写入硬盘&#xff0c;文件产生的速度取决于硬盘的读写速度&#xff0c;根据文件的大小&#xff0c;该命令将需要一些时间才能完成。 假设我们要创建一个名…

Kubernetes学习笔记-Part.04 资源规划

目录 Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退 第四章 资源规划 4.1.资源配置 主机名FQDNIP服务器…

智能优化算法应用:基于未来搜索算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于未来搜索算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于未来搜索算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.未来搜索算法4.实验参数设定5.算法结果6.参考…