0.vim命令
vim
gg 移动到文档第一行
G 移动到文档最后一行
:set nu 显示行号
:set noun 取消行号
nG 移动到指定n行,例如20G
$ 移动到行尾
0 移动到行头
clrt+f 屏幕向下移动一页
clrt+b 屏幕向上移动一页
:%s+word1+word2+g 搜索文本,将word1字符串,替换成word2字符串
x 向后删除一个字符
X 向前删除一个字符
shift+d 删除当前行,光标后的字符
dd 删除游标所在整行
ndd 删除光比所在向下n列,例如:3dd
yy 复制游标所在行
p,P 小p将已复制的数据在光标下一行粘贴,大P则为粘贴在游标上一行
u 复原前一个动作,回退一步
i 从当前光标插入
o, O 小写的o当前光标下一行插入 大写的O当前光标上一行插入
r, R 小写的r替换字符,大写的R
:q! 强制退出不保存
:wq 保存
ZZ 大写的ZZ,保持后快速退出(需要在esc退出编辑模式下操作)
ctrl+v 光标移动到215.18前,通过上下左右移动选择一块区域,选号后按y 复制,p 粘贴想要的内容
1 2 3 4 5 6
tcp 0 0 :::10302 :::* LISTEN
tcp 0 0 ::ffff:172.16.10.205:10302 ::ffff:215.18.157.74:5660 ESTABLISHED
tcp 0 0 ::ffff:172.16.10.205:10302 ::ffff:110.182.143.19:27490 TIME_WAIT
tcp 0 0 ::ffff:172.16.10.205:10302 ::ffff:110.182.143.19:27489 TIME_WAIT
tcp 0 0 ::ffff:172.16.10.205:10302 ::ffff:219.66.163.171:52754 ESTABLISHED
tcp 0 0 ::ffff:172.16.10.205:10302 ::ffff:59.39.132.243:30368 TIME_WAIT
这样复制出来的结果就是:
215.18.157.74:5660
110.182.143.19:27490
110.182.143.19:27489
219.66.163.171:52754
59.39.132.243:30368
1.生成指定文件
shell
#使用dd,if参数指定了输入文件(/dev/zero表示一个无限的全零字节流)
#of参数指定了输出文件的路径和名称(/root/1.log)
#bs参数指定了每次读取和写入的块大小(这里是10MB)
#count参数指定了要复制的块数(这里是1)
dd if=/dev/zero of=/root/1.log bs=10M count=1
2.shell压缩脚本
cat test.sh
shell
#!/bin/bash
#要压缩的目录或者文件
source_dir="/mnt"
#压缩后输入的路径或者文件
output_file="/root/mnt.tar.gz"
#使用tar 命令压缩,通过 --exclude 过滤目录或者文件
tar zcvf "${output_file}" --exclude="/mnt/test" --exclude="/mnt/1.log" "${source_dir}"
#打包
#tar zcvf 2020.tar.gz *2020*.log
#解压
#tar -zxvf ktgl20201207.tar.gz -C /data/webapp
#不想解压,查看压缩包内容
#tar ztvf ktgl20201207.tar.gz
3.自定义函数别名
shell
#显示当前定义的所有别名
alias
#打开当前用户的.bashrc文件,自定义环境变量、别名和函数等设置
vim ~/.bashrc
#定义函数
testFunc(){
ps -ef|grep nginx
}
#使变量生效
source ~/.bashrc
#定义别名
alias psnginx=testFunc
4.查看命令cat
shell
#显示行号
cat -n myfile.txt
#显示特殊字符
cat -A myfile.txt
在cat命令后面添加选项-A(或-vET)可以改变输出格式,以显示一些特殊字符的可见表示。
具体来说,-A选项会将以下特殊字符添加到输出中:
- 非打印字符(不包括换行符和制表符)会以^后接对应的控制字符形式显示。例如,ASCII 值为 1 的字符会显示为 ^A。
- 行尾的 $ 符号会显示在每行的末尾。
- 制表符会显示为 ^I。
这个选项通常用于显示一些看不见的特殊字符,以便进行文本分析或调试。
$ cat -A myfile.txt
This is a line of text.^M$
This is another line of text with a tab character. ^I$
#在上面的示例中,^M 表示回车符,^I 表示制表符,$ 表示行尾。
5.find命令
shell
#查找ceph-csi-3.2.0目录下,所有的*log文件
find /ceph-csi-3.2.0/ -name "*log"
#查看/ceph-csi-3.2.0目录下所有*.sh文件每个的大小
#注:xargs组合多个命令的一个工具
find /ceph-csi-3.2.0/ -type f -name "*.sh" | xargs du -sh
#复制/ceph-csi-3.2.0目录下所有*.sh文件到/root/test下
find /ceph-csi-3.2.0/ -type f -name "*.sh" -exec cp -a {} /root/test \;
#/ceph-csi-3.2.0目录开始搜索文件,排除目录/ceph-csi-3.2.0/scripts/*,排除文件/ceph-csi-3.2.0/deploy.sh,查找*.sh文件
find /ceph-csi-3.2.0/ -type f -path "/ceph-csi-3.2.0/scripts/*" -o -path "/ceph-csi-3.2.0/deploy.sh" -o -type f -name "*.sh" -print
#比较下面两个打包的区别
#第一个是打包成一个文件
find /ceph-csi-3.2.0/ -type f -path "/ceph-csi-3.2.0/scripts/*" -o -path "/ceph-csi-3.2.0/deploy.sh" -o -type f -name "*.sh" -print | xargs tar zcvf allSh.tar.gz
#第二个是打包成多个文件
find /ceph-csi-3.2.0/ -type f -path "/ceph-csi-3.2.0/scripts/*" -o -path "/ceph-csi-3.2.0/deploy.sh" -o -type f -name "*.sh" -print -exec tar zcvf {}.tar.gz {} \;
6.ln 软链接和硬链接
shell
#软链接
ln -svf /ceph-csi-3.2.0/allSh.tar.gz /root/
● -s:创建软链接(Symbolic Link),而不是创建硬链接。
● -v:显示详细的输出,即在创建链接时显示正在进行的操作。
● -f:强制执行操作,即如果目标文件已存在,则覆盖它。
#硬链接
ln /ceph-csi-3.2.0/allSh.tar.gz /root/
在Linux中,ln命令用于创建链接(link)文件。其中有两种类型的链接:软链接(Symbolic Link)和硬链接(Hard Link)。它们之间有以下区别:
- 路径类型:软链接是一个指向目标文件的路径名,而硬链接是一个指向目标文件的物理副本。
- 文件类型:软链接被视为一个独立的文件,它具有自己的 inode 和文件权限。硬链接是文件系统中原始文件的另一个名称,实际上它们共享相同的 inode 和文件权限。
- 跨文件系统:软链接可以跨越不同的文件系统,因为它们只是包含目标文件路径的文本文件。硬链接只能在同一文件系统内工作,因为它们依赖于 inode。
- 目标更新:如果目标文件被重命名、删除或移动,软链接将失效,而硬链接仍然有效,因为它们直接指向目标文件的物理副本。
- 目录链接:软链接可以链接到目录,而硬链接不能链接到目录。
- 多个链接:对于硬链接,可以有多个链接指向同一文件,而软链接只能有一个链接指向目标文件。
总之,软链接是指向目标文件路径的独立文件,可以跨文件系统并且保留原始文件的路径和权限信息。硬链接是原始文件的另一个名称,具有相同的inode和权限,不能跨越文件系统,并且在目标文件更改时仍然有效。
使用ln命令创建链接时,如果不指定任何选项,默认情况下会创建硬链接。要创建软链接,可以使用ln -s选项。
7.文件和目录对比
shell
diff 文件内容对比命令(案例:diff 1.txt 2.txt)
du 查看文件或目录使用空间大小
basename 过滤出路径下面最后的文件名或目录
dirname 从文件名中删除最后一个组成部分
df 查看系统硬盘占用空间情况 (案例:df -TH)
df -i 查看磁盘inode使用空间
#查看目录下,低于100K的文件数量
find /mnt -type f -size -100k | wc -l
#删除低于100K,过多小文件
find /mnt -type f -size -100k | xargs rm -f
[root@k8s-master01 jtpv]# basename /root/jtpv/pv.yaml
pv.yaml
[root@k8s-master01 jtpv]# dirname /root/jtpv/pv.yaml
/root/jtpv
8.目录或文件权限
shell
[root@news-static ~]# ls -l 1.html
-rw-r--r--. 1 root root 0 12月 25 2019 1.html
[root@news-static ~]# ls -ld nginx-1.23.2
drwxr-xr-x. 9 1001 1001 4096 11月 30 2022 nginx-1.23.2
r w x
4 2 1
读 写 执or进入
0644/-rw-r--r-- #文件
0755/drwxr-xr-x #目录
0644+0022=0666 文件最大权限666
0755+0022=0777 目录最大权限777
umask
0022 #第一位0: 表示这是一个八进制数
[root@news-static ~]# umask
0022
[root@news-static ~]# ls -l 1.html
-rw-r--r--. 1 root root 0 12月 25 2019 1.html
[root@k8s-master01 ~]# diff 1.txt 2.txt
12a13
> 123
chown 更改文件所有者以及所有组,常用-R 是目录内所有文件都授权
chattr +i 锁定文件
lsattr 显示文件或目录的扩展属性的命令
chattr +a 只允许增加内容
[root@news-static ~]# lsattr 2.txt
-------------e- 2.txt
[root@news-static ~]# chattr +i 2.txt
[root@news-static ~]# lsattr 2.txt
----i--------e- 2.txt
[root@news-static ~]# chattr -i 2.txt
[root@news-static ~]# lsattr 2.txt
-------------e- 2.txt
[root@news-static ~]#
[root@news-static ~]# chattr +a 2.txt
[root@news-static ~]# lsattr 2.txt
-----a-------e- 2.txt
[root@news-static ~]# echo 3 > 2.txt
-bash: 2.txt: 不允许的操作
[root@news-static ~]# echo 3 >> 2.txt
[root@news-static ~]# cat 2.txt
123
3
[root@news-static ~]#
9.遍历目录
shell
[root@news-static mydir]# cat test.sh
#!/bin/bash
directory=$1
# 使用 find 命令递归遍历指定目录下的所有文件和子目录
find "$directory" -print | while read file; do
if [[ -d "$file" ]]; then # 判断是否为目录
echo "Dire: $file"
elif [[ -f "$file" ]]; then # 判断是否为文件
echo "File: $file"
fi
done
[root@news-static mydir]# /tmp/mydir/test.sh /tmp/mydir
Dire: /tmp/mydir
File: /tmp/mydir/boge.sh
File: /tmp/mydir/test.sh
Dire: /tmp/mydir/dir1
Dire: /tmp/mydir/dir1/dir2
Dire: /tmp/mydir/dir1/dir2/dir3
File: /tmp/mydir/dir1/dir2/dir3/file3.log
File: /tmp/mydir/dir1/dir2/file2.log
File: /tmp/mydir/dir1/file1.log
[root@news-static mydir]#
[root@news-static mydir]# cat boge.sh
#!/bin/bash
listFile() {
local tempDir=$1
# 使用 find 命令递归遍历指定目录下的所有文件和子目录
find "$tempDir" -print | while read file; do
if [[ -d "$file" ]]; then # 判断是否为目录
echo "Dir: $file"
elif [[ -f "$file" ]]; then # 判断是否为文件
echo "Fil: $file"
fi
done
}
#运行函数
listFile $1
[root@news-static mydir]# /tmp/mydir/test.sh /tmp/mydir
Dire: /tmp/mydir
File: /tmp/mydir/boge.sh
File: /tmp/mydir/test.sh
Dire: /tmp/mydir/dir1
Dire: /tmp/mydir/dir1/dir2
Dire: /tmp/mydir/dir1/dir2/dir3
File: /tmp/mydir/dir1/dir2/dir3/file3.log
File: /tmp/mydir/dir1/dir2/file2.log
File: /tmp/mydir/dir1/file1.log
[root@news-static mydir]#
10.处理僵尸进程
生产案例:
zombie 僵尸进程的发现,查看,及解决的步骤
1、通过 top 查看是否存在zombie 僵尸进程
[root@localhost ~]# top
top - 14:53:32 up 86 days, 9:47, 2 users, load average: 2.09, 1.91, 1.79
Tasks: 1248 total, 1 running, 1246 sleeping, 0 stopped, 1 zombie
Cpu(s): 16.5%us, 7.3%sy, 0.0%ni, 72.9%id, 3.1%wa, 0.0%hi, 0.2%si, 0.0%st
2、查看具体是哪个进程
[root@localhost ~]# ps -A -o stat,ppid,pid,cmd | grep -e "^1^"
Z 2216 31127 [abrt-server]
3、查看僵尸进程是什么应用
[root@localhost ~]# lsof -p 2216
4、kill僵尸进程
[root@localhost ~]# kill -9 2216
11.shell并发快速查询在线IP
cat select_ip.sh
shell
#!/bin/bash
#__author__: boge
#不在线ip记录
> ./ip_offline.txt
#在线ip记录
> ./ip_online.txt
#传入网段3个参数案例: 10.0.1 1 254
if [ $# -ne 3 ];then
echo "Usage: bash $0 10.0.1 1 254"
exit 3
fi
pingnum=`seq $2 $3`
for i in $pingnum
do
{
ping -c 1 -i 0.1 -W 1 $1.$i &> /dev/null
if [ $? -eq 0 ];then
echo "IP: $1.$i is online."
echo "$1.$i" >> ./ip_online.txt
else
echo "IP $1.$i is offline."|tee -a ./ip_offline.txt
fi
}&
done
#等待所有子进程返回结果后在退出主进程
wait
12.循环for和while
shell
#for循环输出1到10的数字
[root@news-static ~]# for i in `seq 10`;do echo "$i";sleep 1;done
#无限循环输出
[root@news-static ~]# cat while.sh
#!/bin/bash
while true
do
date
sleep 1
done
#while 循环输出1到10的数字
[root@news-static ~]# cat while.sh
#!/bin/bash
counte=1
while [ $counte -le 10 ]
do
echo $counte
counte=$((counte + 1))
sleep 0.5
done
11.shell中的列表和字典
shell
-------------
SHELL数组(实现列表)
-------------
# family=(aaa bbb ccc) <--- 定义数组
# echo ${#family[*]} <--- 取数组里变量长度
3
# echo ${family[0]} <--- 取数组第一个变量
aaa
# echo ${family[1]} <--- 取数组第二个变量
bbb
# echo ${family[2]} <--- 取数组第三个变量
ccc
# echo ${family[*]} <--- 取数组里所有变量
aaa bbb ccc
# echo ${family[*]:2} <--- 去掉数组里的前两个值,保持取最后一个值
ccc
脚本示例:
# vim test.sh
#!/bin/bash
family=( # or 也可以这样定义 family=(aaa bbb ccc)
aaa
bbb
ccc
)
for name in ${family[*]} #第一种方法,常规for循环取值的方式
do
echo $name
done
echo "================="
for ((name=0;name<${#family[*]};name++)) #第二种方法
do
echo ${family[name]}
done
执行结果:
[root@nfs-server scripts]# bash test.sh
aaa
bbb
ccc
=================
aaa
bbb
ccc
实现"字典":
my_config=(
shanghai+http://10.0.1.201+boge+devops1
beijing+http://10.0.1.202+boge+devops2
hongkong+http://10.0.1.203+boge+devops3
)
for r in `echo ${regions}`
do
export MY_REGION=`echo ${my_config[@]}|tr " " "\n"|grep -w $r|awk -F+ '{print $1}'`
export MY_URL=`echo ${my_config[@]}|tr " " "\n"|grep -w $r|awk -F+ '{print $2}'`
export MY_USERNAME=`echo ${my_config[@]}|tr " " "\n"|grep -w $r|awk -F+ '{print $3}'`
export MY_PASSWORD=`echo ${my_config[@]}|tr " " "\n"|grep -w $r|awk -F+ '{print $4}'`
echo "====== $r START ======"
echo $MY_URL
echo $MY_USERNAME
echo $MY_PASSWORD
echo $MY_REGION
echo "====== $r END ======"
done
# 另外一种实现字典的形式
#!/bin/bash
test='
{
"aaa": 1,
"bbb": 2,
"ccc": 3
}
'
echo $test|jq -r ".aaa"
12.运维服务菜单选项
1. if elif else
脚本
shell
#!/bin/bash
# 这个脚本演示了如何使用 case 语句根据用户输入执行不同的操作
echo "请输入你的选择[1 - 4]:"
echo "1. 开始服务"
echo "2. 停止服务"
echo "3. 重启服务"
echo "4. 退出服务"
read choice
if [[ $choice -eq 1 ]];then
echo "开始服务了"
elif [[ $choice -eq 2 ]];then
echo "停止服务了"
elif [[ $choice -eq 3 ]];then
echo "重启服务了"
else
echo "退出服务了"
fi
2.使用case
脚本:
shell
#!/bin/bash
# 这个脚本演示了如何使用 case 语句根据用户输入执行不同的操作
echo "请输入你的选择[1 - 4]:"
echo "1. 开始服务"
echo "2. 停止服务"
echo "3. 重启服务"
echo "4. 退出服务"
read choice
case $choice in
1)
echo "Starting service..."
# 执行启动操作的命令
;;
2)
echo "Stopping service..."
# 执行停止操作的命令
;;
3)
echo "Restarting service..."
# 执行重启操作的命令
;;
4)
echo "Exiting service..."
exit
;;
*)
echo "Invalid choice"
;;
esac
13.标准的运维工具脚本
shell
#!/bin/bash
# 这个脚本演示了如何使用 getopts 函数解析命令行参数
if [ $# -eq 0 ];then
echo "Usage: bash $0 (-A|-D|-L) -e (1h or more) -t (admin|view) -u boge"
exit 1
fi
# 默认值
ACTION=""
EXPIRY=""
USER_TYPE=""
USER_NAME=""
# 解析命令行参数
while getopts "ADLe:t:u:" OPTION; do
case $OPTION in
A)
ACTION="add-test $1"
;;
D)
ACTION="del-test $1"
;;
L)
ACTION="list-test $1"
;;
e)
EXPIRY="$OPTARG"
[[ $OPTARG =~ ^[1-9][0-9]*h$ ]] || { echo "'-e' must be set like '2h, 5h, 50000h, ...'"; exit 1; }
;;
t)
USER_TYPE="$OPTARG"
[[ $OPTARG =~ ^(admin|view)$ ]] || { echo "'-t' can only be set as 'admin' or 'view'"; exit 1; }
;;
u)
USER_NAME="$OPTARG"
;;
?)
echo "Invalid option: -$OPTARG"
exit 1
;;
esac
done
function add-test(){
# 打印解析的参数
echo "ACTION: $ACTION"
echo "EXPIRY: $EXPIRY"
echo "USER_TYPE: $USER_TYPE"
echo "USER_NAME: $USER_NAME"
}
function del-test(){
# 打印解析的参数
echo "ACTION: $ACTION"
echo "EXPIRY: $EXPIRY"
echo "USER_TYPE: $USER_TYPE"
echo "USER_NAME: $USER_NAME"
}
function list-test(){
# 打印解析的参数
echo "ACTION: $ACTION"
echo "EXPIRY: $EXPIRY"
echo "USER_TYPE: $USER_TYPE"
echo "USER_NAME: $USER_NAME"
}
${ACTION}
参考博客:博哥爱运维
https://www.toutiao.com/article/7271959603280265739?wid=1698656801777
- Zz ↩︎