Shell脚本书写格式
#!/bin/bash
<<COMMENT
Author:hjh
Data:2020-09-01
Version:1.0
Description:This is my first script
COMMENT
#屏幕将显示echo命令后的字符串
#echo命令后给什么字串屏幕将回显什么字符串
echo "Hello Shell Script"
- 第一行指定编译器:#!/bin/bash、#!/bin/sh、#/usr/bin/env python等
- 多行注解<<:开始和结束分隔符保持一致
- 单行注解#
- 命令行
Shell脚本执行方法
-
脚本没有执行权限
bash 1.sh sh 1.sh
-
脚本有执行权限
chmod +x 1.sh #相对路径 ./1.sh #绝对路径 /home/iViewfinder/Shell/1.sh
-
不开启子bash执行
通过pstree命令可以看到上述方法执行脚本时都会开启子进程执行,不开启子进程执行使用
source
或者.
source 2.sh . 2.sh
数据的输入与输出
输出
-
echo
#!/bin/bash #version:1.0 echo "1.查看网卡信息" echo "2.查看内存信息" echo "3.查看磁盘信息" echo "4.查看CPU信息" echo "5.查看账户信息"
echo命令通过
-e
可以识别字符串中的转义字符:符号 功能 \e或者\033 设置终端属性,字体颜色、背景颜色等 \t 插入tab \b 退格Backspace \n 换行且光标移动到行首 例如:绿色字体输出*
echo -e "\e[32mOK\e[0m"
* -
printf
printf [格式] 参数
用于格式化输出:
pintf "%d" 12
输入
-
read
read [选项] [变量名]
选项 功能 -p 显示提示信息 -s 静默模式,不显示输入内容(密码输入) #!/bin/bash read -p "请输入用户名:" user read -s -p "请输入密码:" pass useradd "$user" echo "$pass" | passwd --stdin "$user" #输入用户名和密码,新建系统用户
“|”:管道,将前者命令输出写入管道,后者命令从管道中读取数据
–stdin:标准输入,从标准输入(管道)中读取数据
输入输出的重定向
-
输出重定向
-
输出分类:标准输出通道、错误输出通道
-
重定向:
>:重定向标准输出到文件
>>:追加标准输出到文件
2>:重定向错误输出到文件
2>>:追加错误输出到文件
&>:重定向标准输出、错误输出到一个文件
&>>:追加标准输出、错误输出到一个文件
2>&1:重定向错误输入到标准输出通道输出
1>&2:重定向标准输出到错误输出通道输出 -
/dev/null:系统黑洞,写入该文件的数据都将被丢弃
ls /etc/passwd /nofile > test.txt 2>&1 #将标准输入、错误输出都重定向到test.txt文件
-
-
输入重定向
- <:从文件读取数据
- <<:不从文件读取数据,在分隔符内部写数据
#!/bin/bash cat > /tmp/test.txt << HERE 输入重定向测试文件 Welecom to Earth. HERE
cat从输入重定向(Here Document)中读取数据再重定向输出到文件
各种引号
-
单引号’'与双引号""
-
单引号、双引号都是为了引用一个整体;而其区别在于单引号能屏蔽特殊字符,而双引号不能。
-
转义字符
\
只能屏蔽后面一个特殊字符echo $$ #当前进程号 echo "$$" #当前进程号 echo '$$' #$$
-
-
反引号``
``是一个命令替换符号,使用命令的输出结果替换命令
tar -czf /root/log-`date +%Y%m%d`.tar.gz /var/log #文件名是动态的,``内被命令输出给替换掉;log-20200901.tar.gz
因为反引号的缺陷(不支持嵌套),现在用
$()
代替``echo $(echo 我是1级嵌套 $(echo 我是2级嵌套))
变量
-
自定义变量
- 定义:变量名=变量值(=两边不能有空格)
- 规范:
字母
、数字
、_
组成,且不能以数字开头 - 变量的引用:$
- 变量的引用:${},当变量名与非变量字符挨在一起时
#!/bin/bash #获取主机信息(ip、内存、CPU负载) ip=$(ifconfig eth0 | grep netmask | tr -s " " | cut -d" " -f3) mem=$(free | grep Mem | tr -s " " | cut -d" " -f7) cpu=$(uptime | tr -s " " | cut -d" " -f11) echo "本机IP地址是:$ip" echo "本机内存剩余:$mem" echo "本机cpu平均负载:$cpu"
-
tr:转换字符、删除字符、压缩重复字符
#转换字符 echo "Hello World" | tr a-z A-Z #删除字符 echo "Hello World" | tr -d A-Z #压缩字符 echo "Hello World" | tr -s " "
-
cut:以行为单位剪切字段,并将剪切后的字段标准输出,获取某一列
echo "hello world" | cut -d" " -f5
-d:自定义分隔符
-f:指定选取某一段
-
系统变量
变量名 描述 USER 当前账号的账户名称 HISTSIZE 当前终端历史命令条数 HOME 当前账户的根目录 PATH 命令搜索路径 PWD 当前工作目录 RANDOM 随机返回0-32767的整数 $0 当前脚本的名称 $n 第n个位置参数 $? 上一条命令退出时的状态码(0正确,非零失败) $$ 当前进程进程号 #!/bin/bash echo "当前账户是:$USER" echo "当前账户根目录是:$HOME" echo "当前工作目录是:$PWD" echo "返回0~32767的随机数:$RANDOM" echo "当前脚本的进程号:$$" echo "当前脚本的名称是:$0" echo "当前脚本第一个参数是:$1" echo "当前脚本第二个参数是:$2" echo "当前脚本第三个参数是:$3" echo "当前脚本的所有参数是:$*" ls /etc/passwd echo "我是正确返回状态码:$?,上一条执行正确" ls /etc/pas echo "我是错误返回状态码:$?,上一条执行错误"
数据过滤与正则表达式
数据过滤
-
grep:用于查找关键字并打印匹配的行
选项 含义 -i 忽略大小写 -v 取反匹配 grep th test.txt grep -i the test.txt
正则表达式
-
基本正则表达式
字符 含义 c 字母c . 任意单个字符 * 前一个字符出现≥0次 .* 多个任意字符 [] 集合中任意单个字符 [x-y] 连续的字符串范围 ^ 字符串的开头的行 $ 字符串的结尾的行 [^] 对括号内的集合取反 \ 转义后的字符串 \{n,m\} 前一个字符重复n到m次 \{n,\} 前一个字符重复n次 \(\) 将()内的内容存储到保留空间,通过\n复制粘贴调用第n个 #!/bin/bash cp /etc/passwd /tmp/ grep "root" /tmp/passwd grep ":..0:" /tmp/passwd grep "00*" /tmp/passwd grep "[os]t" /tmp/passwd grep "[0-9]" /tmp/passwd grep "[f-q]" /tmp/passwd grep "^root" /tmp/passwd #以root开头的行 grep "bash$" /tmp/passwd #以bash结尾的行 grep "0\{1,2\}" /tmp/passwd #包含一个到两个连续0的行 grep "\(root\).*\1" /tmp/passwd #两个root之间可以是任意字符的行 grep -v "^$" /tmp/passwd #非空白行
-
扩展正则表达式
字符 含义 {n,m} 等同于\{n,m\} + 前一个字符出现≥1次 ? 前一个字符出现≥0次 | 或,匹配|前或后的字串 () 等同于\(\) grep默认不支持扩展正则表达式,需要使用grep -E;或者直接使用egrep
egrep "0{1,2}" /tmp/passwd egrep "0+" /tmp/passwd egrep "(root|admin)" /tmp/passwd
算术运算
进行运算的方式:
$(())- $[]
- let:一般将运算的结果赋值给变量,不需要$
- bc:小数运算交互模式
符号 | 含义 |
---|---|
+ - * / | 加减乘除 |
++ – | 自增1 自减1 |
** % | 求幂 取模 |
+= -= *= /= | 自加 自减 自乘 自除 |
&& || | 与 非 |
> >= | 大于 大于等于 |
< <= | 小于 小于等于 |
表达式?表达式:表达式 | 根据表达式的结果,返回特定的值 |
#!/bin/bash
echo $((2+3))
echo $(2**4)
x=2
echo $((x+=2))
echo $[2+8*2]
echo $[1>2?11:22]
y=5
let y++
echo $y
#!/bin/bash
#计算1+2+3,...,+n的和
read -p "请输入一个正整数:" num
sum=$[num*(num+1)/2]
echo -e "\033[32m$num以内整数的总和是:$sum\033[0m"
#使用三角形底边和高计算面积
read -p "请输入三角形底边长度:" bottom
read -p "请输入三角形高度:" higth
A=$(echo "scale=1;1/2*$bottom*$hight" | bc)
echo -e "\033[32m三角形面积是:$A\033[0m"
#时间格式转换
read -p "请输入秒数:" sec
ms=$[sec*1000]
echo -e "\033[32m$sec 秒=$ms 毫秒\033[0m"
hour=$(echo "scale=2;$sec/60/60" | bc)
echo -e "\033[32m$sec 秒=$hour 小时\033[0m"
bc:转换成小数
scale:指定小数点后位数