赞
踩
service 服务名 start | stop | restart | status
守护进程 daemon
查看服务的方法:/etc/init.d/服务名 ,发现只有两个服务保留在service
systemctl start | stop | restart | status 服务名
查看服务的方法:/usr/lib/systemd/system
multi-user.target 等价于原运行级别 3(多用户有网,无图形界面)
graphical.target 等价于原运行级别 5(多用户有网,有图形界面)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KQrxnd5l-1686570839702)(img\image-20230525091142263.png)]
init 5
init 3
老版本
chkconfig --list # 查看开机自启动的情况
chkconfig network off # 设置network的开机自启动
chkconfig --list
chkconfig network on
chkconfig --level 3 network off # 关闭network的运行级别3
chkconfig --list
chkconfig --level 3 network on # 打开network的运行级别3
新版本
systemctl status NetworkManager
systemctl disable NetworkManager
systemctl status NetworkManager
systemctl enable NetworkManager
systemctl list-unit-files
防火墙
systemctl status firewalld
systemctl stop firewalld.service # 关掉防火墙
systemctl status firewalld
systemctl disable firewalld.service # 关掉防火墙的开机自启动
systemctl status firewalld
systemctl enable firewalld.service
systemctl start firewalld.service # 可以没有.service
systemctl start firewalld
在 linux 领域内大多用在服务器上,很少遇到关机的操作。毕竟服务器上跑一个服务是永无止境的,除非特殊情况下,不得已才会关机。
7* 24小时都启动
shutdown # 关机,默认一分钟后关机
shutdown -c # 取消关机
shutdown now # 立马关机
shutdown 3 # 3分钟后关机
shutdown 15:28 # 15:28关机
预读和延迟的写入
sync # 功能描述:将数据由内存同步到硬盘中
halt # 功能描述:停机,关闭系统,但不断电
poweroff # 功能描述:关机,断电
reboot # 功能描述:就是重启,等同于shutdown -r now
shutdown[选项] 时间
Linux 系统中为了提高磁盘的读写效率,对磁盘采取了 “预读迟写”操作方式。当用户保存文件时,Linux 核心并不一定立即将保存数据写入物理磁盘中,而是将数据保存在缓冲区中,等缓冲区满时再写入磁盘,这种方式可以极大的提高磁盘写入数据的效率。但是,也带来了安全隐患,如果数据还未写入磁盘时,系统掉电或者其他严重问题出现,则将导致数据丢失。使用 sync 指令可以立即将缓冲区的数据写入磁盘。
Shell 可以看作是一个命令解释器,为我们提供了交互式的文本控制台界面。我们可以通过终端控制台来输入命令,由 shell 进行解释并最终交给内核执行。 本章就将分类介绍常用的基本 shell 命令。
ls -l /bin/ | grep sh
基本语法
manual 手册
man[命令或配置文件] # 功能描述:获得帮助信息
man ls # 按q退出
man cd # 进入的却是bash,cd是shell中的内置命令,一般都是比较基础的命令,exit也是,写在bash内部的
type cd # 判断命令类型
type ls
type useradd
type exit
type history # history 是显示所有之前执行的命令的记录
man -f cd
man 1p cd
man 3 cd
man man
显示说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbQnGj0B-1686570839703)(img\image-20230525104027940.png)]
案例实操
查看 ls 命令的帮助信息
[root@hadoop101 ~]# man ls
一部分基础功能的系统命令是直接内嵌在 shell 中的,系统加载启动之后会随着 shell 一起加载,常驻系统内存中。这部分命令被称为“内置(built-in)命令”;相应的其它命令被称为“外部命令”。
help cd
help ls # 这个不匹配,ls是外部命令
ls --help
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmmB1eAu-1686570839704)(img\image-20230525145042752.png)]
pwd:print working directory 打印工作目录
基本语法
pwd # 功能描述: 显示当前工作目录的绝对路径
pwd cd /etc/sysconfig pwd type pwd # pwd 是内置命令 help pwd cd /root/桌面/ # 绝对路径 pwd cd /root/视频/ # 绝对路径 cd ../视频/ # 相对路径 cd ../桌面/ # 相对路径 cd /root cd 桌面/ # 从/root 用相对路径的方式 cd 到桌面 cd - # 返回上次的文件夹 cd # 回到主目录 , root回到的是主目录 , atguigu用户 则是回到 /home/atguigu/ cd /home/atguigu/ su atguigu # 切换用户为atguigu pwd # 显示的是 /home/atguigu exit # 退出,回到root
ls:list 列出目录内容
基本语法
ls[选项][目标或是文件]
ls
ls -a # -a all 表示所有的 , 这个显示出来的..是上一级目录的意思 , .是所在目录
cd ..
cd .
cd ./桌面/
cd -
ls -l
ll # ll 就是 ls -l 的缩写
type ll
ls -al # ls -al 将所有(包括隐藏文件都将属性权限等数据全部展示)
显示说明
每行列出的信息依次是: 文件类型与权限 链接数 文件属主 文件属组 文件大小用byte来表示 建立或最近修改的时间 名字
cd:Change Directory 切换路径
基本语法
cd [参数]
参数说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P1gjpuMj-1686570839704)(img\image-20230525154617913.png)]
mkdir:Make directory 建立目录
基本语法
mkdir [选项] 要创建的目录
mkdir a ls mkdir /a mkdir /b ls # 没有b,因为是在 / 目录下创建的 ls / mkdir b c # 创建目录b, c ls mkdir d/e/f # mkdir: 无法创建目录"d/e/f": 没有那个文件或目录 mkdir d d/e d/e/f ls d/ ls d/e mkdir -p g/h/i # 使用选项 -p 创建多层目录 ls ls d ls g/h/ rmdir a # 删除目录 ls rmdir b c # 删除目录b, c rmdir d g # rmdir: 删除 "d" 失败: 目录非空; rmdir: 删除 "g" 失败: 目录非空 rmdir d/e/f/ d/e d/ ls rmdir -p g/h/i/ ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b87PgmKV-1686570839705)(img\image-20230525155014791.png)]
rmdir:Remove directory 移除目录
基本语法
rmdir 要删除的空目录
基本语法
touch 文件名称
ls
touch hello
ls
cd /home/atguigu
touch hello2
ls
cd -
ls
touch /home/atguigu/hello3
ls
ls /home/atguigu/
vim hello4 # vim和touch的区别是touch可以直接创建一个空的文件,但是vim不行,如果没有编辑,退出之后就还是什么都没有。
ls
vim hello4 # 但是如果我们退出 :wq! ,在退出之后就会有这个文件
ls
基本语法
cp[选项] source dest # 功能描述:复制source文件到dest
ls cp initial-setup-ks.cfg ../home/atguigu/ # 这里也可以用绝对路径 /home/atguigu/ ls /home/atguigu/ cp initial-setup-ks.cfg /home/atguigu/hello2 # 这里会问 cp:是否覆盖"/home/atguigu/hello2"? 回答y,hello2 的内容就被覆盖了。 ls /home/atguigu/ vim /home/atguigu/hello2 cp initial-setup-ks.cfg /home/atguigu/ \cp initial-setup-ks.cfg /home/atguigu/ # 用 \cp 强制覆盖不提示,因为这个是直接使用的 \cp 是原生命令 \cp initial-setup-ks.cfg /home/atguigu/hello2 type cp cp --help # cp 不是bash内置命令,要用 cp --help type ls ls \ls # \ls也是ls的原生命令,ls是别名 alias # 别名的意思 ls mkdir a cp initial-setup-ks.cfg a/ ls cp -r a/ /home/atguigu/ # 递归的复制 a 整个文件夹到 /home/atguigu/ 目录下 cd /home/atguigu/a ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M73sC7cT-1686570839705)(img\image-20230525163615068.png)]
参数说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P0O2hICd-1686570839705)(img\image-20230525163638090.png)]
经验技巧
强制覆盖不提示的方法:\cp
这个是直接使用的 \cp 是原生命令
基本语法
rm [选项] deleteFile # 功能描述:递归删除目录中所有内容
rm hello # 会问:是否删除普通空文件“hello”?
ls
type rm # rm 是 'rm -i' 的别名
rm -f hello4 # 强制删除hello4,没有交互,直接删除
ls
rm a # 无法删除"a" : 是一个目录
rm -r a # 递归的删除a以及其中的所有 且有交互,会问是否删除
ls
cd /home/atguigu/
ls
rm -rf a/ # 直接递归删除a以及其中的所有 ,没有交互
ls
rm -f ./* # 删除当前目录中的所有但是没有删除当前目录
ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D19g1hdc-1686570839705)(img\image-20230531175558648.png)]
基本语法
mv oldNameFile newNameFile # 功能描述:重命名
mv /temp/movefile /targetFolder # 功能描述:移动文件
mv initial-setup-ks.cfg /home/atguigu/ # 移动initial-setup-ks.cfg 到 /home/atguigu/ 文件夹中 ls cd /home/atguigu/ ls mv initial-setup-ks.cfg /root/ # 把initial-setup-ks.cfg 移回到 /root/ 原来的位置 cd - ls mv initial-setup-ks.cfg /home/atguigu/1.cfg # 把initial-setup-ks.cfg 移动到 /home/atguigu/ 并且重命名为 1.cfg ls ls /home/atguigu/ mv /home/atguigu/1.cfg initial-setup-ks.cfg # 把 1.cfg 移回来且恢复名字为 initial-setup-ks.cfg ls mv anaconda-ks.cfg 2.cfg # 重命名anaconda-ks.cfg 为 2.cfg ls mv 2.cfg anaconda-ks.cfg # 恢复 anaconda-ks.cfg 的文件名 ls
查看文件内容,从第一行开始显示。
基本语法
cat [选项] 要查看的文件
ls
cat initial-setup-ks.cfg # 查看initial-setup-ks.cfg 文件内容
cat -n initial-setup-ks.cfg # 显示所有行的行号查看initial-setup-ks.cfg 文件内容
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K3xUFzTK-1686570839706)(img\image-20230531181041395.png)]
经验技巧
一般查看比较小的文件,一屏幕能显示全的。
more 指令是一个基于 VI 编辑器的文本过滤器,它以全屏幕的方式按页显示文本文件的内容。more 指令中内置了若干快捷键,详见操作说明。
基本语法
more 要查看的文件
more initial-setup-ks.cfg # 分页显示initial-setup-ks.cfg 文件内容
操作说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CQB4BhtI-1686570839706)(img\image-20230531181439900.png)]
less 指令用来分屏查看文件内容,它的功能与 more 指令类似,但是比 more 指令更加强大,支持各种显示终端。less 指令在显示文件内容时,并不是一次将整个文件加载之后才显示,而是根据显示需要加载内容,对于显示大型文件具有较高的效率。
基本语法
less 要查看的文件
ls
less xzhdx.txt # less打开xzhdx.txt 动态加载
操作说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3yrQ0og-1686570839706)(img\image-20230531181633304.png)]
经验技巧
用 SecureCRT 时 [pagedown] 和 [pageup] 可能会出现无法识别的问题。
echo 输出内容到控制台
基本语法
echo [选项] [输出内容]
echo hello,world # 控制台打印hello,world
echo hello world # 控制台打印hello world
echo hello world # 控制台打印的还是hello world
echo "hello world" # 控制台打印的是hello world
echo "hello \ world" # 控制台打印hello \ world
echo "hello\nworld" # 控制台打印hello\nworld
echo -e "hello\nworld"
# 控制台打印的是:
# hello
# world
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lwm9ApHu-1686570839706)(img\image-20230531181911880.png)]
基本语法
ls -l > 文件 # 功能描述:列表的内容写入文件 a.txt 中(覆盖写)
ls -al >> 文件 # 功能描述:列表的内容追加到文件 aa.txt 的末尾
cat 文件 1 > 文件 2 # 功能描述:将文件 1 的内容覆盖到文件 2
echo “内容” >> 文件
ls
ll
ll > info # 将ll的内容写入到info文件(且新建info)中
ls
cat info
ls > info # 将ls的内容写入到info文件中,是覆盖写入
cat info
echo "hello, linux" >> info # 将hello, linux追加写入到info中
cat info
echo $ # $+名字 表示环境变量, 按Tab显示所有的环境变量
echo $USER # 显示用户名
echo $PATH # 显示环境变量
echo $HOSTNAME # 显示主机名
echo $HOSTNAME >> info # 将主机名追加写入到info中
head 用于显示文件的开头部分内容,默认情况下 head 指令显示文件的前 10 行内容。
基本语法
head 文件 # 功能描述:查看文件头10行内容
head -n 5 文件 # 功能描述:查看文件头5行内容,5可以是任意行数
head xzhdx.txt # 显示xzhdx.txt的前10行
head -n 20 xzhdx.txt # 显示xzhdx.txt的前20行内容
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jLvYL4U-1686570839706)(img\image-20230601144948275.png)]
tail 用于输出文件中尾部的内容,默认情况下 tail 指令显示文件的后 10 行内容。
基本语法
tail 文件 # 功能描述:查看文件尾部10行内容
tail -n 5 文件 # 功能描述:查看文件尾部5行内容,5可以是任意行数
tail -f 文件 # 功能描述:实时追踪该文档的所有更新
tail xzhdx.txt # 显示xzhdx.txt的尾部10行
tail -n 5 xzhdx.txt # 显示xzhdx.txt的尾部5行
tail -f info # 实时追踪info文档的更新内容
# 在另一个连接中执行(观察tail -f 中的实时更行):
echo hello >> info # 不用>,用>>因为用>是覆盖,会发生类似报错的。
echo welcomee >> info
echo 1 >> info
echo 2 >> info
echo 3 >> info
vim info # 用vim不会让tail -f 的结果发生改变,因为tail是用文件索引号追踪的,vim会改变文件的索引号(inode),tail追踪的还是之前的那个索引号。本质上不是原来的文件了。
ls -i info # 可以显示info的索引号
vim info
ls -i info
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9IlQRb3U-1686570839707)(img\image-20230601151545457.png)]
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfhvtBDp-1686570839707)(img\image-20230601145303644.png)]
软链接也称为符号链接,类似于 windows 里的快捷方式,有自己的数据块,主要存放
了链接其他文件的路径。
基本语法
ln -s [原文件或目录] [软链接名] # 功能描述:给原文件创建一个软链接
ls cd /home/atguigu/ ln -s /root/info myInfo # 当前目录创建一个软链接myInfo链接到/root/info ls -l # 前面是l就是一个链接 cd - ll cat info cd - cat myInfo cd - vim myInfo # 在myInfo中修改,之后在root目录中cat info发现已修改 cd - cat info ls mkdir folder touch folder/file ls folder/ cd - ln -s /root/folder/ /home/atguigu/myFolder # 在atguigu中创建软链接myFolder链接到/root/folder ls ll cd - cd folder/ ls pwd cd /home/atguigu/ ls cd myFolder/ ls pwd # 这个显示的是/home/atguigu/myFolder pwd -P # 用-p选项显示的是物理路径 /root/folder cd /root/ cd -P /home/atguigu/myFolder/ # cd也可以用-P换到物理路径的folder下 cd - rm myInfo # 链接文件也是文件,也是用rm删除 ls cd - ls # 发现只是把链接文件删除掉了,链接到的文件info还在,并没有被删掉 cd - ls rm -rf myFolder # -rf没有交互,且递归 ls cd - ls #发现这个也只是删除了链接文件,实际文件还在 cd - ls cd - ln -s /root/folder/ myFolder # 恢复这个链接文件 ls rm -rf myFolder/ # 发现这个是把myFolder(folder)里的文件递归删除,且没有交互,但是folder里的文件全部被删除了。 ls cd - ls cd folder/ ls cd /home/atguigu/myFolder/ ls pwd -P cd - ls cd .. ls rm -rf folder/ # 递归的删除了folder以及folder中的文件 cd /home/atguigu/myFolder/ cd /home/atguigu/ ls # 这里的myFolder标为了红的 ll # 显示myFolder的链接目标被删除的特殊标识 rm myFolder ls
经验技巧
删除软链接: rm -rf 软链接名,而不是 rm -rf 软链接名/
如果使用 rm -rf 软链接名/ 删除,会把软链接对应的真实目录下内容删掉
查询:通过 ll 就可以查看,列表属性第 1 位是 l,尾部会有位置指向
硬链接(去掉-s)
ln [原文件或目录] [软链接名]
基本语法
history # 功能描述:查看已经执行过历史命令
history # 所有历史命令
history 10 # 过去刚刚输入过的10条命令
!1156 # 显示第1156条命令并且重新调用
history -c # 清空命令
基本语法
date [OPTION]... [+FORMAT]
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5phXfTmZ-1686570839707)(img\image-20230601162342297.png)]
参数说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EiXdJUKT-1686570839707)(img\image-20230601162429307.png)]
基本语法
date # 功能描述:显示当前时间
date +%Y # 功能描述:显示当前年份
date +%m # 功能描述:显示当前月份
date +%d # 功能描述:显示当前是哪一天
date "+%Y-%m-%d %H:%M:%S" # 功能描述:显示年月日时分秒
date # 获取当前的使时间日期
date +%Y # 获取当前的年
date +%y # 当前年的后两位
date +%m # 当前的月份
date +%d # 当前的日
date +%Y-%m-%d-%H:%M:%S # 按格式输出2023-06-01-16:53:37
date +%Y-%m-%d %H:%M:%S # 用空格就不行了:date: 额外的操作数 "%H:%M:%S",要加""
date "+%Y-%m-%d %H:%M:%S" # 输出2023-06-01 16:55:34
date +%S # 获取秒
date +%s # 获取时间戳
基本语法
date -d '1 days ago' # 功能描述:显示前一天时间
date -d '-1 days ago' # 功能描述:显示明天时间
date -d "1 days ago" # 一天前的时间日期
date -d "-1 days ago" # 一天后的时间日期
date -d "-1 hours ago" # 一小时后的时间日期
基本语法
date -s 字符串时间
date -s "2017-06-19 20:52:18" # 修改当前时间为2017-06-19 20:52:18
date
date -s "2027-06-19 20:52:18" # 修改当前时间也可以是未来时间
date
ntpdate 210.72.145.44 # 修改当前是时间为ntpdate服务器时间,210.72.145.44是中国国家授时中心
基本语法
cal [选项] # 功能描述:不加选项,显示本月日历
cal # 显示当前所在月份的日历
cal -3 # 显示当前所在月及前一月和后一月的日历
cal -m # 把周一放在第一列显示日历
cal 2023 # 显示2023年的全年的日历
cal -y # 显示当前年的全年的日历
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SjuDc5ap-1686570839708)(img\image-20230601163146856.png)]
Linux是多用户多任务的分时管理系统
基本语法
useradd 用户名 # 功能描述:添加新用户
useradd -g 组名 用户名 # 功能描述:添加新用户到某个组
cd /home/
ls
useradd tony # 添加用户tony
ls
useradd -d /home/dave david # -d就是用户主目录叫dave,但是用户名字还是david,登录时还是显示的david 也可以用修改文件夹名的方式修改这个
ls
基本语法
passwd 用户名 # 功能描述:设置用户密码
passwd tony # 用户没有密码时不安全的,为tony设置密码
passwd david
基本语法
id 用户名
id tony # 查看tony这个用户存不存在
id david
id dave # 没有这个用户
cat /etc/passwd # 查看所有创建了的用户
less /etc/passwd # 分页查看所有创建了的用户
su: swith user 切换用户
基本语法
su 用户名称 # 功能描述:切换用户,只能获得用户的执行权限,不能获得环境变量
su - 用户名称 # 功能描述:切换到用户并获得该用户的环境变量及执行权限
su atguigu # 切换用户为atguigu ls cd ~ pwd su tony # 切换用户为tony ls # 这里没有权限,因为tony和atguigu是同级用户。 cd ~ pwd su root exit ls pwd ls ../tony/ exit # 返回到了root用户,root用户可以查看其他用户的目录 ls ls tony/ ls atguigu/
基本语法
whoami # 功能描述:显示自身用户名称
who am i # 功能描述:显示登录用户的用户名以及登陆时间
who am i # 显示登录用户的用户名及登录时间
whoami # 只显示用户名
su david # 切换到david用户下
whoami # 只显示用户名 david
who am i # 显示的是当前的登录用户 root pts/0 2023-06-1 19:27...
su tony
who am i
whoami
添加 atguigu 用户,并对其设置密码。
useradd atguigu
passwd atguigu
修改配置文件
vi /etc/sudoers
修改 /etc/sudoers 文件,找到下面一行(91 行),在 root 下面添加一行,如下所示:
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
atguigu ALL=(ALL) ALL
或者配置成采用 sudo 命令时,不需要输入密码
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
atguigu ALL=(ALL) NOPASSWD:ALL
修改完毕,现在可以用 atguigu 帐号登录,然后用命令 sudo ,即可获得 root 权限进行操作。
su tony
ls
sudo ls # 临时普通用户sudo的权限,但是显示: tony 不在 sudoers 文件中。此事将被报告。
exit
vim /etc/sudoers # sudoers 是root才能修改且要强制修改才能修改
su tony
ls
sudo ls
exit
基本语法
userdel 用户名 # 功能描述:删除用户但保存用户主目录
userdel -r 用户名 # 功能描述:用户和用户主目录,都删除
userdel tony # 删除tony用户
cd /home
ls
id tony
cat /etc/passwd
ls
rm -rf tony/
userdel -r david
ls
id david
cat /etc/passwd
useradd tony
useradd -d /home/dave david
ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WdSl6ins-1686570839708)(img\image-20230601175357618.png)]
基本语法
usermod -g 用户组 用户名
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOg29USx-1686570839708)(img\image-20230601180155783.png)]
每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同,
如Linux下的用户属于与它同名的用户组,这个用户组在创建用户时同时创建。
用户组的管理涉及用户组的添加、删除和修改。组的增加、删除和修改实际上就是对/etc/group文件的更新。
vim /etc/sudoers su atguigu ls sudo ls # sudoers里没有atguigu,没有给atguigu权限,但是atguigu可以看root的ls(引入组) vim /etc/sudoers # 里面确实没有atguigu sudo vim /etc/sudoers id atguigu id root id tony id david sudo cat /etc/group exit groupadd meifa # 新增meifa组 cat /etc/group # 查看组 usermod -g meifa tony # 将tony修改,将他改到meifa组中 usermod -g meifa david # 将david修改,将他改到meifa组中。 id tony # 查看该tony信息 id david groupmod -n haircut meifa # 修改组meifa的组名该为haircut id tony id david cat /etc/group groupdel tony # 删除tony组(tony组是tony用户的默认组) groupdel david cat /etc/group # wheel组中添加了atguigu用户,wheel拥有ALL权限
基本语法
groupadd 组名
基本语法
groupdel 组名
基本语法
groupmod -n 新组名 老组名
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-phlkj4mM-1686570839708)(img\image-20230601203143103.png)]
基本操作
cat /etc/group
ls ls / ls /etc ll # d开头就是目录 , c字符设别 , b块设备文件 ll /dev ls -l cd .. ll cd - ls -al cp ./anaconda-ks.cfg /home/atguigu/ cp ./initial-setup-ks.cfg /home/atguigu/ su atguigu cd ~ ls ll cat initial-setup-ks.cfg cat anaconda-ks.cfg # 权限不够 ll # 第二个字段是硬链接数
Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。在Linux中我们可以使用 ll 或者 ls -l 命令来显示一个文件的属性以及文件所属的用户和组。
从左到右的 10 个字符表示,如图 7-1 所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kEwrzeWo-1686570839708)(img\image-20230607171848165.png)]
如果没有权限,就会出现减号[ - ]而已。从左至右用0-9这些数字来表示:
0 首位表示类型
在Linux中第一个字符代表这个文件是目录、文件或链接文件等等
- 代表文件
d 代表目录
l 链接文档(link file);
第1-3位确定属主(该文件的所有者)拥有该文件的权限。—User
第4-6位确定属组(所有者的同组用户)拥有该文件的权限,—Group
第7-9位确定其他用户拥有该文件的权限 —Other
rwx 作用文件和目录的不同解释
作用到文件:
[ r ]代表可读(read): 可以读取,查看
[ w ]代表可写(write): 可以修改,但是不代表可以删除该文件,删除一个文件的前提条件是对该文件所在的目录有写权限(因为删除文件相当于修改目录),才能删除该文件.
[ x ]代表可执行(execute):可以被系统执行
作用到目录:
[ r ]代表可读(read): 可以读取,ls查看目录内容
[ w ]代表可写(write): 可以修改,目录内创建+删除+重命名目录
[ x ]代表可执行(execute):可以进入该目录
文件基本属性介绍,如图7-2所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mfTOrqB1-1686570839709)(img\image-20230607172846476.png)]
如果查看到是文件:链接数指的是硬链接个数。
如果查看的是文件夹:链接数指的是子文件夹个数。
基本语法
如图 7-3 所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cQcUccju-1686570839709)(img\image-20230607173119690.png)]
# 第一种方式变更权限
chmod [{ugoa}{+-=}{rwx}] 文件或目录
# 第二种方式变更权限
chmod [mode=421] [文件或目录]
cd /home/atguigu/ # root用户下 ls ll chmod u+x initial-setup-ks.cfg # 修改initial-setup-ks.cfg的属主的权限增加可执行 ll chmod g+w initial-setup-ks.cfg # 修改initial-setup-ks.cfg的属组的权限增加可写权限 ll chmod a=rw initial-setup-ks.cfg # 修改initial-setup-ks.cfg的所有的权限为可读可写不可执行的权限 ll chmod 777 initial-setup-ks.cfg ll chmod 644 anaconda-ks.cfg ll su atguigu cat anaconda-ks.cfg chmod -R 777 xiyou/ # -R 修改整个文件夹里面的所有文件的所有者、所属组、其他用户都具有可读可写可执行权限。 exit
经验技巧
u:所有者 g:所有组 o:其他人 a:所有人(u、g、o 的总和)
r=4 w=2 x=1 rwx=4+2+1=7
实则就是采用了二进制表示 用一个3位的二进制数表示这3个权限的拥有情况,例如:rwx对应111=7,r-x对应101=5, rw-对应110=6。
基本语法
chown [选项] [最终用户] [文件或目录] # 功能描述:改变文件或者目录的所有者
ll
chown atguigu initial-setup-ks.cfg # 修改initial-setup-ks.cfg文件属主为atguigu。
ll
chmod 700 initial-setup-ks.cfg
ll
cat initial-setup-ks.cfg
su atguigu
cat initial-setup-ks.cfg # root 和 atguigu 都可以查看,root是超级管理员,atguigu是所有者
ll
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UjMjq61w-1686570839709)(img\image-20230607173527674.png)]
基本语法
chgrp [最终用户组] [文件或目录] # 功能描述:改变文件或者目录的所属组
chgrp haircat initial-setup-ks.cfg # 不允许,因为是在改所属组,需要超级管理员权限。
exit
chgrp haircat initial-setup-ks.cfg # 修改成功
groupadd bigdata groupadd testing cat /etc/group useradd -g bigdata xiaoming id xiaoming useradd -g bigdata xiaoliang id xiaoliang useradd -g testing xiaohong useradd -g testing xiaolan id xiaohong id xiaolan cd /home/ ls su xiaoming cd ~ ls pwd vim import_code ll exit su xiaoliang cd ~ cd ../xiaoming/ # 权限不够 exit ls ll chmod g+x xiaoming/ ll su xiaoliang cd xiaoming/ ll # 权限不够 exit chmod g+r xiaoming/ ll su xiaoliang cd xiaoming ll cat import_code vim import_code vim import_code exit su xiaoming cd ~ ll chmod g+w import_code exit su xiaoliang cd xiaoming/ vim import_code ll exit su xiaohong ll cd xiaoming # 没有权限 exit chmod 755 xiaoming ll su xiaohong cd xiaoming ll cat import_code vim import_code exit usermod -g bigdata xiaolan id xiaolan su xiaolan cd xiaoming ls vim import_code cat import_code
find 指令将从指定目录向下递归地遍历其各个子目录,将满足条件的文件显示在终端。
基本语法
find [搜索范围] [选项]
ls
find -name info # 找所有的info文件
touch 公共/info
find -name info # 找所有的info文件,发现touch创建的也被find到了
find /root -name info # 找 /root 目录下的所有的info文件
find /root/公共 -name info
find /root -name "*.cfg"
find /home -user tony # 找 /home 目录下的所有tony的文件
ls
ll
ls -lh # 更加人性化的展示文件的大小
find /root -size +10M # 找 /root 目录下的size超过10M的文件
find /root -size + 2M
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FEj3ayCl-1686570839709)(img\image-20230607184829726.png)]
locate 指令利用事先建立的系统中所有文件名称及路径的 locate 数据库实现快速定位给定的文件。Locate 指令无需遍历整个文件系统,查询速度较快。为了保证查询结果的准确度,管理员必须定期更新 locate 时刻(默认一天一更)。
(find是在硬盘中找)
基本语法
locate 搜索文件
updatedb # 更新locate数据库
locate tmp # 查找所有含有tmp的文件
locate xzhdx
which ls # 查找命令
which locate
which which
whereis locate
经验技巧
由于 locate 指令基于数据库进行查询,所以第一次运行前,必须使用 updatedb 指令创建 locate 数据库。
管道符,“|”,表示将前一个命令的处理结果输出传递给后面的命令处理
基本语法
grep 选项 查找内容 源文件
ls
grep -n boot initial-setup-ks.cfg # 查找内容有boot的所有位置
ls
ls | grep .cfg
cat info
wc info # word count单词统计
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lf4hDL9O-1686570839709)(img\image-20230607185233428.png)]
基本语法
gzip 文件 # 功能描述:压缩文件,只能将文件压缩为*.gz 文件
gunzip 文件.gz # 功能描述:解压缩文件命令
ls
gzip xzhdz.txt # 压缩xzhdz.txt文件
ls
ls -lh # 以人类可读的方式显示当前目录中的文件和目录大小
gunzip xzhdx.txt.gz
ls
ls -lh
经验技巧
(1)只能压缩文件不能压缩目录
(2)不保留原来的文件
(3)同时多个文件会产生多个压缩包
基本语法
zip [选项] XXX.zip 将要压缩的内容 # 功能描述:压缩文件和目录的命令
unzip [选项] XXX.zip # 功能描述:解压缩文件
zip -r myroot.zip /root # 把/root直接压缩为myroot.zip,压缩+重命名
ls
ls -lh
unzip -d /tmp myroot.zip # 解压myroot.zip到/tmp目录下
cd /tmp
ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ohMAEzBx-1686570839710)(img\image-20230607185833928.png)]
经验技巧
zip 压缩命令在windows/linux都通用,可以压缩目录且保留源文件。
基本语法
tar [选项] XXX.tar.gz 将要打包进去的内容 # 功能描述:打包目录,压缩后的文件格式.tar.gz
cd ~
ls
tar -zcvf temp.tar.gz initial-setup-ks.cfg xzhdx.txt info 公共/ # 将initial-setup-ks.cfg xzhdx.txt info 公共/打包压缩为temp.tar.gz且显示详细信息
ls
ls -lh
tar -zxvf temp.tar.gz -C /tmp # 将temp.tar.gz解压到/tmp目录下
cd /tmp/
ls
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ztZCCEed-1686570839710)(img\image-20230607190058399.png)]
du: disk usage 磁盘占用情况
基本语法
du 目录/文件 # 功能描述:显示目录下每个子目录的磁盘使用情况
ls
ll
yum install tree # 下载tree
tree ./ # 树结构查看 ./ 目录的所有
ls -lh
ls -lh /
du # 把所有目录,所有文件夹下的,隐藏文件下的全部显示占据空间大小。
du -ah # 把所有目录显示占据空间大小且用人类易于看懂的方式显示
du -ach # 用的-c,但是发现没有简化多少
du -sh # 用-s只统计当前的总和
du --max-depth=1 -ah # 显示最大深度为1, 就是只显示一层,且显示占据空间大小用人类易于看懂的方式显示。
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8oFWwC8h-1686570839710)(img\image-20230607190320202.png)]
df: disk free 空余磁盘
基本语法
df 选项 # 功能描述:列出文件系统的整体磁盘使用量,检查文件系统的磁盘空间占用情况
du -sh
du -sh / # 根目录的大小,只是文件占用的,不是磁盘的空间
df -h # 列出文件系统的整体磁盘使用量,检查文件系统的磁盘空间占用情况,用人易于看懂的方式显示
free -h # 当前内存的使用情况
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lxElFUCN-1686570839710)(img\image-20230607190454581.png)]
基本语法
lsblk # 功能描述:查看设备挂载情况 ls block
lsblk # 查看设备挂载情况
ls /dev/ | grep sr0
ll /dev/ | grep sr0
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnyHAS5l-1686570839710)(img\image-20230607190634276.png)]
对于Linux用户来讲,不论有几个分区,分别分给哪一个目录使用,它总归就是一个根目录、一个独立且唯一的文件结构。
Linux中每个分区都是用来组成整个文件系统的一部分,它在用一种叫做“挂载”的处理方法,它整个文件系统中包含了一整套的文件和目录,并将一个分区和一个目录联系起来,要载入的那个分区将使它的存储空间在这个目录下获得。
挂载前准备(必须要有光盘或者已经连接镜像文件),如图 7-5, 7-6所示
基本语法
mount [-t vfstype] [-o options] device dir # 功能描述:挂载设备
umount 设备文件名或挂载点 # 功能描述:卸载设备
lsblk # 查看CentOS 7 x86_64 的挂载点
ls /run/media/root/CentOS\ 7\ x86_64/
lsblk # 弹出光驱后就没有这个了
ls /run/media/root/CentOS\ 7\ x86_64/ # 无法访问,没有那个文件或目录
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom # 找不到媒体,要重新登录,连接上光盘
lsblk
mount /dev/cdrom /mnt/cdrom # 写保护,将以只读方式挂载
lsblk
ls /mnt/cdrom/
umount /dev/cdrom
lsblk
ls /mnt/cdrom/
vim /etc/fstab # fstab 设置开机自动挂载 , UUID写/dev/cdrom,后面挂载点写 /mnt/cdrom ,文件类型iso9660,配置默认配置defaults ,后面0 0
参数说明
设置开机自动挂载
vi /etc/fstab
添加红框中内容,保存退出。
如图7-7所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mYJhKw3B-1686570839711)(img\image-20230607191304668.png)]
基本语法
fdisk -l # 功能描述:查看磁盘分区详情
fdisk 硬盘设备名 # 功能描述:对新增硬盘进行分区操作
fdisk -l # 查看磁盘分区情况 fdisk -l # 新添加的硬盘没有显示 lsblk -l # 新添加的同样也没有被查询到,需要重启 reboot lsblk # 查询到了sdb磁盘 fdisk -l fdisk /dev/sdb # m p n{p(Partition type) 分区号(默认) 起始扇区(默认) size(默认即是最大的扇区)} p w fdisk -l # 发现添加了新的分区 lsblk # 也可以查看到 lsblk -f # 没有文件信息,UUID和挂载点 mkfs -t xfs /dev/sdb1 # 对它作一个格式化 lsblk -f # 有UUID信息,没有挂载点,进行挂载 mount /dev/sdb1 /home/atguigu/ # 将sdb挂载到atguigu下给atguigu用户使用 lsblk -f df -h ls ll ll -h cp myroot.zip /home/atguigu/ df -h # sdb1的空间被占用了 umount /home/atguigu # 卸载 df -h # 没有sdb1 ll /home/atguigu/ # 只有之前的两个配置文件,没有刚刚存放的myroot.zip了
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9bujFOTd-1686570839711)(img\image-20230607191503131.png)]
经验技巧
该命令必须在 root 用户下才能使用
功能说明
Linux 分区
Device:分区序列
Boot:引导
Start:从X磁柱开始
End:到Y磁柱结束
Blocks:容量
Id:分区类型ID
System:分区类型
分区操作按键说明
m:显示命令列表
p:显示当前磁盘分区
n:新增分区
w:写入分区信息并退出
q:不保存分区信息直接退出
进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源。
ps:process status 进程状态
基本语法
ps aux | grep xxx # 功能描述:查看系统中所有进程
ps -ef | grep xxx # 功能描述:可以查看子父进程之间的关系
ls /usr/lib/systemd/system
ls /usr/lib/systemd/system | grep d.service
ps # 只显示当前用户和当前控制台的进程
ps aux
ps aux | less
ps -ef
ps -ef | less # PPID是父进程的ID
ps aux | less
ps -ef | less # PPID 0是系统进程idu
ps -ef | grep sshd # 查看sshd相关的进程 ,和远程登录相关的
systemctl status sshd # 查看sshd进程的状态信息
ps -ef | grep sshd # 再打开一个xshell的远程连接后,查看远程登录相关的进程,发现多了一个sshd: root@pts/2
ps -ef | grep sshd # 再打开一个xshell的用atguigu用户的身份登录的远程连接,查看远程登录相关的进程,发现多了两个sshd的进程 sshd: atguigu... atguigu[priv]是权限分离
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJaovwYw-1686570839711)(img\image-20230609092335444.png)]
功能说明
ps aux 显示信息说明
USER:该进程是由哪个用户产生的
PID:进程的 ID 号
%CPU:该进程占用 CPU 资源的百分比,占用越高,进程越耗费资源;
%MEM:该进程占用物理内存的百分比,占用越高,进程越耗费资源;
VSZ:该进程占用虚拟内存的大小,单位 KB;
RSS:该进程占用实际物理内存的大小,单位 KB;
TTY:该进程是在哪个终端中运行的。对于 CentOS 来说,tty1 是图形化终端,tty2-tty6 是本地的字符界面终端。pts/0-255 代表虚拟终端。
STAT:进程状态。常见的状态有:R:运行状态、S:睡眠状态、T:暂停状态、Z:僵尸状态、s:包含子进程、l:多线程、+:前台显示、< : 表示当前进程优先级很高、N : 表示当前进程优先级比较低
START:该进程的启动时间
TIME:该进程占用 CPU 的运算时间,注意不是系统时间
COMMAND:产生此进程的命令名
ps -ef 显示信息说明
UID:用户 ID
PID:进程 ID
PPID:父进程 ID
C:CPU 用于计算执行优先级的因子。数值越大,表明进程是 CPU 密集型运算,执行优先级会降低;数值越小,表明进程是 I/O 密集型运算,执行优先级会提高
STIME:进程启动的时间
TTY:完整的终端名称
TIME:CPU 时间
CMD:启动进程所用的命令和参数
经验技巧
如果想查看进程的 CPU 占用率和内存占用率,可以使用 aux;
如果想查看进程的父进程 ID 可以使用 ef;
基本语法
kill [选项] 进程号(PID) # 功能描述:通过进程号杀死进程
killall 进程名称 # 功能描述:通过进程名称杀死进程,也支持通配符,这在系统因负载过大而变得很慢时很有用
kill 3535 # 终止进程3535 ps -ef | grep sshd kill 3481 ps -ef | grep sshd # 再重新远程登录一个root后再,ps kill 3195 # kill掉自己 kill 1130 # kill掉了守护进程 ps -ef | grep sshd ls # 当前登录的还是可以运行的,但是如果要打开一个新的连接,是打不开的,因为sshd服务已经关闭 systemctl status sshd systemctl start sshd # 启动sshd后,再打开一个新的连接就可以打开了 ps -ef | grep 3746 # 查看3746相关进程,3746是sshd的父进程,3746就是终端界面进程bash ps -ef | grep bash kill 3273 # kill当前打开的的终端界面 ps -ef | grep bash # 发现没有kill掉,因为当前终端在使用,在运行,系统不认同kill这条指令 kill -l # 查看当前系统的信号值 kill -9 3273 # 强制关掉这个终端页面 ps -ef | grep bash # 确实被关掉了 kill -9 3818 ps -ef | grep bash kill 3746 kill -9 3746 ps -ef | grep sshd killall sshd
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fnj7o3Rr-1686570839711)(img\image-20230609093352994.png)]
基本语法
pstree [选项]
yum install pstree # 如果第一次使用没有安装pstree,执行这个安装一下
pstree | less # 分页显示pstree
pstree -p | less # 分页显示进程的PID
pstree -u | less # 分页显示用户相关的进程信息
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5f05PCG-1686570839711)(img\image-20230609093650905.png)]
基本命令
top [选项]
top # 可以按 P(shift + p)、M(shift + m)、N(shift + n) 对查询出的进程结果进行排序。
top -d
top -i
top -p 4910
top -i
top -p 2655
top -d 1 # 想要监控某个固定用户,可以按u,提示Which user (blank for all) ,可以输一个atguigu看 ; 可以按k,提示PID to signal/kill [default pid = 4936] ,比如输入4950,就会kill这个进程,然后它还问要求输入给它发送的信号Send pid 4950 signal [15/sigterm](就是之前kill -l 能够发送的所有信号), 这里可以发信号名称也可以发数字这里输入9发送的信号就是9;
选项说明
操作说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PERb3ifo-1686570839712)(img\image-20230609094043345.png)]
查询结果字段解释
第一行信息为任务队列信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBjCQ2XT-1686570839712)(img\image-20230609094151305.png)]
第二行为进程信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKoCdXj7-1686570839712)(img\image-20230609094720025.png)]
第三行为 CPU 信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1XK7N13-1686570839712)(img\image-20230609094847204.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FZjWuZ85-1686570839712)(img\image-20230609094958158.png)]
第四行为物理内存信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JAegnQcf-1686570839713)(img\image-20230609095042133.png)]
第五行为交换分区(swap)信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PoKXDAaS-1686570839713)(img\image-20230609095206615.png)]
执行上述命令后,可以按 P(shift + p)、M(shift + m)、N(shift + n) 对查询出的进程结果进行排序。
案例实操
top -d 1
top -i
top -p 2575
基本语法
netstat -anp | grep 进程号 # 功能描述:查看该进程网络信息
netstat –nlp | grep 端口号 # 功能描述:查看网络端口号占用情况
ifconfig # 查看当前所有的网络连接
ping 192.168.111.1
netstat -anp # 查看该进程网络信息
netstat -anp | less # 查看该进程网络信息进行分页展示
netstat -anp | less # 这个也是进程的快照,新建atguigu用户的连接,然后再netstat,可以看到atguigu就存在了。
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vYkDzxYK-1686570839713)(img\image-20230609095502137.png)]
重新启动 crond 服务
systemctl restart crond # crond是crontab的守护进程
systemctl status crond # 看到crond进程的是开启的
基本语法
crontab [选项]
crontab -l # crontab使用的话必须后面跟上一些选项,-l列举当前的所有定时任务, no crontab for root ,发现没有
crontab -e # 写入 */1 * * * * echo "hello, world" >> /root/hello
ls
ls
ls
ls
cat hello
tail -f hello
crontab -l
crontab -r
crontab -l
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YEYLSLP2-1686570839713)(img\image-20230609101738626.png)]
参数说明
crontab -e
进入 crontab 编辑界面。会打开 vim 编辑你的工作。
* * * * * 执行的任务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osqn7ljF-1686570839713)(img\image-20230609104139545.png)]
特殊符号
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0eOvLQR-1686570839714)(img\image-20230609104402045.png)]
特定时间执行命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q52feBPZ-1686570839714)(img\image-20230609104450469.png)]
案例实操
每隔 1 分钟,向 /root/bailongma.txt 文件中添加一个 11 的数字
*/1 * * * * /bin/echo ”11” >> /root/bailongma.txt
RPM(RedHat Package Manager),RedHat软件包管理工具,类似windows里面的setup.exe是Linux这系列操作系统里面的打包安装工具,它虽然是RedHat的标志,但理念是通用的。
RPM包的名称格式
Apache-1.3.23-11.i386.rpm
基本语法
rpm -qa # 功能描述:查询所安装的所有 rpm 软件包
rpm -qa # 查询所安装的所有 rpm 软件包
rpm -qa | grep firefox # 查询firefox的软件包
rpm -qi firefox # -qi information ,就是查询展示详细信息
经验技巧
由于软件包比较多,一般都会采取过滤。rpm -qa | grep rpm软件包
基本语法
rpm -e RPM软件包
rpm -e --nodeps 软件包
rpm -e firefox # 卸载firefox
rpm -qi firefox # 未安装软件包 firefox
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g5sqOrR4-1686570839714)(img\image-20230609110231639.png)]
基本语法
rpm -ivh RPM 包全名
lsblk
cd /run/media/root/CentOS\ 7\ x86_64/
ls
cd Packages/
ls
ls | grep firefox
rpm -ivh firefox-68.10.0-1.el7.centos.x86_64.rpm
rpm -qi firefox
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FunYZ5us-1686570839714)(img\image-20230609110529727.png)]
YUM(全称为 Yellow dog Updater, Modified)是一个在 Fedora 和 RedHat 以及 CentOS中的 Shell 前端软件包管理器。基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装,如图 8-1 所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ui2wRAvT-1686570839714)(img\image-20230609110826772.png)]
基本语法
yum [选项] [参数]
yum list
yum list | grep firefox
yum remove firefox
yum list | grep firefox
rpm -q firefox
yum -y install firefox
yum list | grep firefox
rpm -q firefox
选项说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djlai5ku-1686570839714)(img\image-20230609162022614.png)]
参数说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGGYKU04-1686570839715)(img\image-20230609162113771.png)]
默认的系统 YUM 源,需要连接国外 apache 网站,网速比较慢,可以修改关联的网络YUM 源为国内镜像的网站,比如网易 163,aliyun 等
安装 wget, wget 用来从指定的 URL 下载文件
yum install wget
在/etc/yum.repos.d/目录下,备份默认的 repos 文件,
pwd /etc/yum.repos.d
cp CentOS-Base.repo CentOS-Base .repo.backup
下载网易 163 或者是 aliyun 的 repos 文件,任选其一,如图 8-2
wget http://mirrors.aliyun.com/repo/Centos-7.repo //阿里云
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo //网易 163
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UPpWfeX-1686570839715)(img\01.png)]
使用下载好的 repos 文件替换默认的 repos 文件
例如:用 CentOS7-Base-163.repo 替换 CentOS-Base.repo
mv CentOS7-Base-163.repo CentOS-Base.repo
清理旧缓存数据,缓存新数据
yum clean all
yum makecache
yum makecache 就是把服务器的包信息下载到本地电脑缓存起来
测试
yum list | grep firefox
yum -y install firefox
less /etc/yum.repos.d/CentOS-Base.repo
从现有虚拟机(关机状态)克隆出新虚拟机,右键选择管理=>克隆,如图 9-1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CJ0BeAFI-1686570839715)(img\02.png)]
点击下一步,如图 9-2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5i6431d-1686570839715)(img\image-20230610131452769.png)]
选择虚拟机中的当前状态,如图 9-3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jamTtDWs-1686570839715)(img\image-20230610131548651.png)]
选择创建完整克隆,如图 9-4
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2IPTsSXA-1686570839716)(img\image-20230610131630054.png)]
设置虚拟机名称及存储位置,如图 9-5
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kRHrfOtA-1686570839716)(img\03.png)]
等等等……等待克隆完成,如图 9-6,9-7
注意: 使用 root 用户。
修改 vim /etc/sysconfig/network-scripts/ifcfg-ens33 ,修改 IP 地址,如图 9-8
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q9SAHFFl-1686570839716)(img\image-20230610134745601.png)]
修改/etc/hostname,修改主机名,如图9-9
ifconfig # 因为是克隆的所以主机名,域什么的都一样 vim /etc/sysconfig/network-scripts/ifcfg-ens33 # 修改克隆机的配置,进去之后将IP地址IPADDR=192.168.126.100改为IPADDR=192.168.126.101 systemctl status network # 查看网络服务配置 systemctl status NetworkManager # 其实CentOS 7 中是NetworkManager systemctl stop network # 为了保险起见 systemctl restart NetworkManager # 重启网络服务 ifconfig ping 192.168.111.1 # ping主机 ping www.baidu.com # ping 外网 cat /etc/hostname hostnamectl set-hostname hadoop101 cat /etc/hostname hostname # 用xshell连接上克隆的虚拟机 ls touch hello2 # 新建一个文件尝试一下 ls
快照: 可以保存当前虚拟机的状态,一般在作一些危险的操作之前会拍一个快照,万一虚拟机崩了可以用快照恢复。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IRjlv86i-1686570839716)(img\shell01.png)]
Linux 提供的 Shell 解析器有
cat /etc/shells # 查看所有的shell解析器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UzGDjyh0-1686570839716)(img\image-20230610162929567.png)]
bash 和 sh 的关系
ls -l /bin/ | grep sh
ls -l /bin/ | grep bash
Centos 默认的解析器是 bash
echo $SHELL # .sh就是shell脚本文件的后缀名
less /bin/unix-lpr.sh # 先看看写好的,格式; 第一行#!/bin/sh 这个指的是默认选择的命令行的解析器是sh,sh链接指向了bash
脚本格式
脚本以==#!/bin/bash== 开头(指定解析器)
第一个 Shell 脚本:helloworld.sh
需求:创建一个Shell脚本,输出helloworld
ls
mkdir scripts
cd scripts/
touch hello.sh
vim hello.sh # 进入之后先第一行写 #!/bin/bash ,第二行写 echo "hello, world"
ls
脚本的常用执行方式
第一种(实际运用当中不用这种方式):采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x 权限)
sh+脚本的相对路径
sh+脚本的绝对路径
bash+脚本的相对路径
bash hello.sh # 因为这里已经在scripts目录下了,所以可以直接hello.sh
cd ~
bash scripts/hello.sh # 用相对路径
bash /root/scripts/hello.sh # 用绝对路径
sh scripts/hello.sh
第二种(实际中最常用的):采用输入脚本的绝对路径或相对路径执行脚本==(必须具有可执行权限+x)==【前面的执行方式是当作bash命令的参数传入的,所以不需要x权限;但是这种方式是在当前bash界面解析执行,需要x权限】
执行脚本
相对路径
绝对路径
/root/scripts/hello.sh # 绝对路径,但提示权限不够
ll scripts # 发现只有可读权限,没有可执行权限
chmod +x scripts/hello.sh
ll scripts/ # hello.sh 文件变为绿色,就是可执行文件
/root/scripts/hello.sh # 绝对路径执行成功
scripts/hello.sh # 相对路径执行成功
cd scripts/ # 但是要注意切换到scripts目录下时
ls
hello.sh # bash: hello.sh: 未找到命令... ,这样用相对路径执行Shell脚本时,系统把它当作时命令执行了
./hello.sh # 这样就正确执行了
注意:第一种执行方法,本质是 bash 解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。
[了解] 第三种:在脚本的路径前加上“.”或者 source
有以下脚本
cat /root/scripts/hello.sh
#!/bin/bash
# echo "hello, world"
分别使用 sh,bash,./ 和 . 的方式来执行,结果如下:
source hello.sh # 当前在scripts目录下
source /root/scripts/hello.sh
. hello.sh # 这里的" . "是命令, ./hello.sh中的" . "表示当前目录
type source # source 是 shell 内嵌
原因:
前两种方式都是在当前 shell 中打开一个子 shell 来执行脚本内容,当脚本内容结束,则子 shell 关闭,回到父 shell 中。
第三种,也就是使用在脚本路径前加“.”或者 source 的方式,可以使脚本内容在当前shell 里执行,而无需打开子 shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需要 source 一下的原因。
开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子 shell 中设置的当前变量,父 shell 是不可见的。
ps -f
bash # bash命令打开子shell
ps -f # 多了一个bash
./hello.sh
exit # 推出的是子shell
常用系统变量
$HOME(当前的主目录)、$PWD(当前的工作目录)、$SHELL(当前使用的shell解析器)、$USER(当前的用户) 等
案例实操
(1)查看系统变量的值
echo $HOME # 当前主目录
env # 显示系统中已存在的环境变量,以及在定义的环境中执行指令
env | less
printenv | less # 和env几乎是一样的
printenv $USER # 再printenv的时候就不用加$符了,直接USER就可以了
printenv USER # root
echo $USER # 一般情况下,打印USER都要$,把USER当变量使用,只是printenv比较特殊,是专门打印env的
ls $HOME
bash # 打开一个子shell
ps -f
echo $HOME # 父shell的变量,子shell也可以看
exit
(2)显示当前 Shell 中所有变量:set
set # 所有变量
set | less
基本语法
定义变量:变量名=变量值,# 注意,=号前后不能有空格
撤销变量:unset 变量名
声明静态变量:readonly 变量,注意:不能 unset
a=2 # 定义a变量 echo $a # 查看a变量的值 echo $my_var # 查看my_var,my_var未定义,所以显示空 my_var=hello # 赋值my_var为hello echo $my_var my_var=Hello # 改变my_var为Hello echo $my_var my_var = Hello # bash: my_var: 未找到命令... ,my_var变量赋值时=两边不能有空格,如果有,系统会认为my_var是个命令。 my_var=hello, world # 所赋的值中间有空格,也会有 未找到命令 my_var="hello, world" # 用"“把字符串引起来 echo $my_var my_var='Hello, world' # 当然用""还是''没有关系,都是可以的 echo $my_var env | grep my_var # 系统中找不到 set | grep my_var # 所有变量可以找到,是个局部变量 bash # 子shell ps -f echo $my_var # 是空,说明刚刚的my_var确实是局部变量,局部变量 exit echo $my_var export my_var # 将my_var升级成全局变量 echo $my_var # 全局变量,当前shell肯定可以 ps -f bash ps -f # 查看ps -f命令是在子shell中执行的 echo $my_var # 子shell可以查看my_var变量 my_var=”hello, Linux" # 在子shell中更改my_var变量 echo $my_var # 在子shell中确实更改了 exit ps -f #查看是退出到了父shell echo $my_var # 发现父shell中的变量不变,还是Hello, world;子shell中的变量改变只作用在子shell的范围内,不会影响父shell中的变量的值。 bash ps -f my_var="hello, Linux" export my_var # 在子shell中把变量值改变后,再将他升级成全局变量 echo $my_var exit echo $my_var # 再父shell中依然没有改变;用了这么多子进程,就是为了看在脚本中的变量,在脚本中哪些变量可以访问到 vim hello.sh # 添加一句 echo $my_var source hello.sh # source可以执行出 ./hello.sh # 也可以执行出 echo $new_var # 没有new_var,为空 new_var="hello, linux" echo $new_var vim hello.sh # 新增一行 echo $new_var ./hello.sh # 前两行输出了,但是最后一样new_var没有输出,因为是局部变量,在子shell中访问不到; . hello.sh # 想要让他输出,第一种方式就是用source或者是 . ,执行它 export new_var # 想要让他输出,第二种方式就是export,将这个变量改为全局变量 ./hello.sh echo $a # 是2 a=1+5 echo $a # 输出的是 1+5 ,不是6,这里是没有类型的,如果想要得到结果,就需要用到后面的运算符 a=$((1+5)) # 使用运算符 echo $a # 输出的是6 a=$[5+9] # 使用运算符 echo $a # 输出的是14 readonly b=5 # 定义只读变量 b=10 # 报错 -bash: b: 只读变量 echo $b set | less unset a # 撤销掉不用的变量 set | less # 所有变量里就找不到a了 unset b # unset b同样也会报错 -bash: unset: b: 无法反设定: 只读 variable
变量定义规则
变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
等号两侧不能有空格
在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算。
变量的值如果有空格,需要使用双引号或单引号括起来。
案例实操
定义变量 A
A=5
echo $A # 5
给变量 A 重新赋值
A=8
echo $A # 8
撤销变量 A
unset A
echo $A
声明静态的变量 B=2,不能 unset
readonly B=2
echo $B # 2
B=9 # -bash: B: readonly variable
在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算
C=1+2
echo $C # 1+2
变量的值如果有空格,需要使用双引号或单引号括起来
D=I love banzhang # -bash: world: command not found
D="I love banzhang"
echo $D # I love banzhang
可把变量提升为全局环境变量,可供其他 Shell 程序使用
export 变量名
vim helloworld.sh
在 helloworld.sh 文件中增加 echo $B
#!/bin/bash
echo "helloworld"
echo $B
./helloworld.sh
# helloworld
#
发现并没有打印输出变量 B 的值。
export B
./helloworld.sh
# helloworld
# 2
全局环境变量
- 系统环境变量基本使用全大写字母,区分普通环境变量
- 全局环境变量作用范围:所有会话和所有生成的子shell
- 查看环境变量使用env或者printenv
局部环境变量
- 作用范围:定义在它们的进程中可见
- 目前没有一个命令可以查看局部环境变量
- set命令:全局变量、局部变量、用户定义变量,按照字母顺序对结果排序
ls
cd scripts/
hello.sh # 未找到命令...
cp hello.sh /bin/ # 所有系统命令都放在了/bin/目录下,所以把hello.sh也放到/bin/下
hello.sh # 成功显示,后面两行空的是因为那两个变量unset之前掉了
rm -f /bin/hello.sh # 但是/bin/是放系统命令的,这里放hello.sh不好
echo $PATH # 其实如果想要改的话,改PATH也可以,在PATH的后面直接用冒号(:)隔开,在后面添加上/bin/hello.sh 就可以
基本语法
$n # 功能描述:n 为数字,$0 代表该脚本名称,$1-$9 代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}
vim hello.sh # 删掉后两行,增加echo "hello, $1"
./hello.sh # 输出 hello, world hello,
./hello.sh xiaoming # 输出 hello, world hello, xiaoming
./hello.sh xiaoliang # 输出 hello, world hello, xiaoliang
vim parameter.sh
#!/bin/bash
echo '===================$n===================' # 这里用单引号是因为怕双引号会认为$n是个参数
echo script name: $0
echo 1st parameter: $1
echo 2nd parameter: $2
ll
chmod +x parameter.sh # 添加可执行权限
./parameter.sh abc def
# ===================$n===================
# script name: ./parameter.sh
# 1st parameter: abc
# 2nd parameter: def
/root/scripts/parameter.sh abc def
# ===================$n===================
# script name: /root/scripts/parameter.sh #这里不想要这么长,可以使用basename命令
# 1st parameter: abc
# 2nd parameter: def
基本语法
$# # 功能描述:获取所有输入 ==参数个数== ,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性。
vim parameter.sh
#!/bin/bash
echo '===================$n===================' # 这里用单引号是因为怕双引号会认为$n是个参数
echo script name: $0
echo 1st parameter: $1
echo 2nd parameter: $2
echo '===================$#==================='
echo parameter numbers: $#
./parameter.sh
# ===================$n===================
# script name: ./parameter.sh
# 1st parameter:
# 2nd parameter:
# ===================$#===================
# parameter numbers: 0
/root/scripts/parameter.sh abc def
# ===================$n===================
# script name: /root/scripts/parameter.sh
# 1st parameter: abc
# 2nd parameter: def
# ===================$#===================
# parameter numbers: 2
基本语法
$* # 功能描述:这个变量代表命令行中所有的参数,== $*把所有的参数看成一个整体 ==
$@ # 功能描述:这个变量也代表命令行中所有的参数,不过 == $@把每个参数区分对待 ==
vim parameter.sh
#!/bin/bash
echo '===================$n===================' # 这里用单引号是因为怕双引号会认为$n是个参数
echo script name: $0
echo 1st parameter: $1
echo 2nd parameter: $2
echo '===================$#==================='
echo parameter numbers: $#
echo '===================$*==================='
echo $*
echo '===================$@==================='
echo $@
/root/scripts/parameter.sh abc def
# ===================$n===================
# script name: /root/scripts/parameter.sh
# 1st parameter: abc
# 2nd parameter: def
# ===================$#===================
# parameter numbers: 2
# ===================$*===================
# abc def
# ===================$@===================
# abc def
基本语法
$? # 功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。
echo $? # 因为之前执行过脚本,之前都是正常执行的
parameter.sh # 未找到命令...
echo $? # 127
基本语法
"$((运算式))" 或 "$[运算式]"
a= 1 + 2 # 未找到命令 a=1+2 echo $a # 1+2 1+2 # 未找到命令 expr 1+2 # 1+2 不对,还是1+2 expr 1 + 2 # 3 得到得数了,expr像是命令,1 + 2是3个参数 expr 5 - 2 # 3 expr 5 * 2 # expr: 语法错误 可能是*造成的 expr 5 \* 2 # 10 使用\转译字符 echo $[5 * 2] # 为了简化引入了运算符#(()) 和#[] echo $[5*2] # 10 中间的空格可有可无 echo $((5*2)) # 10 a=$[6+8] echo $a # 14 a=expr 5 \* 2 # 未找到命令... a="expr 5 \* 2" # 会不会是需要加"" echo $a # expr 5 \* 2 a=$(expr 5 \* 2) # 这里用了命令替换,就是用$()括号里写替换的内容,和运算符的$(())有些像 echo $a # 10 a=`expr 5 \* 2` # 反引号`也是命令替换 echo $a # 10 a=`expr 5 \* 4` echo $a # 20 s=$[(2+3)*4] # 计算(2+3)*4 echo $s # 20 cd scripts/ # 进入scripts目录下创建add.sh vim add.sh # 在脚本中用加法
#!/bin/bash
sum=$[$1 + $2]
echo sum=$sum
chmod +x add.sh # 添加执行权限
./add.sh 25 89 # sum=114
基本语法
test condition
[condition] # 注意 condition 前后要有空格
# 注意:条件非空即为 true,[ atguigu ]返回 true,[ ] 返回 false。
a=hello echo $a # hello test $a = hello # 测试,a的值是否等于hello,test是函数,会返回一个值,通过$?判断是否返回正确 echo $? # 0 返回0就是true,和其他的语言颠倒 test $a = Hello echo $? # 1 返回1就是false,返回错误 a=Hello test $a = Hello echo $? # 0 [ $a = Hello ] # test太麻烦了,就有了[ ],[]里一定左右都要有空格 echo $? # 0 [ $a = hello ] # 判断a的值是不是hello echo $? # 1 返回1 false [ $a=hello ] # $a=hello中间也一定要有空格,如果没有,会认为这是一个参数 echo $? # 0 [ afadafafafaf ] # 在[]中随便打一些内容 echo $? # 0 [ ] # [ ]中间是空的 echo $? # 1 [ $a = hello ] echo $? # 1 [ $a = Hello ] echo $? # 0 [ $a != Hello ] # !=试一下 echo $? # 1 [ $a != hello ] echo $? # 0 [ 2 = 8 ] # 试数字可以吗 echo $? # 1 [ 2 = 2 ] echo $? # 0 [ 2 < 8 ] # 没有那个文件或目录,在shell中 < > 被认为是输入输出 [ 2 -lt 8 ] # -lt 表示小于 echo $? # 0 [ 2 -gt 8 ] echo $? # 1 ls touch test ls ll # test没有x权限 [ -r hello.sh ] # 看hello.sh有没有可读的权限 echo $? # 0 [ -w hello.sh ] # 看hello.sh有没有可写的权限 echo $? # 0 [ -r test ] echo $? # 0 [ -x test ] echo $? # 1 没有可执行的权限 [ -e /home/atguigu/info ] # 看该文件是否存在 echo $? # 1 ls /home/atguigu/ # 确实没有 [ -e /home/atguigu/initial-setup-ks.cfg ] ls /home/atguigu/ # 是有initial-setup-ks.cfg echo $? # 0 [ -f add.sh ] # 看add.sh文件存在并且是一个常规的文件(file) echo $? # 0 [ -d add.sh ] # 看add.sh是不是一个目录 echo $? # 1 [ -d /home/atguigu ] echo $? # 0 a=15 [ $a -lt 20 ] && echo "$a < 20" || echo "$a > 20" # 15 < 20 多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)【可以使用得类似三元运算符?:一样】 a=27 [ $a -lt 20 ] && echo "$a < 20" || echo "$a > 20" # 15 > 20 [ atguigu ] && echo OK || echo notOK # OK [ ]中间有东西就是0 [ ] && echo OK || echo notOK # notOK [ ]中间是空就是1
常用判断条件
两个整数之间比较
-eq等于(equal) -ne不等于(not equal)
-lt小于(less than) -le小于等于(less equal)
-gt大于(greater than) -ge大于等于(greater equal)
# 注:如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等。
按照文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
按照文件类型进行判断
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
案例实操
23 是否大于等于 22
helloworld.sh 是否具有写权限
/home/atguigu/cls.txt 目录中的文件是否存在
多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)【可以使用得类似三元运算符?:一样】
基本语法
单分支
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
①[ 条件判断式 ],中括号和条件判断式之间必须有空格
②if 后要有空格
cd /home/atguigu/; ls -l # ;把两个命令隔开,和管道|不同,管道是执行的结果通过管道传递给后面的命令
cd ~
a=25
if [ $a -gt 18 ]; then echo OK; fi # 单分支
a=15
if [ $a -gt 18 ]; then echo OK; fi
cd scripts/ # 还是到scripts/目录下写脚本
vim if_test.sh
#!/bin/bash
if [ $1 = atguigu ]
then
echo "welcome, atguigu"
fi
chmod +x if_test.sh
./if_test.sh # 期待一元表达式 传入空会报错
vim if_test.sh
#!/bin/bash
#if [ $1 = atguigu ] # 如果没有传入参数的话,是空,会报错,所以在实际通常写成[ "$1"x = "atguigu"x ]
if [ "$1"x = "atguigu"x ]
then
echo "welcome, atguigu"
fi
./if_test.sh
./if_test.sh xiaoming
./if_test.sh atguigu # welcome, atguigu
if [ $a -gt 18 ] && [ $a -lt 35 ]; then echo OK; fi
echo $a # 15 a的值是15,当然不会OK
a=25
if [ $a -gt 18 ] && [ $a -lt 35 ]; then echo OK; fi # OK
a=36
if [ $a -gt 18 ] && [ $a -lt 35 ]; then echo OK; fi # 没有输出OK
if [ $a -gt 18 && $a -lt 35 ]; then echo OK; fi # 报错,直接放在[]中不行
if [ $a -gt 18 -a $a -lt 35 ]; then echo OK; fi # 这样才行,-a就是add 逻辑与;-o就是or 逻辑或; 这里没有输出OK是因为a是36
a=20
if [ $a -gt 18 ] && [ $a -lt 35 ]; then echo OK; fi # OK
vim if_test.sh
#!/bin/bash
#if [ $1 = atguigu ] # 如果没有传入参数的话,是空,会报错,所以在实际通常写成[ "$1"x = "atguigu"x ]
if [ "$1"x = "atguigu"x ]
then
echo "welcome, atguigu"
fi
# 输入第二个参数,表示年龄,判断属于哪个年龄段
if [ $2 -lt 18 ]
then
echo "未成年人”
else
echo "成年人"
fi
./if_test.sh atguigu 15
# welcome, atguigu
# 未成年人
./if_test.sh atguigu 25
# welcome, atguigu
# 成年人
vim if_test.sh
#!/bin/bash #if [ $1 = atguigu ] # 如果没有传入参数的话,是空,会报错,所以在实际通常写成[ "$1"x = "atguigu"x ] if [ "$1"x = "atguigu"x ] then echo "welcome, atguigu" fi # 输入第二个参数,表示年龄,判断属于哪个年龄段 if [ $2 -lt 18 ] then echo "未成年人” elif [$2 -lt 35 ] then echo "青年人” elif [ $2 -lt 60 ] then echo "中年人" else #echo "成年人" echo "老年人" fi
./if_test.sh atguigu 15
# welcome, atguigu
# 未成年人
./if_test.sh atguigu 25
# welcome, atguigu
# 青年人
./if_test.sh atguigu 36
# welcome, atguigu
# 中年人
./if_test.sh atguigu 67
# welcome, atguigu
# 老年人
基本语法
case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
case 行尾必须为单词" in ",每一个模式匹配必须以右括号“)”结束。
双分号" ;; "表示命令序列结束,相当于java中的 break。
最后的"" *) "表示默认模式,相当于java中的 default。
vim case_test.sh
#!/bin/bash case $1 in 1) echo "one" ;; 2) echo "two" ;; 3) echo "three" ;; *) echo "number else" ;; esac
chmod +x case_test.sh
./case_test.sh 2 # two
./case_test.sh 1 # one
./case_test.sh 6 # number else
基本语法 1(和其他的语言比较相似,但是不是Shell中最常用的)
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
vim sum_to.sh
#!/bin/bash
for (( i=1; i <= $1; i++ )) # for后必须有空格,但是括号里无所谓;这里使用了双小括号(()),里面就可以用<=一类的运算符了
do
sum=$[ $sum+$i ]
done
echo sum
chmod +x sum_to.sh
./sum_to.sh 100 # 5050 for循环加到100
./sum_to.sh 10 # 55
a=3
if (($a > 2)); then echo OK; else echo notOK; fi # OK 接放一个数学表达式,这里用(())实现if,但是一般还是用[]这种标准化的写法
a=1
if (($a > 2)); then echo OK; else echo notOK; fi # notOK
案例实操
从 1 加到 100
基本语法 2
for 变量 in 值1 值2 值3…
do
程序
done
for os in linux windows macos; do echo $os; done
# linux
# windows
# macos
for i in {1..100}; do sum=$[$sum+$i]; done; echo $sum # 5050 这里用了{},它是shell的内部运算符,表示一个序列,{1..100}表示1到100,这种遍历方式像增强for循环
vim parameter_for_test.sh
#!/bin/bash
echo '===============$*================'
for para in $*
do
echo $para
done
echo '===============$@================'
for para in $@
do
echo $para
done
chmod +x parameter_for_test.sh
./parameter_for_test.sh a b c d e # $* 和 $@ 没有加引号
# ===============$*================
# a
# b
# c
# d
# e
# ===============$@================
# a
# b
# c
# d
# e
vim parameter_for_test.sh # 加引号
#!/bin/bash
echo '===============$*================'
for para in "$*"
do
echo $para
done
echo '===============$@================'
for para in "$@"
do
echo $para
done
./parameter_for_test.sh a b c d e
# ===============$*================
# a b c d e # $*认为这是多个参数的整体
# ===============$@================
# a # $@则是将它们作为独立的参数输出
# b
# c
# d
# e
- 使用
$*
相当于将所有位置参数不带引号的形式再次传递出去。由于不带引号,最大的问题是参数个数会被重新解析。比如第一个参数"I like"
作为一个整体被拆成了2个位置参数。 另外,由于每个位置参数都没有双引号,会再次做变量扩展,因此java*
变成了"javac"
。 这种使用方式,相当于bar $1 $2 $3 $4
。所以最终输出结果是4个位置参数,并且java*
被扩展为"javac"
。- 使用 @ 与 ‘ @ 与 ` @与‘*`没有区别。
- 使用
"$*"
根据man文档解释,相当于将所有位置参数连接成一个word。连接符就是IFS(一般就是空格),所以,此时输出的结果只有一个位置参数,位置参数格式变成了1个。由于有双引号的作用,java*
没有被扩展为"javac"
。 这种方式,相当于bar "$1 $2 $3 $4"
- 使用
"$@"
根据man文档解释,相当于拆分成多个word,并且每个word都有双引号。即相当于bar "$1" "$2" "$3" "$4"
。因此,位置参数格式保持不变,同时java*
没有被扩展为"javac"
案例实操
打印所有输入参数
比较 ∗ 和 *和 ∗和@区别
∗ 和 *和 ∗和@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 2 … 2 … 2…n的形式输出所有参数。
当它们被双引号""包含时,$*会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;$@会将各个参数分开,以“$1” “$2”…“$n”的形式输出所有参数。
基本语法
while [ 条件判断式 ]
do
程序
done
vim sum_to.sh
#!/bin/bash # 用for进行实现 for (( i=1; i <= $1; i++ )) # for后必须有空格,但是括号里无所谓;这里使用了双小括号(()),里面就可以用<=一类的运算符了 do sum=$[ $sum+$i ] done echo sum # 用while做一个实现 a=1 while [ $a -le $1 ] do sum2=$[ $sum2 + $a ] a=$[$a + 1] done echo $sum2
./sum_to.sh 100
# 5050
# 5050
vim sum_to.sh
#!/bin/bash # 用for进行实现 for (( i=1; i <= $1; i++ )) # for后必须有空格,但是括号里无所谓;这里使用了双小括号(()),里面就可以用<=一类的运算符了 do sum=$[ $sum+$i ] done echo sum # 用while做一个实现 a=1 while [ $a -le $1 ] do # sum2=$[ $sum2 + $a ] # a=$[$a + 1] # 这样也太麻烦了,后来的版本在优化 # 内嵌命令: let sum2+=a let a++ done echo $sum2
./sum_to.sh 100
# 5050
# 5050
案例实操
从 1 加到 100
基本语法
read (选项) (参数)
# 1) 选项:
# -p:指定读取值时的提示符;
# -t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待
# 2) 参数
# 变量:指定读取值的变量名
vim read_test.sh
#!/bin/bash
read -t 10 -p "请输入您的芳名:" name
echo "welcome, $name"
chmod +x read_test.sh
./read_test.sh
# 请输入您的芳名:atguigu # 输入atguigu
# welcome, atguigu
./read_test.sh
# 请输入您的芳名:welcome, # 一直等,不输入
案例实操
提示 7 秒内,读取控制台输入的名称
函数和Shell脚本差不多,Shell脚本的返回值是$?,但是这往往不是我们想要的,且在调用脚本时过于麻烦,
基本语法
basename [string / pathname] [suffix] # 功能描述:basename 命令会删掉所有的前缀包括后一个(‘/’)字符,然后将字符串显示出来。
# basename 可以理解为取路径里的文件名称
# 选项:
# suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。
ls
vim add.sh
date # 2023年 06月 12日 星期一 16:20:25 CST 当前的时间
date +%s # 1686558040 当前的时间戳
vim cmd_test.sh
#!/bin/bash
filename="$1"_log_$(date +%s) # $(date +%s)这里叫做命令替换,但是如果从函数角度看,这个就是调用了一下系统函数,后面+%s就是传入的参数,把得到的结果用$()符包起来,再进行字符串的拼接。
echo $filename
chmod +x cmd_test.sh ./cmd_test.sh atguigu # atguigu_log_167572035 vim cmd_test.sh vim parameter.sh ./parameter.sh a # ===================$n=================== # script name: ./parameter.sh # 1st parameter: a # 2nd parameter: # ===================$#=================== # parameter numbers: 1 # ===================$*=================== # a # ===================$@=================== # a /root/scripts/parameter.sh a b # ===================$n=================== # script name: /root/scripts/parameter.sh # 1st parameter: a # 2nd parameter: b # ===================$#=================== # parameter numbers: 2 # ===================$*=================== # a b # ===================$@=================== # a b # 如果不想看前面的/root/scripts/,只想看到parameter.sh basename /root/scripts/parameter.sh # parameter.sh basename /root/scri/safdia # sfdia 所以发现它并不是查找这个文件在不在,而只是作字符串的剪切 basename /root/scripts/parameter.sh .sh # parameter suffix,在后面再加上后缀,就也可以把后缀名剪切掉 vim parameter.sh
#!/bin/bash
echo '===================$n===================' # 这里用单引号是因为怕双引号会认为$n是个参数
echo script name: $( basename $0 .sh )
echo 1st parameter: $1
echo 2nd parameter: $2
echo '===================$#==================='
echo parameter numbers: $#
echo '===================$*==================='
echo $*
echo '===================$@==================='
echo $@
./parameter.sh a b # ===================$n=================== # script name: parameter # 1st parameter: a # 2nd parameter: b # ===================$#=================== # parameter numbers: 2 # ===================$*=================== # a b # ===================$@=================== # a b /root/scripts/parameter.sh a b # ===================$n=================== # script name: parameter # 1st parameter: a # 2nd parameter: b # ===================$#=================== # parameter numbers: 2 # ===================$*=================== # a b # ===================$@=================== # a b
案例实操
截取该/home/atguigu/banzhang.txt 路径的文件名称。
基本语法
dirname 文件绝对路径 # 功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
# dirname 可以理解为取文件路径的绝对路径名称
dirname /root/scripts/parameter.sh # /root/scripts 发现和basename相反
dirname ../scripts/parameter.sh # ../scripts 和basename一样,都是只是字符串的剪切,不会查看文件是否存在
dirname ../scri/dsafdi/adsgsdagf # ../scri/dsafdi
vim parameter.sh
#!/bin/bash
echo '===================$n===================' # 这里用单引号是因为怕双引号会认为$n是个参数
echo script name: $( basename $0 .sh )
# cd $(dirname $0) # 切换目录到当前目录
echo script path: $(cd $(dirname $0); pwd)
echo 1st parameter: $1
echo 2nd parameter: $2
echo '===================$#==================='
echo parameter numbers: $#
echo '===================$*==================='
echo $*
echo '===================$@==================='
echo $@
./parameter.sh a b # ===================$n=================== # script name: parameter # script path: /root/scripts # 1st parameter: a # 2nd parameter: b # ===================$#=================== # parameter numbers: 2 # ===================$*=================== # a b # ===================$@=================== # a b cd /home/atguigu/ # 换路径 ../../root/scripts/parameter.sh a b # 无论在哪个目录path都可以对 # ===================$n=================== # script name: parameter # script path: /root/scripts # 1st parameter: a # 2nd parameter: b # ===================$#=================== # parameter numbers: 2 # ===================$*=================== # a b # ===================$@=================== # a b # $()命令替换,就是函数的调用
案例实操
获取 banzhang.txt 文件的路径。
基本语法
[ function ] funname[()]
{
Action;
[return int;]
}
vim fun_test.sh
#!/bin/bash
function add(){
s=$[$1 + $2]
echo "和:"$s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
add $a $b
chmod +x fun_test.sh
./fun_test.sh
# 请输入第一个整数: 35
# 请输入第二个整数: 67
# 和: 102
vim fun_test.sh # 参数解决了,但是只是直接echo显示,没有返回值
#!/bin/bash
function add(){
s=$[$1 + $2]
# echo "和:"$s
return "和: " $s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
add $a $b
echo $?
./fun_test.sh # 说返回值只能是0-255的数
# 请输入第一个整数: 35
# 请输入第二个整数: 67
# ./fun_test.sh: 第 5 行:return: 和: 102: 需要数字参数255
vim fun_test.sh
#!/bin/bash
function add(){
s=$[$1 + $2]
# echo "和:"$s
return $s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
add $a $b
echo "和: " $?
./fun_test.sh # 成功执行了
# 请输入第一个整数: 35
# 请输入第二个整数: 67
# 和: 102
./fun_test.sh # 得数错了
# 请输入第一个整数: 156
# 请输入第二个整数: 237
# 和: 137
vim fun_test.sh
#!/bin/bash
function add(){
s=$[$1 + $2]
# echo "和:"$s
# return $s
echo $s
}
read -p "请输入第一个整数:" a
read -p "请输入第二个整数:" b
sum=$(add $a $b)
echo "和: " $sum
echo "和的平方:" $[$sum * $sum]
./fun_test.sh
# 请输入第一个整数: 156
# 请输入第二个整数: 237
# 和: 393
# 和的平方: 154449
经验技巧
必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行。不会像其它语言一样先编译。
函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值 n(0-255)
案例实操
计算两个输入参数的和。
实际生产应用中,往往需要对重要数据进行归档备份。
需求:实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/root/archive 下。
这里用到了归档命令:tar
后面可以加上-c 选项表示归档,加上-z 选项表示同时进行压缩,得到的文件后缀名为.tar.gz。
脚本实现如下:
#!/bin/bash # 首先判断输入参数个数是否为 1 if [ $# -ne 1 ] then echo "参数个数错误!应该输入一个参数,作为归档目录名" exit fi # 从参数中获取目录名称 if [ -d $1 ] then echo else echo echo "目录不存在!" echo exit fi DIR_NAME=$(basename $1) DIR_PATH=$(cd $(dirname $1); pwd) # 获取当前日期 DATE=$(date +%y%m%d) # 定义生成的归档文件名称 FILE=archive_${DIR_NAME}_$DATE.tar.gz DEST=/root/archive/$FILE # 开始归档目录文件 echo "开始归档..." echo tar -czf $DEST $DIR_RATH/$DIR_NAME if [ $? -eq 0 ] then echo echo "归档成功!" echo "归档文件为:$DEST" echo else echo "归档出现问题!" echo fi exit
vim daily_archive.sh
#!/bin/bash # 首先判断输入参数个数是否为1 if [ $# -ne 1 ] then echo "参数个数错误!应该输入一个参数,作为归档目录名" exit # exit就可以直接退出 fi # 从参数中获取目录名称 if [ -d $1 ] then echo else echo echo "目录不存在!" echo exit fi # 提取目录名称 DIR_NAME=$(basename $1) DIR_PATH=$(cd $(dirname $1); pwd) # 获取当前日期 DATE=$(date +%y%m%d) # 定义生成的归档文件名称 FILE=archive_${DIR_NAME}_$DATE.tar.gz # 文件名称 DEST=/root/archive/$FILE #文件的绝对路径名 # 开始归档目录文件 echo "开始归档..." echo tar -czf $DEST $DIR_PATH/$DIR_NAME # 归档 # 判断归档是否成功 if [ $? -eq 0 ] then echo echo "归档成功!" echo "归档文件为:$DEST" echo else echo "归档出现问题!" echo fi exit
chmod u+x daily_archive.sh
ll
./daily_archive.sh # 参数个数错误!应该输入一个参数,作为归档目录
./daily_archive.sh a b
# 参数个数错误!应该输入一个参数,作为归档目录
./daily_archive.sh ../scripts # 提示归档出现问题!,是因为没有/root/archive/目录
mkdir /root/archive
./daily_archive.sh ../scripts # 归档成功
crontab -l # 这个我们也没有必要每次手动去归档,可以设置定时任务
crontab -e # 编辑定时任务, 在里面添加0 2 * * * /root/scripts/daily_archive.sh /root/scripts
crontab -l # 这样就每天定时归档,实现数据的备份归档管理
正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中,grep,sed,awk 等文本处理工具都支持通过正则表达式进行模式匹配。
一串不包含特殊字符的正则表达式匹配它自己,例如:
cat /etc/passwd | grep atguigu
就会匹配所有包含 atguigu 的行。
ls
vim daily_archive.sh
cat /etc/passwd # 可以获取到所有的用户信息
cat /etc/passwd | grep atguigu # 信息太多,如果只要看atguigu的信息,可以在后面加上| grep atguigu,直接筛选出来atguigu的相关信息
cat /etc/passwd | grep 1000: # 筛选出所有的和1000:相关的信息
cat /etc/passwd | grep 00: # 筛选出所有的和00:相关的信息
特殊字符:^
^ 匹配一行的开头,例如:
cat /etc/passwd | grep ^a
会匹配出所有以 a 开头的行
特殊字符:$
$ 匹配一行的结束,例如
cat /etc/passwd | grep t$
会匹配出所有以 t 结尾的行
思考:^$ 匹配什么?
特殊字符:.
. 匹配一个任意的字符,例如
cat /etc/passwd | grep r..t
会匹配包含 rabt,rbbt,rxdt,root 等的所有行
特殊字符:*
==*== 不单独使用,他和上一个字符连用,表示匹配上一个字符 0 次或多次,例如
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep ro*t
会匹配 rt, rot, root, rooot, roooot 等所有行
思考:.*匹配什么?
字符区间(中括号):[ ]
[ ] 表示匹配某个范围内的一个字符,例如
[6,8]------匹配 6 或者 8
[0-9]------匹配一个 0-9 的数字
[0-9]*------匹配任意长度的数字字符串
[a-z]------匹配一个 a-z 之间的字符
[a-z]* ------匹配任意长度的字母字符串
[a-c, e-f]-匹配 a-c 或者 e-f 之间的任意字符
cat /etc/passwd | grep r[a,b,c]*t
会匹配 rt,rat, rbt, rabt, rbact,rabccbaaacbt 等等所有行
特殊字符:\
\ 表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配
某一特殊字符本身时(例如,我想找出所有包含 ‘$’ 的行),就会碰到困难。此时我们就要
将转义字符和特殊字符连用,来表示特殊字符本身,例如
cat /etc/passwd | grep 'a\$b'
就会匹配所有包含 a$b 的行。注意需要使用单引号将表达式引起来。
cat /etc/passwd | grep ^a # 获取到的都是以a开头的行 cat /etc/passwd | grep ^at # 获取所有以at开头的行 cat /etc/passwd | grep bash$ # 获取所有以bash结尾的行 cat /etc/passwd | grep ^atbash$ # 写死了时获取atbash cat /etc/passwd | grep ^$ # 什么都没有,其实^$是指空行 cat daily_archive.sh | grep ^$ # 空行 cat daily_archive.sh | grep -n ^$ # 显示行号的空行 cat daily_archive.sh | grep r..t # 显示所有r和t中间只隔2个字符的行 cat /etc/passwd | grep r..t cat /etc/passwd | grep r.t # 显示所有r和t中间只隔1个字符的行 cat /etc/passwd | grep r...t # 显示所有r和t中间只隔3个字符的行 cat /etc/passwd | grep ro*t # 获取所有r和t之间有任意个o的行,包含没有 cat /etc/passwd | grep ^a.*bash$ # .*是指任意字符,这里表示以a开头,bash结尾的中间有任意字符的行 cat /etc/passwd | grep ^a.*in$ # .*是指任意字符,这里表示以a开头,in结尾的中间有任意字符的行 cat /etc/passwd | grep ^a.*var.*in$ # 以a开头,in结尾,中间有任意位置有var的行 cat /etc/passwd | grep r[a,b]t # 匹配rat或者是rbt echo "rbtadfasf" | grep r[a,b]t echo "23ddratadfasf" | grep r[a,b]t echo "23ddratadfasf" | grep r[ab]t # r[ab]t中间也可以不加逗号 echo "23ddraaatadfasf" | grep r[ab]*t # 匹配a或者b出现任意多次 echo "23ddrabbadfasf" | grep r[ab]*t # 也可以匹配到 cat /etc/passwd | grep r[a-z]*t # 匹配r和t之间有任意字母的行 cat daily_archive.sh | grep $ # 默认认为$是结尾,但是这里没有指定以什么结尾,所有就全部输出了 cat daily_archive.sh | grep '\$' # 要匹配$符,就要进行转义, 并且必须要用单引号''引起来,不能用双引号。 cat daily_archive.sh | grep '/\$' # 匹配/$
# 匹配一个手机号
echo "13812345678" | grep ^1[34578][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$ # 匹配一个手机号
echo "138123456780" | grep ^1[34578][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$ # 匹配失败
echo "15912345678" | grep ^1[34578][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$ # 匹配成功
echo "138123456780" | grep ^1[34578][0-9]{9}$ # 这里使用拓展的正则表达式,但是不支持,需要加-E
echo "138123456780" | grep -E ^1[34578][0-9]{9}$ # 加上-E之后就支持这种{}表示次数的写法了
cut 的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
基本用法
cut [选项参数] filename
# 说明:默认分隔符是制表符
vim cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
cat cut.txt # dong shen # guan zhen # wo wo # lai lai # le le cut -d " " -f 1 cut.txt # 按空格分割,提取第一列 # dong # guan # wo # lai # le cut -d " " -f 2,3 cut.txt # 按空格分割,提取第2,3列 # shen # zhen # wo # lai # le cat /etc/passwd | grep bash$ # 信息太多 cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,7 cat /etc/passwd | grep bash$ | cut -d ":" -f 1-4 # 按:分割,提取1到4列 cat /etc/passwd | grep bash$ | cut -d ":" -f 4- # 提取4列到最后 cat /etc/passwd | grep bash$ | cut -d ":" -f -4 # 提取第4列到开头的列 echo $PATH # /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin echo $PATH | cut -d ":" -f 2- # /usr/local/bin:/usr/sbin:/usr/bin:/root/bin echo $PATH | cut -d ":" -f 3- # /usr/sbin:/usr/bin:/root/bin ifconfig ifconfig ens33 ifconfig ens33 | grep netmask # inet 192.168.126.100 netmask 255.255.255.0 broadcast 192.168.126.255 筛选出了有ip地址的行 ifconfig ens33 | grep netmask | cut -d " " -f 10 # 192.168.126.100 这样就剪切出了IP,前面有空格,所以是10 ifconfig ifconfig | grep netmask | cut -d " " -f 10 # 提取出了所有的IP地址 # 192.168.126.100 # 127.0.0.1 # 192.168.122.1
选项参数说明
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符分割列,默认是制表符"\t" |
-c | 按字符进行切割 后加加 n 表示取第几列 比如 -c 1 |
案例实操
数据准备
切割 cut.txt 第一列
切割 cut.txt 第二、三列
在 cut.txt 文件中切割出 guan
选取系统 PATH 变量值,第 2 个“:”开始后的所有路径:
切割 ifconfig 后打印的 IP 地址
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法
awk [选项参数] '/pattern1/{action1} /pattern2/{action2}...' filename
# pattern:表示 awk 在数据中查找的内容,就是匹配模式 # pattern其实是正则表达式
# action:在找到匹配内容时所执行的一系列命令
which awk # /usr/bin/awk ll /usr/bin | grep awk # awk->gawk awk链接指向了gawk,awk实际上用的是gawk,gawk是awk的GNU版 cat /etc/passwd | grep ^root | cut -d ":" -f 7 # /bin/bash 截取 cat /etc/passwd | awk -F ":" '/^root/ {print $7}' # awk -F指定按什么分割,如果不指定,默认按空格分割,'/pattern/ {}' pattern是正则表达式,{}里面放执行的代码,直接输出第7列 print $7 , awk一个工具代替了grep和cut两个命令 cat /etc/passwd | grep ^root | cut -d ":" -f 1,6,7 # root:/root:/bin/bash 这样只能按原来的输出,如果想在1 6 7中间加逗号,这样grep和cut就没法实现了 cat /etc/passwd | awk -F ":" '/^root/ {print $1","$7}' # root,/bin/bash 用awk就可以在中间加东西,它会按照$1","$7的格式输出第1列和第7列 cat /etc/passwd | awk -F ":" '/^root/ {print $1","$6","$7}' # root, /root,/bin/bash 同样,这样可以输出1 6 7 列 cat /etc/passwd | awk -F ":" '{print $1","$7}' # 所有行的第1列和第7列 cat /etc/passwd | awk -F ":" 'BEGIN{print "user, shell"}{print $1","$7} END{print "end of file"}' # 在输出的时候在头部输出 user, shell 在尾部输出end of file cat /etc/passwd | awk -F ":" '{print $3}' # 打印出所有的ID cat /etc/passwd | awk -F ":" '{print $3+1}' # 打印出所有的ID+1 cat /etc/passwd | awk -F ":" '{print $3+2}' # 打印出所有的ID+2,如果又想改ID+n,就又得改命令 cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}' # 这样就不用一直改命令了,只要传参数,且在{}中不需要加$i,直接写i cat /etc/passwd | awk -v i=2 -F ":" '{print $3+i}' # ID+2 cat /etc/passwd | awk -F ":" '{print "文件名:"FILENAME "行号:"NR "列数:"NF}' # 所有的文件名都是-,因为这里是管道操作,利用内置变量获取 awk -F ":" '{print "文件名:"FILENAME "行号:"NR "列数:"NF}' /etc/passwd # 直接传入,文件名就可以直接显示了 ifconfig | grep -n ^$ # 用grep显示空行的行号,且打印出的行号后面有冒号 # 9: # 18: # 26: ifconfig | awk '/^$/ {print NR}' # awk没有冒号 # 9 # 18 # 26 ifconfig | awk '/^$/ {print "空行:"NR}' # 按照格式 # 空行:9 # 空行:18 # 空行:26 ifconfig ens33 | grep netmask # 之前用cut剪切IP ifconfig ens33 | grep netmask | cut -d " " -f 10 ifconfig | grep netmask | cut -d " " -f 10 ifconfig | awk '/netmask/ {print $2}' # awk默认就是按照空格分割的,awk不用想cut一样要考虑前面的空格,直接$2
选项参数说明
选项参数 | 功能 |
---|---|
-F | 指定输入文件分隔符 |
-v | 赋值一个用户定义变量 |
案例实操
数据准备
搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 7 列。
搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 1 列和第 7 列,中间以“,”号分割。
注意:只有匹配了 pattern 的行才会执行 action。
只显示/etc/passwd 的第一列和第七列,以逗号分割,且在所有行前面添加列名 user,shell 在最后一行添加"dahaige,/bin/zuishuai"。
注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。
将 passwd 文件中的用户 id 增加数值 1 并输出
awk 的内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数(行号) |
NF | 浏览记录的域的个数(切割后,列的个数) |
案例实操
统计 passwd 文件名,每行的行号,每行的列数
查询 ifconfig 命令输出结果中的空行所在的行号
切割 IP
我们可以利用 Linux 自带的 mesg 和 write 工具,向其它用户发送消息。
需求:实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。
脚本实现如下:
#!/bin/bash login_user=$(who | grep -i -m 1 $1 | awk '{print $1}') if [ -z $login_user ] then echo "$1 不在线!" echo "脚本退出.." exit fi is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ $is_allowed != "+" ] then echo "$1 没有开启消息功能" echo "脚本退出.." exit fi if [ -z $2 ] then echo "没有消息发出" echo "脚本退出.." exit fi whole_msg=$(echo $* | cut -d " " -f 2- ) user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}') echo $whole_msg | write $login_user $user_terminal if [ $? != 0 ] then echo "发送失败!" else echo "发送成功!" fi exit
who am i # 查看自己的用户信息 who # 查看所有的用户 who am i who # 打开atguigu用户的连接之后,查看所有用户 mesg # 查看消息接收是否开启 who -T # 用户有"+",就是打开消息接收了,CentOS是默认开启的,ubuntu是默认关闭的 # root + pts/0 2022-03-18 14:33 (192.168.126.1) # atguigu + pts/1 2022-03-18 18:58 (192.168.126.1) mesg n # 关闭mesg who -T # root就变成"-" # root - pts/0 2022-03-18 14:33 (192.168.126.1) # atguigu + pts/1 2022-03-18 18:58 (192.168.126.1) mesg y # 开启mesg who -T # root + pts/0 2022-03-18 14:33 (192.168.126.1) # atguigu + pts/1 2022-03-18 18:58 (192.168.126.1) who -T # 如果再开一个atguigu的控制台 # root + pts/0 2022-03-18 14:33 (192.168.126.1) # atguigu + pts/1 2022-03-18 18:58 (192.168.126.1) # atguigu + pts/2 2022-03-18 18:58 (192.168.126.1) write atguigu pts/1 # 后面要传入控制台pts/1,因为一个用户可以开多个控制台,如atguigu有pts/1和pts/2 # hi, atguigu # hello # a^Hh^H^H^H # 这里按tab键,被认为是非法字符 # how are you vim send_msg.sh # 写一个脚本文件,以后发送消息就可以直接调用脚本,不用想前面的
#!/bin/bash # 查看用户是否登录 login_user=$(who | grep -i -m 1 $1 | awk '{print $1}') # 命令替换,grep -i 是忽略打消写 -m 后面加数字,是获取多少行 if [ -z $login_user ] # 判断login_user有没有,-z判断是否为空,判断login_user里面有没有,是不是空 then echo "$1 不在线!" echo "脚本退出.." exit fi # 查看用户是否开启消息功能 is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ $is_allowed != "+" ] then echo "$1 没有开启消息功能" echo "脚本退出.." exit fi # 确认是否有消息发送 if [ -z $2 ] then echo "没有消息发出" echo "脚本退出.." exit fi # 从参数中获取要发送的消息 whole_msg=$(echo $* | cut -d " " -f 2- ) # $*全部参数 # 获取用户登录的终端 user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}') # 写入要发送的消息 echo $whole_msg | write $login_user $user_terminal # 判断发送是否成功 if [ $? != 0 ] then echo "发送失败!" else echo "发送成功!" fi exit
chmod u+x send_msg.sh ./send_msg.sh # 用法: grep [选项]... PATTERN [FILE]... # 试用'grep --help'来获取更多信息。 # 不在线! # 脚本退出.. ./send_msg.sh xiaoming # xiaoming 不在线! # 脚本退出.. ./send_msg.sh atguigu # 没有消息发送 # 脚本退出.. ./send_msg.sh atguigu hi, atguigu # 发送成功! ./send_msg.sh atguigu boss is coming # 发送成功!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。