1、使用While循环打印目录中的所有文件:
#!/bin/bash
# 定义要遍历的目录
directory="./"
# 使用while循环读取目录中的文件
while read file
do
echo "Found file: $file"
done < <(find "$directory" -maxdepth 1 -type f)
最后一行的"< <" 并不是一个单独的输入重定向符号,两个< 至少有一个空格,它是两个符号的组合:左边 < 代表左边接受从右边输入,右边 <(command) 代表右边shell(子shell)命令的输出,将输出输出到左边。
2、 使用awk截取字符串:注意使用的是单引号
awk -F '分隔符' '{print $列号}'
使用cut截取字符串:
cut -d '分隔符' -f列号
3、shell脚本参数的获取,如果参数是以”字符串+列表“的形式传入,那么shell会自动拆分成多个参数再传入脚本。例如参数:192.168.1.{1,2,3,4}
,该参数会被自动拆分成192.168.1.1、192.168.1.2、192.168.1.3、192.168.1.4四个,脚本中引用$2
,对应着192.168.1.2。
4、统计系统登录用户数
grep "bash$" /etc/passwd | wc -l
5、awk命令的工作方式:
awk 'BEGIN{ 语句块 } pattern { commands } END{ 语句块 }' file
(1)首先执行BEGIN语句块的语句。
(2)接着从文件或stdin中读取一行,如果能匹配pattern,则执行随后的commands语句。重复这个过程,知道文件全部被读取完毕。pattern是可选的,若果没有pattern,awk就认为所有行都是匹配的。
(3)当读取至输入流末尾,执行END语句块的语句。
6、shell脚本传入参数的方法:
1)脚本执行时,参数跟在可执行文件后面传入,这时在脚本中引入参数的方法就是$1
(第一个参数)、$2
(第二个参数)、······
2)在脚本内部,交互传入参数,例如:
#!/bin/bash
read -p "请输入一个整数:" num1
read -p "请输入一个整数:" num2
echo $num1,$num2
7、rpm软件包管理
RPM软件包:扩展名为".rpm" ,适用于RHEL、CentOS等系统
DEB软件包:扩展名为".deb" , 适用于Ubuntu、Debian等系统
rpm -qa | grep nfs # 显示当前系统中以rpm方式安装的所有软件且过滤出有关nfs的软件包
rpm -qi 软件包名 #显示已安装的指定软件的详细信息
rpm -qc 软件包名 #显示已安装的指定软件的配置文件
rpm -qR 软件包名 #显示已安装的指定软件的依赖的软件包及文件
8、在shell脚本中(bash编程),<<EOF
表示后续的输入作为子命令或子Shell的输入,直到遇到EOF
为止,再返回到主Shell。也就是说当想自动完成一个程序子命令的自动输入的时候就可以用这个方法,举例说明:
#!/bin/bash
fdisk /dev/mmcblk0 <<eof
d
3
n
p
3
w
eof
EOF 是一种特殊的输入重定向操作符。它的作用是在命令行中指定一个多行输入,并将其作为标准输入传递给命令。在编写 shell 脚本时,经常用来在命令行中提供多行输入。例如封装一个函数,对某个文件追加内容。
#!/bin/bash
function AdditionalInformation(){
cat <<-EOF >>file.txt
行字符串~
2行字符串~
EOF
}
AdditionalInformation
9、实时监控脚本编写示例:
方法:在while循环中不断读取变量的值,而变量的值是在循环外通过执行命令获得的
监控内存和磁盘容量,小于给定值时报警
#!/bin/bash
# 实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,发送报警邮件给root管理员
# 提取根分区剩余空间
disk_size=$(df / | awk '/\//{print $4}')
# 提取内存剩余空间
mem_size=$(free | awk '/Mem/{print $4}')
while :
do
# 注意内存和磁盘提取的空间大小都是以 Kb 为单位
if [ $disk_size -le 512000 -a $mem_size -le 1024000 ]
then
mail ‐s "Warning" root <<EOF
Insufficient resources,资源不足
EOF
fi
done
10、假设有一个叫做gedit的应用程序正在运行,可以使用pgrep
命令获得gedit的进程ID:
pgrep gedit
进一步的,我们可以使用如下命令查看该进程的环境变量
cat /proc/进程ID号/environ
由于该文件中记录的变量之间由\0
分割,也就是彼此紧挨着,因此可以通过管道传给tr
将其中的\0
换成\n
cat /proc/进程ID号/environ | tr '\0' '\n'
11、如果需要在PATH中添加一条新路径,可以使用如下命令:
export PATH="$PATH:/需要/添加的/新路径"
12、变量值的长度可以通过${#变量名}
的方式获得
13、sleep命令可以延迟脚本执行一段时间(以秒为单位)。使用方式直接命令后加数字就可以,不用带单位。
sleep 1
#延时一秒
14、提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默认的 123456 作为默认密码。
#!/bin/bash
read -p "请输入用户名: " user
#使用‐z 可以判断一个变量是否为空,如果为空,提示用户必须输入账户名,并退出脚本,退出码为 2
#没有输入用户名脚本退出后,使用$?查看的返回码为 2
if [ -z $user ];then
echo "您不需输入账户名"
exit 2
fi
#使用 stty ‐echo 关闭 shell 的回显功能
#使用 stty echo 打开 shell 的回显功能
stty -echo
read -p "请输入密码: " pass
stty echo
pass=${pass:-123456}
#${var:-word}若变量var已存在并且非null,则返回$var的值;否则返回字符串“word”,原变量var的值不受影响。
useradd "$user"
echo "$pass" | passwd ‐‐stdin "$user"
15、批量修改脚本
for i in `ls *.$1`
do
mv $i ${i%.*}.$2
done
${i%.*}
:取最后一个"."之前的内容 (从 $i 的右边开始匹配模式子串 “.*” ,并将最短的匹配结果删除)
${i%%.*}
:取第一个"."之前的内容 (从 $i 的右边开始匹配模式子串 “.*” ,并将最长的匹配结果删除)
${i##*.}
:取最后一个"."之后的内容 (从 $i 的左边开始匹配模式子串 “*.” ,并将最长的匹配结果删除)
${i#*.}
:取第一个"."之后的内容 (从 $i 的左边开始匹配模式子串 “*.” ,并将最短的匹配结果删除)
16、多进程执行
当循环体的执行比较费时间,为了节省执行的总时间,我们可以将循环体单独写成函数,然后在循环中循环执行该函数,且后面加“&”符号,代表在后台执行(也就是单独开一个进程执行),这样就会开多个进程并行执行。
func()
{
原循环体内容,注意循环变量要用$1代替。
}
for i in {1..254}
do
func 参数 &
done
17、动态时针显示,echo命令后的-e参数是输出转义字符,“\b”代表不换行,“\c”代表删除刚刚输出的字符。
#! /bin/bash
# 进度条,动态时针版本
# 定义一个显示进度的函数,屏幕快速显示| / ‐ \
INTERVAL=0.5
for i in {1..50}
do
echo -e "-\b\c"
sleep $INTERVAL
echo -e "\\b\c"
sleep $INTERVAL
echo -e "|\b\c"
sleep $INTERVAL
echo -e "/\b\c"
sleep $INTERVAL
done
18、{start..end}
可以用来迭代从start到end之间的值,如果start等于end的数字会报错。这时候如果是数字迭代,也可以用`seq 9`来表示1到9的数列。这其实是嵌入命令的写法,本质是先执行seq 9命令,生成1到9的数列。
19、我们可以使用 命令 |grep "行关键字" | awk '{print $列数}'
来筛选出命令执行结果中指定行制定列的信息。
例如:
ifconfig eth0 | grep "RX pack" | awk '{print $5}'
# 筛选出 ifconfig eth0 执行结果中 RX pack 所在行第五列的信息
20、批量创建用户
#!/bin/bash
# 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码
# 本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息
for i in `cat user.txt`
do
useradd $i
echo "123456" | passwd ‐‐stdin $i
done
21、按条件掐头去尾
1、字符串掐头
从左向右,最短匹配删除:
- 格式:${变量名#*关键词}
从左向右,最长匹配删除:
- 格式:${变量名##*关键词}
root@kylin:~# DIR="/var/www/html/index.html"
root@kylin:~# echo ${DIR#*/} #删除到最近匹配
var/www/html/index.html
root@kylin:~# echo ${DIR##*/} #删除到最远匹配
index.htm
2、字符串去尾
从右向左,最短匹配删除:
- 格式:${变量名%关键词*}
从右向左,最长匹配删除:
- 格式:${变量名%%关键词*}
root@kylin:~# DIR="/var/www/html/index.html"
root@kylin:~# echo ${DIR%h*} #删除到最近匹配
/var/www/html/index.
root@kylin:~# echo ${DIR%%h*} #删除到最远匹配
/var/www/