#!/bin/bash
#Data:20220508
#Version : 1.0
echo "hellow word"
#显示本机已经存在的命令需要用``符号
echo my hostname is `hostname`
shell脚本执行。要么告诉指定的 路径,要么修改bash内容
或者bash加文件名,或者将文件移动到$path的路径下
[root@localhost ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
加入对于的路径
或者指定路径执行:
[root@localhost ~]# /root/hello.sh
hellow word
my hostname is localhost.localdomain
当脚本运行一次会产生hash路径,若移动脚本会导致当前脚本继续安装原来路径运行,无法运行,需要清hash列表
Hash -d 删除指定的命令的hash缓存
-r全删除
shell的错误提示
命令错误可以依次执行;语法错误无法执行:
bash -n 显示shell脚本的语法是否有问题
bash -x 调试执行
变量:
引用变量,保留输出格式需要加“”进行显示
[root@localhost ~]# m=`cat /etc/passwd` #执行引用命令需要用``
[root@localhost ~]# echo $m
这样执行将文件内容显示为一行
[root@localhost ~]# echo "$m" 加上引号表示按照文件原有格式输出
注意变量赋值给变量:
name1=xxx
name2=xxxx
name2=$name1
修改name1,name2此时值还是原理name1的值
[root@localhost ~]# echo $$ 查看当前进程id
9915
[root@localhost ~]# echo $PPID 当前进程父进程的id号
9463
[root@localhost ~]# pstree -p查看进程的关系
Bash 不支持浮点数;弱类型
变量命令
1.不用关键字做变量名
2.数字字母下划线,不能以数字开头
3.见明知意思
4.驼峰法
bash变量种类: bash后台执行 sleep前台执行
局部变量:局部变量的工作范围为 当前的bash;当前shell有效,不具有传递功能
全局变量:export 加变量名字 全局变量,可以传递子进程,子进程可以对环境变量进行修改,但是不影响全局变量
[root@localhost ~]# export name=wangqian
[root@localhost ~]# bash
[root@localhost ~]# echo $$
10063
[root@localhost ~]# declare -x
[root@localhost ~]# export 两种都可定义全局环境变量
[root@localhost ~]# unset name 删除name的变量
[root@localhost ~]# set 查看所有的变量和函数
系统内置变量
[root@localhost ~]# lscpu 查看cpu型号
[root@localhost ~]# lsblk 硬盘大小
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 40G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 39G 0 part
├─centos-root 253:0 0 37G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 4.4G 0 rom
[root@localhost ~]# cat /proc/meminfo 内存大小
MemTotal: 1863004 kB
MemFree: 514804 kB
[root@localhost ~]# free -h 内存大小
操作系统版本:[rooot@centos7 ~]#cat /etc/centos-release
egrep -o 显示正则匹配的内容
grep -Eo 等同于
echo $SHLVL 查看bash当前环境bash嵌套了几次
常量:有效期是该进程的生存周期
[root@localhost bin]# readonly name=age
[root@localhost bin]# name=1
bash: name: 只读变量
Declare -r 查看常量的值
加()执行命令,表示秀爱umask,只在本次生效,对原来umask不变;原理是开启了一个子shell,不会影响父进程
[root@localhost bin]# (umask 666;touch /date/xixi)
[root@localhost bin]# ls -l /date/xixi
----------. 1 root root 0 5月 17 22:36 /date/xixi
[root@localhost bin]# umask
0022
{} 和()都会把命令整体执行,()不会影响当前环境,{}会影响当前环境
例子:
[root@localhost bin]# x=1;echo "pid=$$";(echo "subid=$$";echo "subx=$x";x=2;echo "sub2=$x");echo x=$x
pid=12161
subid=12161
subx=1
sub2=2
x=1
位置变量:
(2)位置变量
位置变量:在湖本代码中调用通过命令行传递给脚本的参数
$1,$2,....对应第1、第2等参数,shift[n]换位置
$0:命令本身
$*:传递给脚本的所有参数,全部参数合为一个字符串
$@:传递给脚本的所有参数,每个参数为独立字符串
$#:传递给脚本的参数的个数
$@$*只在被双引号包起来的时候才会有差异
echo "f1.sh arg is $1"
./f2.sh "$*" 在f1.sh调用f2.sh,f1.sh传入多个参数$*表示f2.sh按照字符串接受,$#f2.sh接受第一个位置产数
set -- 表示清除位置产数
set--清空所有位置变量
set--清空所有位置变量
(3)详细理解
1.readonly
[root@centos7 ~]#readonly name=mage
[root@centos7 ~]#echo $name
Mage
[root@centos7 ~]#name =wang
-bash: name : readonly variable
[root@centos7 ~]#unset name
-bash: unset : name :cannot unset: readonly variable
[root@centos7 ~]#set |grep name
2.declare -r
当退出程序对应的结果也会消失,程序结束对应的变量也会消失,变量的生命有效期就是程序运行的时期,程序什么时候结束常量就会结束。
常量的运用不多但还是要用到的比如Π,有时候回去到3.14,有时候是3.1415,常量主要是要保证他的固定值。
将脚本软链ln -s
ln -l arg.sh link1.sh 前面为源文件,后一个软连接文件-----$0:命令本身不一样,软连接到一个脚本
Shift-----传入的位置产数依次处理(默认一次移动一位,加数字可以控制移动几次)、
2退出状态
进程使用退出状态来报告成功或失败
- 0代表成功,1-255代表失败
- $?变量保存最近的命令退出状态
判断命令是否执行成功$? ,为0表示成功,1-255表示失败
脚本返回的结果是否为0,是由最后一条命令决定的
&>可以将错误信息或者普通信息都重定向输出
[root@localhost dev]# ping -c1 192.168.3.1 &> /dev/null
[root@localhost dev]# echo $?
0
通过echo $? 表示网络的正常
3 退出状态码
◆bash自定义退出状态码
exit [n] :自定义退出状态码 后面内容不执行
注意:脚本中一旦遇到exit命令 ,脚本会立即终止;终止退出状态取决于exit命令后面的数字
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
执行脚本相当于在进程下开启一个子进程:exit可以退出子进程
4 算术运算
◆bash中的算术运算:help let
+, -,*,/,%取模(取余),**(乘方)
实现算术运算:
(1) tet var=算术表达式
[root@localhost dev]# let z=x+y
[root@localhost dev]# echo $z
30
(2) var= $[算术表达式]
[root@localhost dev]# a=$[x+y]
[root@localhost dev]# echo $a
30
(3) var= $((算术表达式))
(4) var= $(expr arg1 arg2 arg3 ..)
注意:expr 是个命令 本身就可以做运算。
[root@localhost dev]# a=$(expr 3 * 2)
[root@localhost dev]# echo $a
6
#expr 1 + 2
1 + 2 中间有空格是不对的
#expr 3 * 2
乘号是不可以直接*的,需要转义
(5) declare-ivar =数值
(6) echo '算术表达式’| bc
[root@localhost dev]# echo "1+2" | bc
3
◆乘法符号有些场景中需要转义,如*
◆bash有内建的随机数生成器: $RANDOM ( 0-32767 )
echo $[$RANDOM%50] : 0-49之间随机数
字母color显示不同颜色
[root@localhost dev]# COLOR=$[RANDOM%7+31] ; echo -e "e[1;${COLOR}mcolore[0m"
color
与或
Cmd1&&cmd2
如果cmd1为假,cmd2不需要执行,反之cmd1为真,需要cmd2执行
Cmd1||cmd2
如果cmd1为真,cmd2不需要执行,反之cmd1为假,需要cmd2执行
异或 ^
1^0=1
0^0=0
0^1=1
1^1=0
赋值
declare -I var =数字
declare -i a=6
[root@localhost ~]# declare -i a=6
[root@localhost ~]# declare -i b=3
[root@localhost ~]# declare -i c=a*b
[root@localhost ~]# echo $c
18
[root@
判断文件中一行是否为空grep"^$"即可
一、shell脚本编程基础
(一)条件测试
判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要测试命令辅助完成测试过程;
评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1
测试命令:
test EXPRESSION-----》 等价 [ ]
test命令可以用来判断后面的表达是否成立,test本身是一个内部命令,test命令的用法可以通过输入help test。输入help test 之后,可以看到后面跟了[expr]称为表达式。
执行结果或返回的状态是0或者1,0代表真,1代表假;test的结果是根据0或者1的状态来进行判断。
Help test
例子:比较两个字符串是否一样
[root@localhost ~]# a=abcx
[root@localhost ~]# b=bcx
[root@localhost ~]# test $a = $b
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ $a = $b ]
[root@localhost ~]# echo $?
1
[root@localhost bin]# ((9**2 >81))
[root@localhost bin]# echo $?
1
等价与-n;但是可以省略-产数。
[root@localhost ~]# [ a ]
[root@localhost ~]# echo $?
0
逻辑关系&&和||
[root@localhost ~]# x=xixi;y=hehe;[ $x = $y ] && echo equal || echo no equal
no equal
[root@localhost ~]# x=xixi;y=xixi;[ $x = $y ] && echo equal || echo no equal
equal
数字比较选项 eq等于;
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
判断输入的是否是数字,需要用到“=~”(表示左侧字符串是否能够被右侧的PATTERN所匹备,
[[ "$n" =~ ^[0-9]+$ ]] && echo digit
等价:
[[ "$n" =~ ^[[:digit:]]+$ ]] && echo digit
执行看结果,参数个数不对,原因出在其中有一个不是数字(一个是数字,一个是字母)前面如果不是数字也可以进行判断,所以要全面考虑;以上是正则表达式的用法。(如果是取非数字,则加!号)(逻辑运算:非:!;!1=0;!0=1;
判断文件后缀:
假设对$^filename 变量进行判断它是否为sh后缀,写出表达式:[[ $filename =~ .+.sh$ ]] && echo sh || echo no sh;
(sh的文件名至少含有一个字符)
进行赋值:filename a.sh,执行操作,便可判断文件后缀。
case语句:
例如:
#!/bin/bash
case ${USER} in
xixi)
echo "hello xixi";;
root)
echo "hello root";;
*)
echo "unkown";;
esac
例子:
命令读取的例子:
file="/root/bin/test1.txt"
for word in `cat $file`
do
echo "the word is $word"
done
更改字段分隔符$IFS
words="a:b:c:d:f"
IFS=:
for word in $words
do
echo "The word is $word"
done
用通配符遍历目录
for file in /tmp/*
do
if [ -f $file ]
then
echo "file :$file"
elif [ -d $file ]
then
echo "file :$file"
fi
done
三.循环控制命令
1.循环控制语句——break
break可以退出任意类型的循环
1)跳出内部循环
2)跳出外部循环break n
2.循环控制语句——continue
1)continue可以跳过执行当前循环的命令,但不会终止整个循环
2)可指定跳过的循环层数continue n



