文章目录
前言
Shell是Linux系统中一种特殊程序,在用户终端与内核进行交互的翻译官,用户登录Linux系统时,会自动加载一个Shell程序,离开Shell操作系统将无法运行,Bash是Linux系统中默认的Shell程序。
Shell运行的过程:计算机接收用户所传输的命令,Shell会自动加载,将所接受到的命令转换成计算机所能识别的二进制语言,再将命令传递给系统内核执行。
一、Shell脚本的概述
在一些复杂的Linux维护工作中,大量重复性的输入和交互操作不但费时费力,而且容易出错,而编写一个恰到好处的shell脚本,可以批量处理、自动化地完成一系列维护任务,大大减轻管理员的负担
1.Shell脚本的概念
将要执行的命令按顺序保存到一个文本文件
给该文件可执行的权限
可结合各种Shell控制语句已完成更复杂的操作
2.Shell脚本应用场景
重复性操作
交互性任务
批量事务处理
服务运行状态监控
定时任务执行
3.Shell脚本的构成
1.脚本申明(解释器):若第一行为“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来解释执行,#!/bin/bash为默认解释器。还有其它类型的解释器,比如#!/usr/bin/python、#!/usr/bin/expect。
2.注释信息:以“#”开头的语句表示为注释信息,被注释的语句在运行脚本时不会被执行。
3.可执行语句
修改这个文件的权限使它可以执行 # 使用 chmod +x + 脚本文件
检测语法错误
执行脚本
3.1 查看当前系统支持的Shell脚本种类
[root@yzq opt]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
3.2 创建一个脚本文件
[root@yzq opt]# mkdir shell_bianliang
[root@yzq opt]# ls
1.txt rh shell_bianliang tar.1.txt.gzip
[root@yzq opt]# cd shell_bianliang/
[root@yzq shell_bianliang]# ls
[root@yzq shell_bianliang]# vim demo.sh
3.3 执行Shell脚本
方法一:指定路径的命令,要求文件必须有 x 权限。
方法二:指定Shell来解释脚本,不要求文件必须有 x 权限。
sh 脚本路径:(shell脚本调试,将运行过程展示)
[root@yzq shell_bianliang]# sh -x demo.sh
+ mkdir -p /opt/ky21/id
+ touch /opt/ky21/id/xh.txt
+ echo 14
source 脚本路径:(全局生效,不建议与exit一起使用)
赋予执行权限
执行命令
[root@yzq shell_bianliang]# chmod +x demo.sh
[root@yzq shell_bianliang]# ./demo.sh
3.4查看结果
[root@yzq shell_bianliang]# cd /opt/
[root@yzq opt]# ls
1.txt ky21 rh shell_bianliang tar.1.txt.gzip
[root@yzq opt]# cd ky21/
[root@yzq ky21]# ls
id
[root@yzq ky21]# cd id/
[root@yzq id]# ls
xh.txt
[root@yzq id]# cat xh.txt
14
4 管道和重定向
4.1 管道
将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。
cmd1 命令1 | cmd2 命令2 【…|cmdn 命令n】
统计连接数
[root@yzq ~]# netstat -natp | wc -l
20
4.2 重定向
1.交互式硬件设备
类型 | 设备文件 | 文件描述编号 | 默认设备 | 描述 |
---|---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 | 从该设备接收用户输入的数据 |
标准输出 | /dev/stdout | 1 | 显示器 | 通过该设备向用户输出数据 |
标准错误输出 | /dev/stderr | 2 | 显示器 | 通过该设备报告执行出错信息 |
2.重定向操作
重定向输入 < 从指定的文件读取数据
[root@yzq opt]# echo "123456" > pass.txt
[root@yzq opt]# cat pass.txt
123456
[root@yzq opt]# passwd --stdin zhangsan < pass.txt
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。
重定向输出 > 将标准输出结果 保存 到指定的文件,并且覆盖原有内容
>> 将标准输出结果 追加 到指定的文件的尾部,不覆盖原有内容
[root@yzq opt]# cat txt
111
[root@yzq opt]# echo "222" > txt
[root@yzq opt]# cat txt
222
[root@yzq opt]# echo "333" >> txt
[root@yzq opt]# cat txt
222
333
标准错误输出 2> 将错误信息 保存 到指定的文件,并且覆盖原有内容
2>> 将错误信息 追加 到指定的文件的尾部,不覆盖原有内容
[root@yzq opt]# aaa
bash: aaa: 未找到命令...
[root@yzq opt]# aaa 2> txt
[root@yzq opt]# cat txt
bash: aaa: 未找到命令...
[root@yzq opt]# bbb
bash: bbb: 未找到命令...
[root@yzq opt]# bbb 2>> txt
[root@yzq opt]# cat txt
bash: aaa: 未找到命令...
bash: bbb: 未找到命令...
混合输出 &> 将标准输出、标准错误保存到同一文件中
2>&1 将标准错误输出重定向到标准输出
[root@yzq opt]# ls &> txt
[root@yzq opt]# cat txt
pass.txt
passwd.txt
rh
shell_bianliang
txt
[root@yzq opt]# ccc &> txt
[root@yzq opt]# cat txt
bash: ccc: 未找到命令...
相似命令是: 'cc'
[root@yzq opt]# ccc &>> txt
[root@yzq opt]# cat txt
bash: ccc: 未找到命令...
相似命令是: 'cc'
bash: ccc: 未找到命令...
相似命令是: 'cc'
cat
cat <同cat效果相同,但打开方式不同,cat是自己打开自己拿,cat <是重定向输入打开给cat查看
[root@yzq opt]# cat sum.sh
#!/bin/bash
read -p "输入第一个整数:" num1
read -p "输入第二个整数:" num2
echo "$num1 + $num2的和为:$[$num1+$num2]"
[root@yzq opt]# cat <sum.sh
#!/bin/bash
read -p "输入第一个整数:" num1
read -p "输入第二个整数:" num2
echo "$num1 + $num2的和为:$[$num1+$num2]"
cat << EOF
EOF为结束符,在输出EOF后cat输出结束并打印出来
[root@yzq opt]# cat <<EOF
> 123
> 456
> EOF
123
456
cat << EOF > txt
可以把输入重定向和输出重定向结合使用,把从屏幕输出的内容保存到文件
456
[root@yzq opt]# cat << EOF > txt
> [local]
> name=local
> baseurl=fire:///mnt
> enabled=1
> gpg
> EOF
[root@yzq opt]# cat txt
[local]
name=local
baseurl=fire:///mnt
enabled=1
gpg
二、Shell脚本变量
变量的分类
自定义变量:由用户自己定义、修改和使用
环境变量:由系统维护,用于设置工作环境
位置变量:通过命令行给脚本程序传递参数
预定义变量:Bash中内置的一类变量,不能直接修改
查看变量的值
格式:echo $变量名
“=”表示赋值
1. 自定义变量
自定义变量只在此shell环境生效
由用户自己定义、修改和使用
格式:变量名=变量值
变量名:零时存放数据的地方;字母、数字、下划线组成,不能以数字开头,并且区分大小写
不能是特殊符号
变量值:零时的可变化数据
等号:表示赋值关系
用echo查看和引用变量值
{}引用变量
[root@yzq opt]# a=10
[root@yzq opt]# echo $a
10
[root@yzq opt]# test=100
[root@yzq opt]# echo $testRMB
[root@yzq opt]# echo ${test}RMB
100RMB
echo选项:
-n表示不换行输出
[root@yzq opt]# echo -n $test
100[root@yzq opt]#
-e输出转义字符,将转义后的字符输出到屏幕上
常见转义字符:
\c 不换行输出,\c后不存在字符时相当于-n
[root@yzq opt]# echo -e "nihao"
nihao
[root@yzq opt]# echo -e "nihao\c"
nihao[root@yzq opt]#
\n 表示换行(相当于回车)
nihao[root@yzq opt]# echo -e "nihao\n123"
nihao
123
\t表示转义后插入tab,即制表符
[root@yzq opt]# echo -e "nihao\t123"
nihao 123
注:\转义符,跟在转义符\之后的特殊符号将失去特殊含义,变为普通字符。如$输出$符号,而不是变量
[root@yzq opt]# echo $test
100
[root@yzq opt]# echo \$test
$test
取消定义
unset 变量名
[root@yzq opt]# echo $test
100
[root@yzq opt]# unset test
[root@yzq opt]# echo $test
[root@yzq opt]#
2.环境变量
由系统维护,用于设置工作环境
[root@yzq opt]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
使用env命令查看当前环境下的环境变量。
HOME表示用户宿主目录,RANDOM表示随机数。返回0-32767的整数,PWD表示当前所在工作目录。
[root@yzq opt]# env
XDG_SESSION_ID=2
HOSTNAME=yzq
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.28.1 51096 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/opt
LANG=zh_CN.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
SSH_CONNECTION=192.168.28.1 51096 192.168.28.10 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
DISPLAY=localhost:10.0
OLDPWD=/root
_=/usr/bin/env
[root@yzq opt]# echo $RANDOM
15805
[root@yzq opt]# echo $RANDOM
28579
[root@yzq opt]# echo $RANDOM
15265
echo KaTeX parse error: Expected ‘EOF’, got ‘#’ at position 10: PATH #̲查看当前搜索路径 PATH=”PATH:/root” #将/root目录添加到搜索路径
export PATH=“$PATH:/root” #输出为全局环境变量
环境变量的全局配置文件为/etc/profile,在此文件中定义的变量作用于所有用户。
但环境变量被覆盖时,可进入虚拟机/etc/profile文件加入这行修改
export PATH=“/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin”
或打开另一台虚拟机,使用远程复制/etc/profile到环境变量损坏的主机
3.预定义变量⭐⭐
Bash中内置的一类变量,不能直接修改
$? 上一条命令执行是否成功 0 成功 非零 失败
$# 表示命令或脚本要处理的参数的个数。
$$ 限制当前进程的pid号
$! 返回最后一个后台进程的进程号
$0:表示当前执行的脚本或命令的名称。
∗
、
*、
∗、@:表示命令或脚本要处理的参数。
$* 表示把所有参数看成以空格分隔的一个字符串整体,代表”$1 $2 $3 $4″ (脚本后面的所有内容)
[root@yzq opt]# ls
1.txt echo.sh mianji.sh read.sh rh tar.1.txt.gzip tx weizhi.sh
[root@yzq opt]# vim test.sh
[root@yzq opt]# chmod +x test.sh
[root@yzq opt]# ./test.sh echo.sh read.sh weizhi.sh
#!/bin/bash
echo -n "薪资"
read offer
echo $offer
#!/bin/bash
read -p "薪资" offer
echo "${offer}k"
#!/bin/bash
echo "位置变量0为$0
位置变量1为$1
位置变量2为$2
"
[root@yzq opt]# cat test.sh
#!/bin/bash
cat $*
$@ 表示把各个参数加上双引号分隔成n份的参数列表,每个参数是独立的个体,代表”$1″ “$2” “$3” “$4”。
$$ 返回当前进程的进程号。
$! 返回最后一个后台进程的进程号。
4.位置变量
$n:n为数字,$0代表命令本身,$1-$9代表带一个到第九个参数,十以上的参数需要使用大括号表示,比如${10}
[root@yzq opt]# vim weizhi.sh
[root@yzq opt]# chmod +x weizhi.sh
[root@yzq opt]# ./weizhi.sh a b
位置变量0为./weizhi.sh
位置变量1为a
位置变量2为b
[root@yzq opt]# cat weizhi.sh
#!/bin/bash
echo "位置变量0为$0
位置变量1为$1
位置变量2为$2
"
赋值
**{}**定义整体(分割)
[root@yzq opt]# nihao=yy
[root@yzq opt]# echo $nihao
yy
[root@yzq opt]# echo $nihao1
[root@yzq opt]# echo ${nihao}1
yy1
赋值时使用引号
双引号“”:允许通过$符号引用其他变量值
双引号主要起界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来;其他情况下双引号通常可以省略
[root@yzq opt]# echo $nihao
yy
[root@yzq opt]# echo "$nihao"
yy
单引号‘’:禁止引用其他变量值,$视为普通字符
[root@yzq opt]# echo $nihao
yy
[root@yzq opt]# echo '$nihao'
$nihao
[root@yzq opt]# yy='nihao a'
[root@yzq opt]# echo $yy
nihao a
反撇号“:命令替换,提取命令执行后的输出结果,…
和$(…)作用相同
允许将执行某个命令的屏幕输出结果赋值给变量。
反撇号括起来的范围内必须是能够执行的命令行,否则将会出错
使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用 “$()”来代替反撇号操作,以解决嵌套的问题
[root@yzq opt]# demo=`cat tx`
[root@yzq opt]# echo $demo
dd ff gg
[root@yzq opt]# cat=$(cat tx)
[root@yzq opt]# echo $cat
dd ff gg
[root@yzq opt]# rpm -qc `rpm -qf `which useradd``
rpm:未给出要查询的参数
未安装软件包 useradd
[root@yzq opt]# which useradd
/usr/sbin/useradd
[root@yzq opt]# rpm -qc /usr/sbin/useradd
未安装软件包 /usr/sbin/useradd
[root@yzq opt]# which useradd
/usr/sbin/useradd
[root@yzq opt]# rpm -qf /usr/sbin/useradd
shadow-utils-4.1.5.1-25.el7.x86_64
[root@yzq opt]# rpm -qc shadow-utils-4.1.5.1-25.el7.x86_64
/etc/default/useradd
/etc/login.defs
[root@yzq opt]# rpm -qc $(rpm -qf $(which useradd))
/etc/default/useradd
/etc/login.defs
交互式定义变量read
可以使用 Bash 的内置命令 read 来给变量赋值。
用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)读入 一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量(多余的内容赋值给 最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。
[root@yzq opt]# read nihao
hello
[root@yzq opt]# echo $nihao
hello
交互式定义变量(read)参数
-p 提示用户的信息
-n 定义字符数
-s 不显示用户输入的内容,常用于输入密码
read -p “提示信息” 变量名
echo $变量名
[root@yzq opt]# read -p "今天周几:" week
今天周几:周四
[root@yzq opt]# echo $week
周四
[root@yzq opt]# cat read.sh
#!/bin/bash
read -p "薪资" offer
echo "${offer}k"
[root@yzq opt]# ./read.sh
薪资20
20k
echo -n “提示信息”
read 变量名
echo $变量名
[root@yzq opt]# cat echo.sh
#!/bin/bash
echo -n "薪资"
read offer
echo $offer
[root@yzq opt]# ./echo.sh
薪资21
21
5.全局变量export
默认情况下,新定义的变量只在当前的Shell环境中有效,因此称为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用。
[root@yzq opt]# a=11
[root@yzq opt]# echo $a
11
[root@yzq opt]# su
[root@yzq opt]# echo $a
[root@yzq opt]# exit
exit
[root@yzq opt]# echo $a
11
可以通过内部命令export将指定的变量导出为全局变量,使用户定义的变量在所有的子Shell环境中能够继续使用。
为了使用户定义的变量在所有的子 shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无须使用”$”符号),变量名之间以空格分隔.
格式1:export 变量名
格式2:export 变量名 = 变量值
[root@yzq opt]# export b=22
[root@yzq opt]# echo $b
22
[root@yzq opt]# su
[root@yzq opt]# echo $b
22
6.整数变量的运算
格式:expr 变量1 运算符 变量2 [运算符 变量3] (整数参数)
运算符:+ 加法、- 减法、* 乘法、/ 除法、% 取余
运算符号:
(
(
)
)
和
(())和
(())和[ ] (必须和echo一起用才能输出结果)
运算命令:expr和let
运算工具:bc(系统自带)
[root@yzq opt]# expr 3 - 2
1
[root@yzq opt]# expr 3.0 - 2
expr: 非整数参数,支持常量和变量运算
[
]
变量的运算可以省略
[
]
里的
[ ]变量的运算可以省略[ ]里的
[]变量的运算可以省略[]里的
[root@yzq opt]# a=5
[root@yzq opt]# b=2
[root@yzq opt]# echo $[a+b]
7
[root@yzq opt]# echo $[$a+$b]
7
let运算
可以改变变量本身的值,但不显示结果,需要echo,其他运算方式可以做运算但不改变变量本身的值
[root@yzq opt]# n=0
[root@yzq opt]# let n=n++
[root@yzq opt]# echo $n
0
使用bc运算,支持小数运算,可用echo结合管道 | 使用
scale定义小数点后几位
[root@yzq opt]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=2
14/100
.14
[root@yzq opt]# echo "scale=2;14/100" | bc
.14
bc还可以做逻辑运算,真为1假为0(单=为赋值,不能用,使用双==)
[root@yzq opt]# echo "2>2" | bc
0
[root@yzq opt]# echo "2==2" | bc
1
常用的运算表达式:
i=KaTeX parse error: Undefined control sequence: \* at position 10: (expr 12 \̲*̲ 5) i=((12 * 5))
i=$[12 * 5]
let i=12*5
[root@yzq opt]# i=$(expr 12 \* 5)
[root@yzq opt]# echo $i
60
[root@yzq opt]# i=$(expr 12 * 5)
expr: 语法错误
[root@yzq opt]# i=$(12 * 5)
bash: 12: 未找到命令...
[root@yzq opt]# i=$((12 * 5))
[root@yzq opt]# echo $i
60
[root@yzq opt]# i=$[12 * 5]
[root@yzq opt]# echo $i
60
[root@yzq opt]# let i=12*5
[root@yzq opt]# echo $i
60
i++ 相当于 i=
[
[
[i+1]
i– 相当于 i=
[
[
[i-1]
i+=2 相当于 i=
[
[
[i+2]
++ i 是先加后赋值;i ++ 是先赋值后加
[root@yzq opt]# i=0
[root@yzq opt]# echo $i
0
[root@yzq opt]# let i=i++
[root@yzq opt]# echo $i
0
[root@yzq opt]# let i=++i
[root@yzq opt]# echo $i
1
7.只读变量
readonly 命令设置只读变量
[root@yzq opt]# yy=1
[root@yzq opt]# echo $yy
1
[root@yzq opt]# readonly yy
[root@yzq opt]# yy=2
bash: yy: 只读变量
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/76557.html