适用人群:
运维工程师(系统运维、应用运维、DBA)
开发工程师(内核/驱动开发、软件开发、嵌入式开发 )
架构师(进阶,性能调优、故障处理、…)
应用场景:
Web应用
数据库
大数据
云计算
物联网
图标: TUX(晚礼服的企鹅)
作者: Linus Torvalds(20岁发布0.01版本;学习大佬,成为牛人)
汇编语言 -> 操作机器语言(0/1)
狭义: linux kernel
广义: GNU/Linux
CentOS版本
源头: 贝尔实验室(Ken Thompson[Unix之父]/Dennis Ritchie)
为了开发系统,发明了高级语言(基于ForTran语言发明了B语言,解释型语言),进而New B, 为了更直观,改名C语言。
大型系统一般适用UNIX,商业化(收费)
BSD: 伯克利软件套件
FreeBSD: 1993
Solaris: Sun公司,Oracle,对硬件依赖严重?
Minix: Andrew Tanenbaum
Linux源码公开,更改、发布后需要公开(Free)
源代码管理:
SVN
BitKeeper
Git
Github: 源代码交流平台
Richard Stallman
自由软件,GNU(1985)
GPL(1989)
保障个人开发自由
GNU核心: GNU/Hurd
Linux内核加入GNU (GNU/Linux, 能直接上手的linux)
GNU/Linux(计算机硬件 -> 硬件接口层[核心层kernel] -> 命令解释层 -> 外围应用层)
BSD
保障公司自由
Linux发行版
Fedora: 新但是可能不稳定
CentOS: 免费
Debian: 社区类Linux
Ubuntu: 针对桌面有优化,Gnome,硬件兼容性强于CentOS,资源占用多
SUSE: 号称最华丽的OS,KDE
OS: 操作计算机底层硬件的软件
OS启动流程
安装系统时核心分区
文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。
缩写:Fourth Extended Filesystem,第四代扩展文件系统的缩写
起源:2008
特点:
1、可靠,它是由比较老的代码生成的;
2、日志文件系统,对文件在磁盘中的位置以及任何其它对磁盘的更改做记录。如果系统崩溃,得益于journal技术,文件系统很少会损坏。
3、文件系统容量达到1EB,而文件容量达到了16TB. 理论上支持无限数量的子目录。除此以外,EXT4的分配器MBalloc还支持一次性调用分配多个数据块,
4、引入了盘区概念,每个盘区为一组连续的数据块,上述文件可以通过盘区的方式表示为“该文件数据保存在接下来的25600个数据块中”,提高了访问效率。
5、给日志数据添加了校验功能,日志校验功能可以很方便地判断日志数据是否损坏。
6、高性能,将ext3的两阶段日志机制合并成一个阶段,在增加安全性的同时提高了性能。日志总归会占用一些开销,ext4允许关闭日志,以便某些有特殊需求的用户可以借此提升性能
缩写:
起源:1993,由Silicon Graphics为他们的操作系统开发,之后被移植到Linux内核上。
特点:
1、特别擅长处理大文件,同时提供大型的数据传输。
2、对文件系统元数据提供了日志支持。当文件系统更新时,元数据会在实际的磁盘块被更新之前顺序写入日志。XFS的日志被保存在磁盘块的循环缓冲区上,不会被正常的文件系统操作影响。
3、64bit文件系统,最大支持 8EiB(exbibytes, 2^60 bytes)减1字节的单个文件系统,实际部署时取决于宿主操作系统的最大块限制。对于一个32bit Linux系统,文件和文件系统的大小会被限制在 16TiB(Tebibyte , 2^40 bytes) bytes。
最大容量: 8EB
硬盘不同分区根据需要挂载到/(root)
或者其他目录
相关概念:挂载点
/bin: binary, 存放经常使用的命令,一般是软链接,指向/usr/bin
/sbin: super user bin, 存放系统管理员使用的系统管理程序, 一般是软链接,指向/usr/sbin
/home: 存放普通用户的主目录,每个用户都有自己的一个目录,以用户名命名
/root: 系统管理员的用户主目录
/lib: 系统开机所需要的最基本的动态链接共享库,类似windows的dll文件(system32目录等). 一般是软链接,指向/usr/lib
/lib64:
/lost+found: 一般是空的,当系统非法关机后,会存放一些文件
/etc: 所有系统管理所需的配置文件和子目录
/usr: 用户的很多应用程序和文件都存放于此,类似于windows的program files目录
/boot: 存放启动linux时使用的一些核心文件,包括一些连接文件以及镜像文件
/proc: 虚拟目录,系统内存的映射,可以通过直接访问这个目录来获取系统信息
/srv: service, 存放一些服务启动之后需要提取的数据
/sys: linux2.6内核引入,安装了2.6内核中新出现的一个文件系统sysfs
/tmp: 存放临时文件
/dev: 类似windows设备管理器,把所有的硬件用文件的形式存储
/media(centos6): 识别设备后,将其挂载到该目录,centos7迁移至/run/media
/mnt: 用于用户临时挂载别的文件系统,可以将外部的存储挂载到/mnt/上,然后进入该目录就可以查看其内容
/opt: 用于给主机额外安装软件所存放的目录,默认空
/var: 存放不断扩充的文件,通常将经常被修改的目录存放于此,包括各种日志文件
vim = vi + 染色 + 语法检查 + …
编辑器之神
emacs 神之编辑器,作者:GNU创始人Richard Stallman,基于Lisp写的解释器
默认模式
操作:移动、删除字符/整行、复制/粘贴
显示信息:坐标、百分比
常用语法:
语法 | 描述 |
---|---|
yy | 复制当前行 |
y[数字]y | 复制n行 |
p | 粘贴 |
u | 撤销上一步 |
dd | 删除当前行 |
d[数字]d | 删除n行 |
x | 剪切一个字母(del) |
X | 剪切一个字母(backspace) |
yw | 复制一个词 |
dw | 删除一个词 |
shift+6(^) | 移动至行头 |
shift+4($) | 移动到行尾 |
w | 切到下一个词头 |
e | 切到下一个词尾 |
b | 切到上一个词头 |
gg | 页头 |
G | 页尾 |
数字+shift+g | 移动到n行头 |
从一般模式进入方式:i/a/o
离开方式:ESC
常用语法:
语法 | 描述 |
---|---|
i | 当前光标前 |
a | 当前光标后 |
o | 当前光标行的下一行 |
I | 光标所在行最前 |
A | 光标所在行最后 |
O | 当前光标行的上一行 |
从一般模式进入方式:‘:’ / ‘/’
离开方式:ESC / :q / :q! / :wq
主要操作:保存、退出编辑器
常用语法:
语法 | 描述 |
---|---|
:set nu | 显示行号 |
:set nonu | 关闭行号 |
:w | |
:q | |
:wq | |
:! | 强制执行 |
/word | n查找下一个,N查找上一个 |
:noh | 取消高亮显示 |
/old/new/g | 替换当前行所有匹配内容 |
:%s/old/new/g | 替换内容,/g替换匹配到的所有内容 |
/old/new | 替换匹配到的第一个内容 |
:%s/old/new | 替换每一行匹配到的第一个内容 |
注::s
在部分markdown中会显示为表情,可以用:s
代替,这个在csdn中好像无效
切换快捷键:shift+space
windows ip查询
方法1:cmd -> ipconfig
方法2:网络适配器 -> 以太网 -> 状态 -> 详细信息
linux ip查询
ifconfig
场景1:虚拟机ping不通主机,但是主机能够ping虚拟机
打开主机的规则(防火墙->入站规则->文件和打印机共享回显请求专用公用)
虚拟机直接连接外部物理网络的模式,主机起到网桥作用,虚拟机可以直接访问外部网络,并且对外部网络可见
虚拟机和主机构建一个专用网络,并通过虚拟网络地址转换(NAT)设备对IP进行转换。虚拟机通过共享主机IP可以访问外部网络,但外部网络没法访问虚拟机
虚拟机只与主机共享一个专用网络,与外部网络无法通信
linux
hostname
hostnamectl [set-hostname new_name]
/etc/hostname
windows
C:\Windows\System32\driver\etc\hosts
修改hosts文件,可以使用主机名/域名代替ip
192.168.122.100 hadoop100
192.168.122.101 hadoop101
...
10.23.23.23 www.domain_name.com
ping hadoop100
注意:域名劫持
#################################################################################
# /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0 #设置开机自动连接网络
allow-hotplug eth0
iface eth0 inet static #static表示固定ip , dhcp表示使用动态ip
address 192.168.3.x #设置ip地址
netmask 255.255.255.0 #设置子网掩码
network 192.168.3.0 #
broadcast 192.168.3.255
gateway 192.168.3.1 #设置网关
################################################################################
# /etc/resolv.conf
nameserver 192.168.3.1 # 一般和gateway的地址是一致的
#################################################################################
# 设置完重启服务或者重启,重启服务下面两个命令之一即可
service networking restart #重启网络
/etc/init.d/networking restart #记得sudo
#################################################################################
远程登陆工具:
xshell
SSH Secure Shell
SecureCRT
FinalShell
linux中的进程和服务
process: 计算机中一个正在执行的程序或命令
service: 启动后一只存在、常驻内存的process
传输文件
scp
xftp
...
centos7使用NetworkManager
systemctl stop NetworkManager
systemctl disable NetworkManager
network和NetworkManager只需要存在一个running
修改IP后可能遇到的问题
1 物理机能ping虚拟机,但是虚拟机不能ping物理机 =》 物理机防火墙没关
2 虚拟机能ping物理机,但是虚拟机不能ping外网 =》 DNS设置问题
3 虚拟机ping www.baidu.com 显示域名未知等信息 =》 查看GATEWAY和DNS设置是否正确
4 如果上述方法还是解决不了=》关闭NetworkManager服务
systemctl stop NetworkManager
systemctl disable NetworkManager
5 若检查发现systemctl status network有问题 =》 检查ifcfg-eth0
命令
# centos6
service service_name start | stop | restart | status
# centos7
systemctl start | stop | restart | status service_name
查看当前启用服务
ls /etc/init.d/
# centos7
ls /usr/lib/systemd
ls /usr/lib/systemd/system/ # .service后缀
设置开机自启动服务
setup
SystemV
第一个启动的服务init
# centos6 只能串行启动,仅老版 systemV
chkconfig --list
chkconfig service_name on | off
chkconfig --level x service_name on | off
# centos7 并行
systemctl disable | enable | status | stop | restart service_name
systemctl list-unit-files # 状态: enable / disable / static(不确定,与其他有关联)
防火墙
老版本: iptables
新版本: firewalld
进程分类:前台、后台(守护进程,有后缀d)
1 系统服务
2 用户进程/服务
ps
ps [-euf] [aux] # 查看进程,-属于标准unix风格,不加-属于BSD风格
ps aux | less
ps -auhadoop # 查看hadoop进程
选项 | 说明 |
---|---|
a | 列出带有终端的所有用户的进程 |
x | 列出当前用户的所有进程,包括没有终端的进程 |
u | 面向用户友好的显示风格 |
-e | 列出所有进程 |
-u | 列出某个用户关联的所有进程 |
-f | 显示完整格式的进程列表 |
[hadoop@hadoop001 Documents]$ bash
[hadoop@hadoop001 Documents]$ ps -f
UID PID PPID C STIME TTY TIME CMD
hadoop 6102 6098 0 02:19 pts/2 00:00:00 -bash
hadoop 6455 6102 0 02:32 pts/2 00:00:00 bash # 父shell是-bash
hadoop 6497 6455 0 02:32 pts/2 00:00:00 ps -f
[hadoop@hadoop001 Documents]$ exit # 退出子shell
exit
[hadoop@hadoop001 Documents]$ ps -f
UID PID PPID C STIME TTY TIME CMD
hadoop 6102 6098 0 02:19 pts/2 00:00:00 -bash
hadoop 6528 6102 0 02:33 pts/2 00:00:00 ps -f
VSZ 虚拟内存,不常用进程会被置换至虚拟内存,LRU(最近最少使用)
RSS 物理内存
TTY 终端,?代表没有终端,tty(tty1,图形化终端,tty2-6, 字符界面终端,pts/0-255,虚拟终端)
进程状态
stat | 说明 |
---|---|
S | 睡眠状态 |
s | 包含子进程 |
R | 运行状态 |
T | 暂停状态 |
Z | 僵尸状态 |
l | 小写l,多进程 |
+ | 前台显示 |
START 启动时间
TIME 持续时间
PPID 父进程ID
systemd即init,PID=1,被系统级别进程(0)启动
场景
查看cpu占用率和内存占用率:aux
查看父进程:-ef
踢用户: ps 找到用户,kill
pstree
查看父进程等信息
pstree -p
pstree -u
kill
kill [option] process_id
killall service_name
kill -9 process_id
kill -l
killall sshd # 慎用,需要到设备上systemctl start sshd
top
top [option]
-d 秒数 # 刷新时间,默认3秒
-i # 不显示闲置或者僵死进程
-p # 通过指定监控进程ID来仅监控某个进程
# 默认按CPU排序(P),按下M,则按memory排序;进程号(N);上下键可以翻页
k # 可以直接kill进程,+sig 比如9
# 回显
# %Cpu(s): 0.1 us, 0.0 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
# us(user) sy(system) ni(nice,调整优先级后的用户) id(idle) wa(wait) hi(hardware interrupt) si(software interrupt) st(stolen)
netstat
显示网络状态和端口信息
netstat -anp | grep process_id
netstat -nlp | grep port_id
-a # 显示所有正在监听和未监听的套接字(进程间通信使用的)
-n # 拒绝显示别名
-l # 仅列出在监听的服务状态
-p # 表示显示那个进程在调用
crontab
定时任务
crontab [option]
-e 编辑crontab定时任务
-l 查询crontab任务
-r 删除当前用户所有的crontab任务
systemctl restart crond
* * * * * task_op
第一个* 一小时中的第几分钟 0-59
第二个* 一天中的第几小时 0-23
第三个* 一个月中的第几天 1-31
第四个* 一年中的第几个月 1-12
第五个* 一周中的周几 0-7 # 可以或
特殊符号:
* 任意
, 不连续
- 连续
*/n 每隔多久执行一次
默认级别: /etc/inittab
常用运行级别
级别 | 描述 |
---|---|
0 | 系统停机状态,系统默认运行级别不能设为0,否则不能启动 |
1 | 单用户工作状态,root权限,用于系统维护,禁止远程登陆 |
2 | 多用户状态(无NFS),不支持网络 |
3 | 完全的多用户状态(有NFS),登陆后进入控制台命令行模式 |
4 | 系统未使用,保留 |
5 | X11控制台,登陆后进入图形GUI模式 |
6 | 系统正常关闭并重启,默认运行级别不饿能设为6,否则不能启动 |
注:常用级别为3/5
查看当前当前运行级别
systemctl get-default
内嵌于shell中,即linux源码中,系统加载启动之后随shell一起加载,常驻系统内存
基本命令:
help command_name
man [type] command_name
alias command_name
type command_name
history
exit
clear # 也可以使用 ctrl + l
reset # 重新初始化终端
pwd # 绝对路径
l. # ls -d .*
ls -i # vim修改文件后,索引会变化
echo # 输出到控制台, 连续多个空格会输出为一个,echo strings, echo "strings", 支持制表符(-e)
echo $ + tab # 查看环境变量
举例
man man
man -f cd
man 1p cd
man 1 cd
alias ll='ls -l --color=auto'
除内置命令
rmdir [-p]
mkdir [-p]
rm
touch # vim 创建新文件借助文本编辑器,若没有新增,则不会创建新文件,与touch不同
\cp # 无提示,直接覆盖,使用linux原生命令 type cp -> cp -i
\rm
cat [-n]
more # 分屏查看,只能查看的简化版vi
less # 分屏查看,按需加载
head [-n] # 默认10行
tail [-n] # 默认10行
tail -f # 实时跟踪该文档的更新,应用场景:日志文件等持续增长且不会更改;起了一个进程挂起;ctrl+s 暂停 ctrl+q 继续 ctrl+c 退出
rm -rf link_name/ # 带/后缀会删除源目录下内容
ln [-s] src_file link_file # 如果不带s,则为硬链接 硬链接指向原inode,软链接创建一个新的文件指向
date
date +%Y
date +%y
date +%m
date +%d
date +%Y-$m-%d-%H:%M:%S # 自己定制显示格式,如果有空格,用""
date +%s # 当前秒数的时间戳,1970/1/1起始
date -d "1 days ago"
date -s "2017-06-19 20:52:52" # 设置当前时间
ntp date # 设置为网络时间
ntpdate src_link
cal
用户管理
useradd
id user_name
less /etc/passwd # 查看当前所有用户,可以看到系统用户(伪用户)
su # switch user
exit # 退出至上一个用户
who # 当前所有用户列表
who am i # 筛选当前用户信息
whoami
sudo # /etc/sudoers new_user ALL=(ALL) ALL ; 改进: new_user ALL=(ALL) 。组也可以设置 使用%开头
userdel
groupadd # /etc/group
usermod -g group_name user_name
groupmod -n new_group_name old_group_name
groupdel group_name
# wheel 管理员组
[root@hadoop001 scripts]# mesg
is y
[root@hadoop001 scripts]# who -T # 查看开启情况
hadoop ? :0 2023-05-23 22:46 (:0)
hadoop + pts/0 2023-05-23 22:49 (:0)
root + pts/1 2023-05-30 01:12 (desktop-3nbdak0.mshome.net)
mesg n # 关闭mesg
mesg y # 开启mesg
[root@hadoop001 scripts]# who -T
hadoop ? :0 2023-05-23 22:46 (:0)
hadoop + pts/0 2023-05-23 22:49 (:0)
root + pts/1 2023-05-30 01:12 (desktop-3nbdak0.mshome.net)
[root@hadoop001 scripts]# write hadoop pts/0
ffd
#!/bin/bash
# user is logining?
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
if [ -z $login_user ]
then
echo "no user online"
exit
fi
is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ $is_allowed != "+" ]
then
echo "user:$1 not allowed"
exit
fi
if [ -z $2 ]
then
echo "no message send"
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 "send fail"
else
echo "send success"
fi
文件管理
ll # 显示目录链接为2,因为目录下有./..
chmod [{ugoa}{+-=}{rwx}] file_name
chmod [mode=421] file_name
chmod -R 777 file_name # 递归
chown
chgrp
find [range] [option]
option:name/user/size(b/c/w/k/M/G) # +10M 大于10M
locate # 利用事先建立的系统中所有文件名称及路径的locate数据库实现快速定位文件,无需遍历,速度快,但是依赖locate更新(updatedb)
which command_name
whereis command_name
grep [-n] target file_name
command | grep target # 联合使用
wc # word count, 行数 单词数 字节数 文件名
压缩
gzip/gunzip # 只能压缩文件,不能压缩目录;一个文件对应一个压缩文件;不保留原文件
zip [-r] # 可压缩目录
unzip [-d] # 可指定目录
tar [option] x.tar(x.tar.gz) files_name
-c 产生.tar打包文件
-v 显示详细信息
-f 指定压缩后的文件名
-z 打包同时压缩
-x 解包.tar
-C 解压到指定目录
磁盘管理
du # disk usage
-h
-a # 不仅查看子目录大小,还要包括文件
-c 显示所有文件和子目录大小,显示总和
-s 仅显示总和
--max-depth=n # 指定统计子目录的深度
du -sh / # 不能显示所有的,只显示/分区
ls -lh # 仅统计文件夹本身大小,不会递归
df # disk free
# /dev/shm 共享内存空间(swap)
free -h # 查看内存
lsblk # 查看设备挂载情况, sda(sata、SCSI) / hda(IDE硬盘) / vda(虚拟化设备)
-f 显示文件系统类型
# UUID 系统为每个分区创建的唯一标识符
# SCSI 小型计算机接口,一般在服务器中使用
# SATA 串行ATA
mount/umount
mount [-t vfstype] [-o options] device mount_dir
# /etc/fstab # 所有设备挂载信息, 最后两个值(kdump(是否备份) 检查优先级(检查和修复文件系统优先级))
fsck # 检查和修复文件系统
fdisk -l # 查看硬盘分区详情,root
fdisk disk_name # 对新增硬盘进行分区操作, root,最多4个主分区,n个扩展分区
fdisk /dev/sdb
lsblk -f # 查看文件系统类型
mkfs -t xfs /dev/sdb1
mount /dev/sdb1 /home/hadoop/
软件安装
# centos7
yum install software_name
RPM(Redhat Package Manager)
RPM包名称
Apache-1.3.23-11.i386.rpm
软件名-软件版本号(1.3.23-11).硬件平台(i386).扩展名(rpm)
rpm -qa # 查询所有安装的rpm包
rpm -qi package_name
rpm -e package # 卸载
rpm -e --nodeps package # 不检查依赖
rpm -i package
rpm -ivh package
mount /dev/cdrom /run/media
sudo mount /dev/cdrom /run/media
cd /run/media/
cd Packages/
ls | grep firefox
sudo rpm -ivh firefox-68.10.0-1.el7.centos.x86_64.rpm
rpm -qi firefox
YUM(Yellow dog Updater, Modify)
基于RPM,可以自动处理依赖关系
yum [option] [para]
-y # 全部yes
# para
install
update
check-update
remove
list
clean
deplist # 显示依赖关系
修改YUM源
yum install wget
# /etc/yum.repos.d/CentOS-Base.repo
wget https://*** # 获取某个源
当前还没用到
命令解释器
cat /etc/shells # 查看当前系统支持的shell,一般默认bash shell(RedHat系),dash(debian系)
echo $SHELL
开头
#!/bin/bash
执行方式
source x.sh # source built-in
bash x.sh
# 添加执行权限后
./x.sh # 相对路径
/x/.../x.sh # 绝对路径
# 错误用法
x.sh # 该方式会认为是命令
子shell中的变量,父shell不可见
点击ctrl+s后,界面会卡住,此时可以执行ctrl+d脱离此状态
系统预定义变量
$HOME
$PWD
$SHELL
$USER
显示当前shell所有变量
set
显示当前全局变量
env
查看变量
printenv var_name
其他示例
ls $HOME
自定义变量
var_name=val
unset var_name
readonly var_name # 不能unset
var_name="hello, world" # 单引号也可以
[hadoop@hadoop001 Documents]$ my_var='hell woo'
[hadoop@hadoop001 Documents]$ env | grep my_var
[hadoop@hadoop001 Documents]$ set | grep my_var
my_var='hell woo'
[hadoop@hadoop001 Documents]$ unset my_var
父bash中定义的变量,在子bash中不可见,除非全局变量
var_name=xxx
export var_name # 声明全局变量,提升,在这之前要定义变量
bash # 进入子shell
echo $var_name
子shell修改全局变量,仅在子shell中生效
export my_var
# x.sh中内容
#!/bin/bash
echo $my_var
source x.sh # 可以输出,在当前shell中执行
./x.sh # 可以输出,因为是全局变量
# x.sh中新增变量(非全局)
echo $new_var
./x.sh # new_var不输出
source x.sh # 可以输出new_var
. x.sh # 可以输出new_var
自定义用小写更合适,区别系统变量(大写)
变量名称可以由字母、数字和下划线组成,不能以数字开头,环境变量名建议大写
等号两侧不能有空格
bash中,默认字符串
my_var=1+5 # 按字符串形式
my_var=$((1+5)) # 按数值
my_var=$[1+5] # 按数值
[hadoop@hadoop001 Documents]$ readonly rb_var=5
[hadoop@hadoop001 Documents]$ echo $rb_var
5
[hadoop@hadoop001 Documents]$ rb_var=4
-bash: rb_var: readonly variable
# 删除只读变量方法
$ readonly PI=3.14
$ unset PI
-bash: unset: PI: cannot unset: readonly variable
$ cat << EOF| sudo gdb
attach $$
call unbind_variable("PI")
detach
EOF
$ echo $PI
直接执行x.sh的方法
mv x.sh /bin/ # 不推荐
PATH=$PATH:current_path
特殊变量
$n
#!/bin/bash
echo "=====$n======" # 不建议,双引号下会认为$n是特殊变量
echo '======$n====='
echo $0 # 脚本名字
echo $1 # 第一个参数
echo $2 # 第二个参数
echo $# # 参数个数
echo $* # 命令行所有参数,将所有参数看作一个整体
echo $@ # 命令行所有参数,区分对待,类似[p1, p2, p3]
echo $? # 最后一次命令返回值
shell不是高级语言,所以没法直接识别1+2等
expr 1 + 2 # 要有空格
expr 5 \* 2
$((1+2))
$[2+2]
命令替换
a=$(expr 5 \* 2)
echo $a
b=`expr 5 \* 3`
echo $b
#!/bin/bash
sum=$[$1 + $2]
echo sum=$sum
条件判断
[root@hadoop001 ~]# a=hello
[root@hadoop001 ~]# test $a = hello
[root@hadoop001 ~]# echo $?
0
# 另一种形式
[ condition ] # 前后要有空格
[ a = hello ] # =两端有空格,若都无空格,一定认为是真
echo $?
[ ] # 认为是假
[ a = b ] # 与高级语言==不同
[ a != b ] # 不支持>, < 具体逻辑实现: -gt, -ge等
[ -r x.sh ]
[ -x x.sh ]
&& # 逻辑与,为真则继续执行
|| # 逻辑或,为假则继续执行
系统函数
basename [string/pathname][suffix] # basename 会删除所有前缀,将字符串显示出来,指定后缀后,可以去掉后缀
dirname [absolute_path]
$0 # 绝对路径,如果只想显示文件名,可以使用$(basename $0) 或者 $(basename $0 .sh)
$(cd $(dirname $0); pwd)
#!/bin/bash
filename="$1"_log_$(date +%s) # 命令替换
echo $filename
自定义函数
[ function ] function_name[()] # []内可省略
{
Action;
[return int;]
}
# 必须在调用函数之前声明函数
# shell脚本逐行执行
# 函数返回值只能通过$?系统变量获得,如果定义函数时不加return,会返回最后一条命令运行结果,返回值范围(0-255)
#!/bin/bash
function add()
{
s=$[ $1 + $2 ]
echo $s
}
read -p "Enter first int: " a
read -p "Enter second int: " b
sum=$(add $a $b)
echo $sum
#!/bin/bash
# first, judge para num
if [ $# -ne 1 ]
then
echo "para not enough"
exit
fi
# second, get dir from para
if [ -d $1 ]
then
echo "dirname valid"
else
echo "dirname invalid"
exit
fi
# third,
DIR_NAME=$(basename $1)
DIR_PATH=$( cd $(dirname $1); pwd)
DATE=$(date +%y%m%d)
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DST=/root/archive/$FILE
echo "begin archive"
tar -czf $DST $DIR_PATH/$DIR_NAME
if [ $? -eq 0 ]
then
echo "archive success"
else
echo "archive fail"
fi
exit
# 执行结果
[root@hadoop001 scripts]# ./archive.sh ../scripts/
dirname valid
begin archive
tar: Removing leading `/' from member names
archive success
[root@hadoop001 scripts]# ll ../archive/
total 8
-rw-r--r--. 1 root root 659 May 28 22:26 archive_scripts_230528.tar.gz
-rw-r--r--. 1 root root 666 May 28 22:25 archive_scripts+230528.tar.gz
正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。
常用处理工具:grep,sed,awk等
^ # 匹配某个开头的一行
cat /etc/passwd | grep ^a
$ # 匹配某个结尾的一行
cat /etc/passwd | grep t$
^xxx$ #全匹配
^$ # 匹配空行
grep -n ^$ # 显示空行号
. # 匹配一个任意字符
grep r..t
* # 某个字符出现任意多次,0-n,一般不单独出现
grep .* # 任意字符串
grep ^a.*bash$
grep ^a.*var.*in$
? # 某个字符出现任意多次,1-n
[] # 匹配中间的字符
grep [1,2] # 等价grep [12]
grep [1-4]
grep '\$' # 匹配$, 转义
grep '/\$' # 匹配/$
grep -E a{2} # 扩展规则,a匹配两次
echo "15033333333" | grep -E ^1[358][0-9]{9} # -E 显式声明扩展规则
文本处理
cut [option] filename
-f # 列号
-d # 分隔符,默认'\t'
-c # 按字符进行切割,后面加n表示取第几列
cut -d " " -f 1 cut.txt
[root@hadoop001 scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,7
root:/root:/bin/bash
hadoop:/home/hadoop:/bin/bash
add1:/home/add1:/bin/bash
hadoop002:/home/hadoop002:/bin/bash
hadoop003:/home/hadoop003:/bin/bash
cat /etc/passwd | grep bash$ | cut -d ":" -f 6- # 第6列之后都要
ifconfig | grep netmask | cut -d " " -f 10
awk
原名:gawk, gnu awk
文本分析工具,逐行读入,以空格为默认分隔符将每行切开
awk [option] '/pattern1/{action1} /pattern2/{action2}...' filename
-F 指定输入文件分隔符
-v 复制一个用户自定义变量
# 是不是有-f???
cat /etc/passwd | grep ^root | cut -d ":" -f 7
# 等价形式,同时搞定行和列
cat /etc/passwd | awk -F ":" '/^root/{print $7}'
# 改进版
cat /etc/passwd | awk -F ":" '/^root/{print $1","$7}'
cat /etc/passwd | awk -F ":" '{print $1","$7}'
cat /etc/passwd | awk -F ":" 'BEGIN{print "user, shell"} {print $1","$7} END{print "end, lalala"}'
cat /etc/passwd | awk -F ":" '{print $3+1}'
cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}'
内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数(行号) |
NF | 浏览记录的域的个数(切割后,列的个数) |
cat /etc/passwd | awk -F ":" '{print "filename: "FILENAME" line_no: "NR" col: "NF}'
filename: - line_no: 41 col: 7 # -代表管道
# ...
filename: - line_no: 47 col: 7
ifconfig | grep -n ^$ # 有多余冒号
ifconfig | awk '/^$/{print NR}'
ifconfig | awk '/netmask/{print $2}' # 优于grep