好的做网站,中国电商网站排名,注册资金,上海企业联系方式初始shell 程序 语言 编程
----------------------------------
语言
自然语言:汉语、英语
计算机语言:c语言、c、(java php python go shell)
编译型语言 c c java
解释型语言 php python bash
编译型语言:编译型语言的首先将源代码编译生成机器语言#xff0c;再由机…初始shell 程序 语言 编程
----------------------------------
语言
自然语言:汉语、英语
计算机语言:c语言、c、(java php python go shell)
编译型语言 c c java
解释型语言 php python bash
编译型语言:编译型语言的首先将源代码编译生成机器语言再由机器运行机器码(二进制)。像C/C等都是编译型语言。
解释型语言:源代码不是直接翻译成机器语言而是先翻译成中间代码再由解释器对中间代码进行解释运行。比如Python/JavaScript/Shell等都是解释型语言c 编译型执行代码需要编译成cpu能认识的二进制码 x86指令集java 编译型执行编译--字节码cpu不能直接运行只能被Java虚拟机执行 shell 解释型语言执行 shell 定义 Shell 也是一种程序设计语言它有变量关键字各种控制语句有自己的语法结构利用shell程序设计语言可以编写功能很强、代码简短的程序。
shell是外壳的意思就是系统的外壳我们可以通过shell的命令来控制和操作操作系统比如linux中的shell命令就包括ls、cd、pwd等等总结来说shell就是一个命令解释器通过接收用户输入的shell命令来启动、停止程序的运行或者对计算机进行控制。 shell查看和切换
[rootlinux-server ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
#默认shell bash shell/bin/sh实际上是链接到/bin/bash的
#centos中脚本使用的默认shell 为/usr/bin/sh
[rootlinux-server ~]# echo $SHELL #查看当前用户所使用的默认Shell的路径
/bin/bash
[rootlinux-server ~]# echo $0 #查看当前正在运行的Shell的名称
-bash ##登录shell
bash ##非登录shell[rootlinux-server ~]# vim /etc/passwd 编辑登录shell使用场景
Shell 能做什么?
1. 自动化批量系统初始化程序 (update软件安装时区设置安全策略...)---初始化脚本
2. 自动化批量软件部署程序 (LAMPLNMPTomcatLVSNginx)---自动化安装脚本
3. 应用管理程序 (KVM)---批量创建虚拟机、管理虚拟机。
4. 日志分析处理程序(PV, UV, 200, !200,grep/awk)----akw、sed、grep
5. 自动化备份恢复程序(MySQL完全备份/增量 Crond)-----数据备份恢复脚本
6. 自动化信息采集及监控程序(收集系统/应用状态信息CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)--监控脚本
7. 配合Zabbix信息采集(收集系统/应用状态信息CPU,Mem,Disk,Net,Apache,MySQL)
8. 9*9乘法表、俄罗斯方块打印三角形打印圣诞树打印五角星运行小火车坦克大战排序实现
9. Shell可以做任何运维的事情(一切取决于业务需求)
shell 和ansible---批量自动化工具--自动化运维--ansible
shell 特性回顾 shell常见元素 文件描述符与输出重定向:
在 shell程序中最常使用的FD (file descriptor) 大概有三个, 分别是:
0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)
在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端
a.txt
1a.txt
2a.txt
a.txt
12
21
一般来说, 1 通常可以省略成 .
12 正确返回值传递给2输出通道 2表示2输出通道之前如果有定义标准错误重定向到某log文件,那么标准输出也重定向到这个log文件如果此处错写成 12, 就表示把1输出重定向到文件2中.
21 错误返回值传递给1输出通道, 同样1表示1输出通道.
例子. 当前目录下只有a.txt,没有b.txt
[rootlinux-server ~]# touch a.txt
[rootlinux-server ~]# ls a.txt b.txt 1file.out 21
[rootlinux-server ~]# cat file.out
ls: cannot access b.txt: No such file or directory
a.txt
现在, 正确的输出和错误的输出都定向到了file.out这个文件中, 而不显示在前端 bash 初始化 用户登录Linux时需要执行的几个文件登录shell
/etc/profile -/etc/profile.d/*.sh - (~/.bash_profile | ~/.bash_login | ~/.profile) - ~/.bashrc - /etc/bashrc - ~/.bash_logout
全局配置不管是哪个用户登录时都会读取该配置文件(系统级别)
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
.bash_profile、.profile和.bash_login
当登录到系统时如果是登录shell通过SSH登录或在控制台登录输入用户名和密码它会查找.bash_profile|.profile|.bash_login中的一个并且只读取第一个找到的文件。这些文件主要用于设置环境变量和执行用户登录时需要运行的命令。
~/.bash_login(用户级)登录时执行 这是用户的登陆文件在每次用户登陆系统时bash都会读此内容所以通常都会将登陆后必须执行的命令放在这个文件中。
~/.bash_logout(用户级)退出登陆时执行 离开时执行如果想在注销shell前执行一些工作都可以在此文件中设置。
非登录shell启动文件顺序读取配置文件顺序
~/.bashrc -/etc/bashrc
~/.bash_profile
~/.bashrc
#profile类的文件: 设定环境变量运行命令或脚本用户在登录的时候会自动生效
#bashrc类的文件: 定义命令别名
# cp /etc/skel/.bash_profile . ##配置登录用户的bash shell环境
# source .bash_porfile~/.bash_history(用户级) #这个文件会记录用户先前使用的历史命令。# su jack: 这个命令简单地切换到用户 jack的身份但不切换到他的环境变量。
# su - jack: 这个命令不仅切换到用户jack的身份还切换到他的环境变量。 bash常用命令
补全 tab键 #yum -y install bash-completion
历史--history
别名---alias
快捷键---ctrlcl
前后台作业---jobs fg bg
重定向
管道 ---|
#命令排序执行: ; ||通配符:[] {} ? *
正则表达式 脚本cd切换当前工作目录。
pwd显示当前工作目录的路径。
echo输出文本或变量内容到标准输出。
export设置环境变量。
unset删除环境变量。
alias创建命令别名。
source读取并执行指定文件中的命令。
history显示命令历史记录。
exit退出当前Shell会话。
touch创建空文件或更新文件的时间戳。
mkdir创建目录。
rmdir删除空目录。
rm删除文件或目录。
cp复制文件或目录。
mv移动或重命名文件或目录。
ls列出目录内容。
cat显示文件内容。
grep在文件中查找指定模式。
wc统计文件或输入中的行数、单词数和字节数。
chmod修改文件或目录的权限。
chown修改文件或目录的所有者。
chgrp修改文件或目录的所属组。
find在指定路径下查找文件。
tar打包和解包文件。
gzip压缩文件。
gunzip解压缩文件。
man显示命令的帮助文档。
which查找指定命令的路径。
read从标准输入读取一行文本。
[rootlinux-server ~]# history #查看历史命令
调用历史命令 上下健!关键字esc . 上一条命令的最后一个参数[rootlinux-server ~]# alias #查看别名[rootlinux-server ~]# vim /etc/profile #设置变量:显示历史命令执行时间
HISTTIMEFORMAT%Y-%m-%d %H:%M:%S #在末尾添加
[rootlinux-server ~]# source /etc/profile #让设置的环境变量生效
2.再次执行history查看结果
Bash 部分快捷键 Ctrla 切换到命令行开始(跟home一样但是home在某些unix环境下无法使用) Ctrlu 清除剪切光标之前的内容Ctrlk 清除剪切光标之后的内容ctrly 粘贴刚才所删除的字符Ctrlr 在历史命令中查找输入关键字调出之前的命令Ctrll 清屏Ctrlc 终止Ctrle 切换到命令行末尾 通配符置换
#在 Shell命令中通常会使用通配符表达式来匹配一些文件*?,[]{}
例:
字符 含义 实例
* 匹配 0 或多个字符 a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。
? 匹配任意一个字符 a?b a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b 。
[list] 匹配 list 中的任意单一字符 a[xyz]b a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb 。
[!list] 匹配 除list 中的任意单一字符 a[!0-9]b a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配 c1-c2 中的任意单一字符 [0-9] [a-z] a[0-9]b a与b之间必须也只能有一个字符 如a0b, a1b... a9b。
{s1,s2,...} 匹配s1或s2等其一字符串 a{abc,xyz,123}b a与b之间只能是abc或xyz或123这三个字符串之一。
[rootlinux-server tmp]# rm -rf ./*
[rootlinux-server tmp]# touch aabcb axyzb a012b ab acb
[rootlinux-server tmp]# ls
a012b aabcb ab acb axyzb
[rootlinux-server tmp]# ls a*b
a012b aabcb ab acb axyzb
[rootlinux-server tmp]# ls a?b
acb
[rootlinux-server tmp]# rm -rf ./*
[rootlinux-server tmp]# touch axb ayb azb axyb
[rootlinux-server tmp]# ls
axb axyb ayb azb
[rootlinux-server tmp]# ls a[xy]b
axb ayb
[rootlinux-server tmp]# ls a[!xy]b
azb
[rootlinux-server tmp]# ls a[!x]b
ayb azb
[rootlinux-server tmp]# rm -rf ./*
[rootlinux-server tmp]# touch a0b a1b a9b
[rootlinux-server tmp]# ls a[0-9]b
a0b a1b a9b
[rootlinux-server tmp]# rm -rf ./*
[rootlinux-server tmp]# touch aabcb axyzb a012b ab
[rootlinux-server tmp]# ls a{abc}b
ls: cannot access a{abc}b: No such file or directory
[rootlinux-server tmp]# ls a{abc,xyz}b
aabcb axyzb
[rootlinux-server tmp]# ls a{abc,xyz,012}b
a012b aabcb axyzb shell 脚本规范
[rootlinux-server ~]# vim helloworld.sh ---.sh代表这个文件是个shell脚本,拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本
#!/usr/bin/env bash ## 或#!/bin/bashshebang蛇棒, 解释器, 翻译
# Author: soso666
# Email: soso666163.com
# Github: https:github.com/soso666
# Date: 2019/12/24 ##注释, 规范要求注明作者、日期、联系方式等
echo hello world ##功能说明:打印hello world[rootlinux-server ~]# sh helloworld.sh
hello world
[rootlinux-server ~]# chmod x helloworld.sh
[rootlinux-server ~]# ./helloworld.sh
[rootlinux-server ~]# /root/helloworld.sh
hello world
第一行: “#!/usr/bin/env bash”叫做shebang, shell语法规定shell脚本文件第一行为整个文件的解释器
第二行: 为“#”开头的行为注释行默认不会被程序所读取, 用来说明文件及标定所属人员使用, 也可用来解释程序
第七行: 为输出打印语句echo, echo可以把后面的“hello world”打印到指定的终端中
bash 脚本测试
1.sh -x这将执行该脚本并显示所有变量的值
[rootlinux-server ~]# sh -x /root/helloworld.shecho hello world
hello world
2.sh -n不执行脚本只是检查语法模式将返回所有错误语法
[rootlinux-server ~]# sh -n /root/helloworld.sh
3.sh -v执行脚本前把脚本内容显示在屏幕上
[rootlinux-server ~]# sh -v /root/helloworld.sh
#!/usr/bin/env bash
# Author: soso666
# Email: soso666163.com
# Github: https:github.com/soso666
# Date: 2019/12/24
echo hello world
hello world
变量
变量类型
变量bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能简单说就是让一个特定的字符串代表不固定的内容
a123,echo $a
分为预定义变量、环境变量、自定义变量、位置变量
预定义变量 预定义的特殊变量有着特殊的含义用户不可以更改所有预定义变量都由$符号和另外一个符号组成常用的预定义变量特殊变量如下 $0用于获取当前脚本或命令的名称。$$用于获取当前进程的PID。$?用于获取上一个命令的退出状态码可以用来判断命令是否执行成功。$#用于获取位置参数的数量也就是命令行参数的个数。$*用于获取所有位置参数的内容可以将所有参数作为一个整体使用。$用于显示所有的参数每个参数都可以单独处理。$!用于获取上一个后台进程的PID可以在后台进程执行完后使用wait命令等待该进程结束。 [rootlinux-server ~]# echo $? 最后一次执行的命令的返回状态。如果这个变量的值为 0
则证明上一条命令正确执行;如果这个变量的值为非 0 则 证明上一条命令执行错误
[rootlinux-server ~]# echo $$ 当前进程的进程号(PID)
[rootlinux-server ~]# echo $! 后台运行的最后一个进程的进程号(PID)
[rootlinux-server ~]# ls
anaconda-ks.cfg a.txt b.txt file.out helloworld.sh #ls命令正确执行
[rootlinux-server ~]# echo $?
0
#预定义变量$?的值是0证明上一条命令正确执行
[rootlinux-server ~]# sleep 3000
[1] 1418
#符号的意思是把命令放入后台执行
[rootlinux-server ~]# echo $!
1418 自定义变量 自己设置的变量只能在当前终端和脚本中使用
#定义变量变量名称值
#变量名称:只能由字母数字下划线组成不能以数字开头#注意:应该让变量名称有意义 赋值符号 前后不能有空格 值: 所有的字符串和数字都可以
#引用变量: $变量名 或 ${变量名}
#查看变量: echo $变量名
#取消变量: unset 变量名仅在当前shell中有效示例:
[rootlinux-server ~]# a100
[rootlinux-server ~]# echo $a
100
[rootlinux-server ~]# echo $aa # 这里输出为空因为解释器认为$aa是变量
[rootlinux-server ~]# echo ${a}a
100a 环境变量 shell在开始执行时已经定义好的就是系统执行环境的一些设置
# env #env是 environment (环境) 的简写所有的环境变量包含自定义的环境变量
# set #列出系统中所有的变量包括自定义的变量
# export 变量名
#使自定义的变量成为环境变量.环境变量拥有可继承性:export之后就拥有继承性环境变量可以被向下继承
临时生效
[rootlinux-server ~]# IPADDR192.168.1.1
[rootlinux-server ~]# echo $IPADDR
192.168.1.1
永久生效
写到4个登陆脚本中 ~/.bashrc | ~/profile | /etc/profile.d/*.sh | /etc/profile环境变量配置文件中前2个用户变量后两个全局环境变量
推荐在/etc/profile.d/*.sh 或/etc/profile 配置
[rootlinux-server ~]# vim /etc/profile.d/test.sh
IPADDT192.168.1.1
[rootlinux-server ~]# source /etc/profile.d/test.sh #让环境变量生效
[rootlinux-server ~]# echo $IPADDT
192.168.1.1
常用环境变量:USERUIDHOMEHOSTNAMEPWDPS1 PATH
PATH:存储所有命令所在的路径 常用环境变量
IFS (Internal Field Separator) 定义了 shell 如何处理空白字符和字段分隔符。通过
修改 IFS 的值你可以控制 shell 如何解析输入行以及如何将输入行分割成字段。
IFS 的默认值包括空格 ( )、制表符 (\t) 和换行符 (\n)。1临时修改 IFS
OLD_IFS$IFS # 保存当前的 IFS 值
IFS; # 修改 IFS
read -a fields field1;field2;field3 # 使用修改后的 IFS
for field in ${fields[]}; do # 输出字段echo $field
done
IFS$OLD_IFS # 恢复 IFS2永久修改 IFS 如果你想在整个 shell 会话期间修改 IFS 的值可以简单地给它赋一个新的值
IFS;3)awk命令应用
IFS, # 将 IFS 设置为逗号
echo apple,banana,grape | awk {print $2} # 使用 awk 处理数据位置变量
位置变量也叫位置参数:在脚本代码中调用通过命令行传递给脚本的参数
$1 $2 $3 $... #分别对应传递给脚本内容里面的第1、第2等参数
例子
# /test.sh start #start是第1个位置参数
#/test.sh 2 3 5 hello #2是第1个位置参数3是第2个位置参数...依次类推
例子:
[rootlinux-server ~]# cd /opt/test/script/
[rootlinux-server script]# vim weizhi.sh
#!/usr/bin/bash
echo 我的第一个位置参数是:$1
echo 我的第二个位置参数是:$2
echo 我的第三个位置参数是:$3
echo 我的第四个位置参数是:$4
echo 一共有 $# 个位置参数
echo 你输入的参数分别是:$*
[rootlinux-server script]# chmod x weizhi.sh
[rootlinux-server script]# ./weizhi.sh 1 3 4 6
我的第一个位置参数是:1
我的第二个位置参数是:3
我的第三个位置参数是:4
我的第四个位置参数是:6
一共有 4 个位置参数
你输入的参数分别是:1 3 4 6 变量的子进程继承
#子进程 仅会继承父 shell 的环境变量 不会继承父 shell 的自定义变量
[rootlocalhost ~]# bash # 打开一个子shell
[rootlocalhost ~]# export ahello # 在子shell声明一个环境变量
[rootlocalhost ~]# bash # 在子shell中再打开一个子shell
[rootlocalhost ~]# echo $a # 变量可以生效
hello
[rootlocalhost ~]# exit # 退出子shell 的子shell
exit
[rootlocalhost ~]# exit # 退出子shell
exit
[rootlocalhost ~]# echo $a # 在当前shell中其子shell 声明的环境变量是无效的
变量符号
反引号
在Linux中反引号是一种命令替换的语法。它用于将命令的输出作为另一个命令的参数或赋值给变量。当在命令中使用时其中包含的命令会被执行并将其输出结果取代所在的位置。
练习1
编写一个shell脚本用于搜集其执行主机的信息打印结果如下:
[rootlinux-server ~]# mkdir /opt/test/script
[rootlinux-server ~]# cd /opt/test/script
[rootlinux-server script]# vim test.sh
[rootlinux-server script]# chmod x test.sh
[rootlinux-server script]# ./test.sh
现在的时间是: 2020-08-22-17:34:03
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: linux-server
当前可用网卡IP是: 192.168.246.148/24
##脚本源码如下
#!/usr/bin/bash
# 获取主机基本信息
timedate %F-%T
ipip a | grep ens33 | awk NR2 {print $2}
echo 现在的时间是: $time
echo 当前的用户是: $USER
echo 当前的用户标识: $UID
echo 当前的主机名称是: $HOSTNAME
echo 当前可用网卡IP是: $ip
取当前系统分区剩余空间:
[rootlinux-server script]# df -Th | awk NR6 {print $5}
489M
取当前系统剩余内存:
[rootlinux-server script]# echo 现在的剩余内存是:free -m |awk NR2{print $4}
现在的剩余内存是:16G
取当前cpu平均负载:
[rootlinux-server script]# echo 现在cpu的uptime | cut -d, -f3- #-d指定分隔符-f指定显示区域3-第三列以后(包括第三列)
现在cpu的 load average: 0.00, 0.01, 0.05
方式二
[rootlinux-server script]# echo 现在cpu的uptime | awk -F , {print $3,$4,$5}
现在cpu的 load average: 0.00 0.01 0.05
练习2
编写一个脚本实现收集主机的基本信息最后脚本还会将这些信息写入一个日志文件.
[rootlinux-server script]# vim xinxi.sh
#!/bin/bash
#获取主机基本信息
centimedate %Y-%m-%d %H:%M:%S
nowtimeuptime |awk {print $1}
username$USER
verageuptime |awk -F, {print $3,$4,$5}
mynamexuange
cat file1.txt EOF
echo 时间:$centime
echo 系统的当前时间是: $nowtime
echo 系统当前负载: $verage
echo 当前的用户是: $username
echo 我的名字是: $myname
EOF
[rootlinux-server script]# chmod x xinxi.sh
[rootlinux-server script]# ./xinxi.sh
[rootlinux-server script]# cat file1.txt
转义
\
当一个字符被引用时其特殊含义被禁止把有意义的变的没意义把没意义的变的有意义
# echo you now $1250 #输出you now 250
# echo you now \$1250 #输出you now $1250
变量运算
运算符
整数运算符 加法
- 减法
* 乘法
/ 除法结果为整数
% 取模求余数
** 幂运算Bash 4.0及以上版本支持
关系运算符
用于比较数值常用于条件语句中
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
逻辑运算符
用于组合条件表达式。 逻辑与前面执行成功后面才执行。前面命令执行失败后面命令也不执行。
|| 逻辑或前面执行失败后面执行前面命令执行成功后面不执行。
! 逻辑非取反操作
; 分隔命令不是逻辑运算符从左往右按顺序执行不管前面执行成功与否后面都执行
字符串运算符 字符串相等
! 字符串不相等
* 字符串重复字符串连接
运算方式 $(()) $[] expr
$(())和$[]命令的表达式可以直接嵌入在命令中expr命令需要使用命令替换的方式或将结果赋值给变量。
$(())
$(())命令是一种Shell的算术展开arithmetic expansion的方式用于执行数学运算
如加法、减法、乘法、除法等。
基本语法$((表达式)) 其中表达式可以包含变量、数学运算符和括号。例如
# echo $(( 52-(3*2)/5 )) #输出6
# echo $(((3*2)/5)) #输出1
$[] 和$(())类似只能执行数学运算
# echo $[ 5 2 - (3*2)/5 ] #输出6expr命令 #注意:运算符号两边的空格必须写
expr命令可以执行数学运算和字符串操作
# expr 5 3 #输出8
# expr 5 \* 3 #乘法运算:输出15
# expr 5 * 3 #输出15
# a5
# b7 # echo $a和$b的和是: expr $a $b
5和7的和是: 12bc命令
使用 bc命令来进行高级算术运算如浮点数运算基本算术运算、对数运算、三角函数运算。
bash本身不能做小数计算:需要bc命令转换
# yum install -y bc #安装bc软件包
# echo 2.6*4 | bc #输出10.4
# echo 2^4 | bc #输出16RANDOM函数
# echo $RANDOM #随机生成0到32767的整数
# echo $(($RANDOM % 6 1)) #取1到6之间的随机数
# echo $(($RANDOM % 10 1)) #取1-10之间的随机数
#RANDOM随机数生成器进行取余实现生成范围内随机数
#取余时需要1的原因取余时如果被整除那么余数会是0这样就不在限定范围内了
变量引用
完全引用和部分引用 完全引用: 也叫强引 硬引
当字符串被单引号包围时所有特殊字符和变量名都会被视为普通文本不会被Shell解释或展开原样变量名原样输出比较适合定义显示纯字符串的情况不希望解析变量、命令等的场景。
部分引用: 也叫弱引 软引
当字符串被双引号包围时字符串中的变量会被展开也就是变量名会被替换为变量的值。适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。
无引号在没有任何引号的情况下Shell会尝试解释字符串中的特殊字符和变量名。[rootlinux-server script]# num1
[rootlinux-server script]# echo 1901班有$num个女生
1901班有1个女生
[rootlinux-server script]# echo 1901班有$num个女生
1901班有1个女生
[rootlinux-server script]# echo 1901班有$num个女生
1901班有$num个女生
变量读取
读取用户标准输入:read
read:功能就是读取键盘输入的值并赋给变量var
语法read [-options] [varname ...]
[-options]
-p prompt-string显示提示信息然后读取输入。
-t timeout设置读取输入的超时时间秒数。如果在指定的时间内没有输入read 命令将返回一个非零退出状态。
-s秘密模式。在读取输入时不显示输入的字符常用于密码输入。[varname ...]
read后面的变量var可以只有一个也可以有多个这时如果输入多个数据则第一个数据给第一个变量第二个数据给第二 个变量如果输入数据个数过多则最后所有的值都给最后一个变量
【实例】
[-p]
#!/usr/bin/bash
read -p 请输入你的用户名和密码还有你的年龄: name pass age
echo 你的名字是 $name
echo 你的密码是 $pass
echo 你的年龄是 $age
[-t]
[rootlinux-server script]# vim readtest.sh
#!/bin/bash
# read test
read -p 请输入你的银行卡帐号 num
read -p 请在五秒内输入密码 -t 5 pass
echo 你的密码错误!
[rootlinux-server script]# ./readtest.sh
[-s]
案例2 #-s 选项 能够使read命令中输入的数据不显示在监视器上
[rootlinux-server script]# vim readtest3.sh
#!/bin/bash
read -s -p Enter your password: pass
echo your password is $pass
exit 1
[rootlinux-server script]# chmod x readtest3.sh
[rootlinux-server script]# ./readtest3.sh
取消屏幕回显
在Shell中取消屏幕回显通常是在需要用户输入密码或其他敏感信息时使用因为在这种情况下显示输入的内容是不安全的。stty命令用于设置和报告终端行输入和输出的格式。
stty -echo 取消回显
stty echo 恢复回显显示变量长度
使用参数扩展来获取变量的长度使用 ${#variable} 的形式来得到变量值的字符数这里的 # 符号用于获取变量值的长度。${#variable} 返回的是字符数这意味着它也会计算空格、标点符号和其他非字母数字字符。如果变量未被初始化或其值为空${#variable} 将返回0表示变量的长度为0。
[rootlinux-server ~]# a123
[rootlinux-server ~]# echo ${#a} #表示$var的长度
3
[rootlinux-server ~]# vim test.sh
#!/bin/bash
empty_var #定义一个空变量
length${#empty_var} #获取变量的长度
# 输出变量的长度
echo 空变量的长度: $length
[rootlinux-server ~]# sh test.sh
空变量的长度: 0
菜单脚本练习
[rootlinux-server ~]# vim d.sh
#!/bin/bash# 定义一个函数来显示菜单
show_menu() {echo 请选择你想使用的功能echo 1. 配置yum客户端echo 2. 添加A记录echo 3. 一键安装LAMP环境echo 4. 一键配置静态IPecho 5. 退出
}
# 定义一个函数来配置IP地址
config_ip() {echo 这是配置IP地址的小工具# 这里可以添加具体的IP配置代码
}
# 主函数
main() {while true; doshow_menuread -p 请输入选项编号1/2/3/4/5: numcase $num in1)echo 配置yum客户端功能;;2)echo 添加A记录功能;;3)echo 一键安装LAMP环境功能;;4)config_ip;;5)echo 退出菜单。break;;*)echo 你输入的不正确请按提示输入;;esacdone
}
# 调用主函数
main[rootlinux-server script]# chmod x d.sh
[rootlinux-server script]# ./d.sh
脚本运行
创建bash脚本shell脚本
1.创建脚本文件 指定命令解释器注释编写bash指令集合
2.修改权限
bash脚本执行
1.直接执行给脚本执行权限
# chmod x yourscript.sh
# ./yourscript.sh 脚本的路径来执行
# /path/to/yourscript.sh 脚本位于当前目录之外提供完整的路径
2.使用 source 或 . 命令
在当前Shell会话中执行脚本并应用其环境变量更改。
# source yourscript.sh
# . yourscript.sh
两种方法都是在当前Shell环境中执行脚本而不是在子Shell中因此任何环境变量的变化都将保留在当前会话中。
3.bash
# bash yourscript.sh 脚本的路径来执行
# bash /path/to/yourscript.sh 脚本位于当前目录之外提供完整的路径
反引号使用
取命令结果用。把命令的结果拿出来
[rootlinux-server ~]# adate %m%d
[rootlinux-server ~]# echo $a
1225
[rootlinux-server ~]# a$(date %m-%d)
[rootlinux-server ~]# echo $a
12-25
#反引号亦可用$() 代替 ${}使用
在shell中${}是一个特殊的语法用于进行变量替换和变量扩展。它可以用于以下几种情况1. 变量替换
${变量名}替换为变量的值。
${变量名:-替换值}如果变量未定义或为空则使用默认值。
${变量名:替换值}如果变量未定义或为空则将其设置为默认值。
${变量名:替换值}如果变量定义且非空则使用替换值。
${变量名:?错误信息}如果变量未定义或为空则输出错误信息并退出。
【实例1】
nameMike
age
echo ${name:-John} # 输出 Mike因为name非空
echo ${name:John} # 输出 Mike因为name非空
echo ${name:John} # 输出 John因为name非空
echo Name: ${age:?age is null} # 如果age为空输出age is null并退出2. 数组变量替换
${数组名[]}返回数组的所有元素。每个元素都是单独的词token即使它们之间没有空格。适合于需要分别处理数组中的每个元素的场合例如在 for 循环中。
${数组名[*]}返回数组的所有元素这些元素被合并成一个字符串中间由默认的IFS字符分隔。适合于需要将数组作为一个整体来处理的场合例如将数组传递给一个接受多个参数的命令。
${#数组名[]}返回数组的元素个数。
${#数组名[*]}返回数组的元素个数。
【实例2】
fruits(apple banana orange)
echo All fruits: ${fruits[]} # 输出All fruits: apple banana orange
echo Fruit count: ${#fruits[]} # 输出Fruit count: 33. 命令替换
${命令}将命令的输出结果替换为字符串
current_date$(date %Y-%m-%d)
echo Current date is ${current_date}变量替换-匹配截取
切片
在Shell中可以使用切片slicing的方式从字符串中提取特定的部分。切片可以用于字符串、数组等数据类型的截取操作。如果切片的长度参数为负数表示从起始位置开始截取到倒数第几个字符
切片的语法为${变量名:起始位置:长度} 或者 ${变量名:起始位置}。
切片
[rootlinux-server ~]# a12345678
[rootlinux-server ~]# echo ${a:5} #从左往右第5位开始截取留下后三位
678
[rootlinux-server ~]# echo ${a:3:4} #从第3位开始截取留下后四位的剩下的都不要。
4567
[rootlinux-server ~]# echo ${a:2:-1} #从左往右第2位开始截取到从右往左第一位
34567
[rootlinux-server ~]# echo ${a:2:-2}
3456
参数解释
用冒号截取echo $a: :从哪里截取留那里。
脚本案例
[rootlocalhost ~]# vim test11.sh
#!/usr/bin/bash
read -s -p 请输入您的手机号 phone
echo
echo 你的手机号是 $phone
echo 手机号后四位是 ${phone:7}
匹配截取
语法
${变量#关键词} 若变量内容从头开始的数据符合『关键词』则将符合的最短数据切除
${变量##关键词} 若变量内容从头开始的数据符合『关键词』则将符合的最长数据切除
${变量%关键词} 若变量内容从尾向前的数据符合『关键词』则将符合的最短数据切除
${变量%%关键词} 若变量内容从尾向前的数据符合『关键词』则将符合的最长数据切除
参数解释
*表示全部字符。
%最短尾匹配
%%最大尾匹配
%从右往左
#从左往右
例:
file/dir1/dir2/dir3/my.file.txt
${file#*/}: 拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}: 拿掉最后一条 / 及其左边的字符串:my.file.txt
${file#*.}: 拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个 . 及其左边的字符串:txt
${file%/*}: 拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}: 拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边)
单一符号是最小匹配;两个符号是最大匹配(贪婪匹配)。实战
urlwww.sina.com.cn
echo ${#url} 获取变量的长度
#输出15
echo ${url} 正常显示变量
#输出www.sina.com.cn
echo ${url#*.} #*.表示从前往后匹配第一个出现的点号.后的所有字符。
#输出sina.com.cn
echo ${url##*.} ##表示最长匹配匹配所有前面的字符直到最后一个点号为止
#输出cn
echo ${url%.*} %.*表示从后向前匹配最近的一个点号.保留该点号之前的所有字符
#输出www.sina.com
echo ${url%%.*} 从后往前匹配到“.”最长匹配去掉从最后一个点号到字符串结尾的所有字符
#输出www
echo ${url#a.} 不加* 不匹配任何部分因为字符串不是以a.开头的 输出www.sina.com.cn
echo ${url#*a.} 加*匹配任意数量的字符后面跟着a. 输出com.cn
[rootlocalhost ~]# vim mail.sh
脚本案例
#!/usr/bin/bash
read -p 请输入你的邮箱 mail
echo 你的邮箱是$mail
echo 你的邮箱服务器是${mail#*}
mail_host${mail#*}
case $mail_host in163.com)echo 网易服务器;;126.com)echo 126服务器;;qq.com)echo qq邮箱;;*)echo 您输入的邮箱不正确exit 2
esac
变量内容的替换
语法
${变量/旧字符串/新字符串} 若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串替代』
${变量//旧字符串/新字符串} 若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串替代』
实战
[rootlinux-server ~]# a123456123789
[rootlinux-server ~]# echo ${a/1/} #第一次匹配的被替换
23456123789
[rootlinux-server ~]# echo ${a/1/0} #第一次匹配到1替换成0
023456123789
[rootlinux-server ~]# echo ${a//1/} #全局的匹配被替换
2345623789
[rootlinux-server ~]# echo ${a//1/x} #全局匹配到1替换成x
x23456x23789
提取路径的文件名部分或目录部分
basename 命令
basename 提取路径中的文件名部分
basename [选项] [路径]
-a返回所有路径中文件名的列表。
-s 后缀去除文件名中的指定后缀。
-z以空字符作为路径分隔符适用于处理包含空格等特殊字符的路径。
例:
[rootlinux-server ~]# temp/home/temp/1.test
[rootlinux-server ~]# basebasename $temp
[rootlinux-server ~]# echo $base
1.test
dirname命令
dirname 提取路径中的目录部分
dirname [选项] [路径]例:
[rootlinux-server ~]# temp/home/temp/1.test
[rootlinux-server ~]# dirdirname $temp
[rootlinux-server ~]# echo $dir
/home/temp