常用命令

头像

命令

命令说明示例
ldd查看程序依赖的动态库ldd /usr/bin/python
strings查看二进制文件中的字符串strings binaryfile

三剑客

命令说明
grep使用正则表达式搜索文本,并把匹配的行打印出来,是强大的文本搜索工具
sed用于编辑匹配到的文本,是一种流编辑器
awk能够对文本进行复杂的格式处理,是一种处理文本的语言

grep

# --color 表示高亮我们查找的字符串
# -n 显示行号
# -c 只显示统计行号
# -v 表示反查
# -E 扩展正则表达式。等价于egrep。(另外fgrep是完全不支持正则)
# 
# -i 表示不区分大小写
# -w "word" 准确匹配某个词
# 
# -A [N] 表示除了显示匹配行之外,后面的N行也同时显示。after
# -B [N] 表示除了显示匹配行之外,前面的N行也同时显示。before
# -C [N] 相当于-A和-B同时起作用
# 

# 查找含有
grep -n "orig" /etc/passwd

# 扩展正则表达式的应用
cat /etc/passwd | grep -E "(root|orig)"

# 从大量的文件中找出含有特定字符的文件
grep -n "orig" *.txt

# ------------------------------
# 基础正则
'^'   '&'   '.'   '*'   '['   ']'
# 扩展正则
'('   ')'   '{'   '}'   '?'   '+'   '|'
# ? 0-1
# + 1-N

sed

# -n 仅仅显示sed后的结果
# -i 直接修改 (默认只是输出到终端)
# -r 扩展正则表达式 (默认是基础正则表达式)

# 【动作说明】
# a 追加,一行内容到第n行后,例如sed '2a hello'
# c 替换,第n1,n2之间的行, 例如sed '1,3c qwer'
# d 删除,第n1,n2之间的行, 例如sed '1,3d'
# p 打印,第n1,n2之间的行, 例如sed -n '1,3p'
# s 替换,可以搭配正则表达式。格式:'s/src/des/'
# ------------------------------

# 只显示第2-4行
cat /etc/passwd | sed -n '2,4p'

# 删除第2-47行
nl /etc/passwd | sed '2,47d'

# 给第2行追加内容
cat 1.txt | sed '2a hello world!'

# g表示全局,即替换所有匹配的字符串
# 如果不加g,则只替换第一个匹配的字符串
echo "hello world! hello everyone!" | sed 's/hello/A/g'

# 从第2行到结束,如果有A,则替换成hi
sed '2,$ s/A/hi/g' a.txt

awk

通过指定格式符,将文本分成几段处理

# 基本格式
awk '{pattern + action}' <file>

# 【动作说明】
# $0 表示当前整行
# $n 表示第n个字段
# NR 表示当前读到的行数
# NF 表示当前被分割的列数。例:NF-1表示倒数第2个字段
# ------------------------------

# 取出登录的用户名和IP
last -n 10 | awk '{print $1 \t $3}'

# 取出登录的用户名和IP,并显示行号和每行的总字段数
last -n 5 | awk '{print $1 "\t" $3 "\t line:" NR "\t columes:" NF}'

# pattern条件判断
awk '$2 < 10 {print $0}' a.txt

# ------------------------------
# 指定分隔符,默认是空格
ls /dev/sd* > sd.txt
cat sd.txt | awk -F '/' '{print $3}'            # 方式1
cat sd.txt | awk  'BEGIN {FS="/"} {print $3}'   #方式2

帮助

命令说明示例
man显示命令的手册页man ls
info显示命令的帮助信息info ls

man

帮助文件通常在目录/usr/share/man下

代号系统内核可以调用的函数或者工具
1.用户在shell环境中可以操作的命令或者可执行文件
2.系统内核可以调用的函数或者工具
3.常用函数库,大部分为C库
4.设备文件说明,通常是/dev下的文件
5.配置文件或者某些文件的格式
6.游戏
7.惯例与协议,例如linux文件系统,网络协议,ASCII code等的说明
8.系统管理员可用的管理命令
9.与Kernel有关的文件
man open
# 查看open的帮助

man -f printf
# 标注了printf在不同的page中的含义。可以取得命令printf更多的信息,方便直接选择,例如man 3 printf

# 所有NAME含有scanf的都显示
man -k scanf

曾经遇到的问题

# whatis: bad fetch on multi key printf   1
# whatis: index cache /var/cache/man/index.db corrupt
# 若遇到以上问题,则可以采用 mandb -c 来重新创建数据库

# 若通过man找不到常用函数
sudo apt-get install glibc-doc
sudo apt-get install manpages-posix-dev     # 常用

# 中文文档,谁看谁爽!
# 比如:man 2 open; man cp等
sudo apt-get install manpages-zh

目录操作

命令说明示例
cd切换目录cd /home/user
pwd打印当前目录pwd
basename获取路径的最后的文件名basename /home/user
dirname获取路径的目录名dirname /home/user

cd

# 回到上一次工作目录
cd -

# 回到用户根目录
cd ~

pwd

# 若加上-P参数,则表示当前实际目录(即不考虑链接文件的作用了,显示实际目录)
pwd -P

文件操作

命令说明示例
touch创建空文件touch file1.txt
mkdir创建目录mkdir dir1
ls显示文件信息ls -ahil
rm删除文件rm file1.txt
rmdir删除空目录rmdir dir1
cp复制文件cp file1.txt file2.txt
mv移动文件mv file1.txt file2.txt
rename批量修改文件名rename -n 's/^/001_/' *.c
ln创建链接文件ln -s file1.txt file2.txt
file显示文件类型file file1.txt
wc统计文件行数、单词数和字符数wc file1.txt
diff比较文件内容差异diff file1.txt file2.txt
patch打补丁patch -p0 < patchfile

cp

# -p 和 -a 都可以顺带将文件属性一并复制
cp -p mian.c test.c
cp -a mian.c test.c

# hard_link 硬链接
cp -l a.out demo.out
# symbolic_link 符号链接
cp -s demo.out demo

# 递归复制
cp -r demo ./

ln

# hard link
ln 源文件 目标文件

# sysmbolic link
ln -s 源文件 目标文件

mkdir

# 若加上该参数表示,递归陈创建
mkdir -p demo/lib

# 若加上-m参数,则可以在创建目录的同时,修改其权限
mkdir -m 755 demo

rename

可以调用perl正则表达式。可以实现批量文件名修改

# -n 仅仅将可能出现的修改结果显示出来
rename -n 's/[c]$/bak/' *.c # 将*.c文件全部修改为*.bak
rename -n 's/$/.bak/' *.c   #在c文件尾部追加.bak后缀(此时已经变为.bak文件)
rename -n 's/^/001_/' *.c   #给所有的c文件,添加001_前缀

rm

# -i 删除前提示是否删除
rm -i test.c

rmdir

# 强制删除test目录,无论其下是否有其他文件
rmdir -r test

touch

除了创建文件之外,还有修改文件的时间属性(内容修改modification time即mtime,访问时间access time即atime,状态时间(诸如文件权限的改变)

# 创建test.txt文件,若文件存在,则修改其时间属性(为当前时间)
touch test.txt

# modification time (mtime)
# status time (ctime)  例如文件属性发生改变时,会改变此值
# access time (atime)  文件内容被取用,例如cat等指令

wc

# 统计当前文件夹下所有c文件的行数
find * -name "*.c" | xargs wc -l

文本操作

命令说明示例
cat连接文件并打印到标准输出设备上cat file1.txt > file2.txt
tac从最后一行开始连接文件并打印到标准输出设备上tac file1.txt > file2.txt
head显示文件头几行head -n 5 file1.txt
tail显示文件尾几行tail -n 5 file1.txt
more分页显示文件内容more file1.txt
less分页显示文件内容,支持上下键翻页less file1.txt
nl显示文本和行号nl file1.txt
od以二进制的方式读取文件内容od -t xCc file1.txt
nano文本编辑器nano file1.txt
vim文本编辑器vim file1.txt

重定向

项目说明
标准输入stdin代码为0
<将内容写入到标准输入中,直到CTRL+D结束
<<将内容追加到标准输入中,直到特定字符串结束
标准输出stdout代码为1
>覆盖正确的数据到文件或设备上
>>追加正确的数据到文件或设备上
标准错误stderr代码为2
2>覆盖错误的数据到文件或设备上
2>>追加错误的数据到文件或设备上
# 将键盘输入的内容,写入到1.txt文件中。"CRTL+D"结束
cat > 1.txt

# 将~/.bashrc文件内容写入到1.txt文件中
cat > 1.txt < ~/.bashrc

# 一直输到eof为止,不用CTRL+D结束了
cat > 1.txt << "eof"

cat

# 显示行号
cat -n main.c

# 将tab显示为^I
cat -I main.c

od

od -t xCc test.txt
od -t x1c test.txt

文件查找

命令说明示例
which显示可执行文件的路径which gcc
whereis显示文件路径whereis gcc
locate显示文件路径locate gcc
find搜索目录层次结构中的文件find . -name main.c

find

# 表示搜索当前目录和其子目录下的所有c文件
find -name *.c

# 查找当前目录下,在24小时内修改过的文件
find . -mtime 0 (若是3则表示3天前的24小时内)
# 查找小于等于3天时间内的被修改的文件(注意和1.的区别)
find . -mtime -3
# 表示大于3天时间的被修改的文件(注意和2.的区别)
find . -mtime +3


# 在shell文件中查找比当前目录还新的文件
find ../shell/ -newer .
# 在当前文件下查找apaki用户的文件
find . -user apaki
# 在当前文件下查找aston用户的文件
find . -groud aston

# 查找文件所有者不在/etc/passwd中的文件
find . -nouser
# 查找文件所属组不再/etc/group中的文件
find . -nogroup


# 查找当前目录文件类型为link的文件
find . -type l
# 大于100Bytes的文件,c表示Byte,k表示kB
find . -size +100c


# ------------------------------
# -exec 后接commond来处理查找到的结果
# ------------------------------

# 该命令表示,在当前目录下找到名称为ubuntu的文件/夹,并ls
find -name ubuntu -exec ls -l {} \;

# 在目录ubuntu/ 下找到所有后缀为md的文件,并cat
find ubuntu/ -name *.md -exec cat {} \; 

# 表示将当前..和.. .c文件全部删除
find -name *.c  -exec rm {} \;

文件属性

命令说明示例
file显示文件类型file file1.txt
lsattr查看文件的隐藏属性lsattr a.txt
chattr设置文件的隐藏属性chattr +i a.txt

基础

相关信息的存储文件

  1. etc/passwd 用户账户
  2. etc/shadow 用户密码
  3. etc/group 用户组

关于权限的理解

  1. 文件的权限针对的是它的内容
  2. 删除文件的权限,不在于它本身的权限,而在于其所在的文件夹(文件相当于文件夹的内容)

文件属性

属性含义
r读取
w编辑、修改文件内容
x被系统执行

文件夹属性

属性含义
r查询该目录下的文件名,诸如ls命令
w修改目录结构列表,例如新建、删除、命名、移动文件
x用户进入该目录进行工作的权限

读写执行的权限,本质上都是针对“内容”的(文件夹的内容不就是其下的文件吗)

chattr

设置文件的隐藏属性

chattr +i a.txt     # 文件a.txt不能被删除,root也不行
chattr +a a.txt     # 文件a.txt仅仅可以追加,但不能删除和修改内容

file

文件种类

  1. [-] 普通文件regular file(纯文本文件ascii,二进制文件binary,数据格式文件data)
  2. [d] 目录directory
  3. [l] 链接文件link
  4. [b] 块设备文件 block devie
  5. [c] 字符设备文件 character device
  6. [s] 套接字socket
  7. [p] 管道FIFO/pipe

lsattr

查看文件的隐藏属性

  • 文件的特殊权限

    若出现大S或者大T,则表示对应位置处没有x权限

    • SUID

      小s标志,出现在owner上,覆盖掉x权限

      • 仅仅对二进制程序有效
      • 执行者对该程序有x的可执行权限
      • 在该程序的运行过程中生效

        则执行者会拥有该程序所有者的权限,例如 passwd 程序

    • SGID

      小s标志,出现在group上,覆盖掉x权限

      • 针对文件
        • 对二进制程序有效
        • 执行者需要具备x权限
        • 在运行过程中有效

          执行者将获得该程序用户组的支持

      • 针对目录
        • 用于有r和x权限

          用户在该目录下,有效用户组变为该目录的用户组

        • 若用户具有w权限

          则新建文件的用户组和该目录的用户组一致

    • SBIT

      小t标志,出现在other上,覆盖掉t权限。仅对目录有效,对文件现在已经无效

      • 用户对目录拥有w和x权限

        创建的文件/目录,仅有自己(和root,嘿嘿也可以不用提root)才能删除

权限管理

命令说明示例
chown改变文件所有者chown user file1.txt
chgrp改变文件所属组chgrp group file1.txt
chmod改变文件权限chmod 755 file1.txt
umask显示文件权限掩码umask

chmod

修改文件权限

chmod 744 main.out
chmod -R 777 test   # -R表示递归

umask

# linux下 umask默认022
# 可以通过.bashrc或者/etc/profile来修改

umask -S #用符合的形式显示了默认权限

打包压缩

命令说明示例
tartar -jcv -f filename.tar.bz2 被压缩的文件或者目录

tar

# -c 新建打包文件
# -x 解包/解压缩文件
# -v 压缩/解压缩过程中显示文件
# -t 显示打包文件中的内容
# -j 指定bzip2进行压缩,常见*.tar.bz2
# -z 指定gzip进行压缩,常见*.tar.gz
# -C 指定解压目录
# -f 指定文件名

# 打包
tar -jcv -f filename.tar.bz2 被压缩的文件或者目录
# 解压
tar -jxv -f filename.tar.bz2 -C 欲解压的目录
# 查看文件内容
tar -jtv -f filename.tar.bz2

网络操作

命令说明示例
ping测试网络连通性ping -c 5 -w 2 www.baidu.com
netstat查看网络状态netstat -tuln
ss查看网络状态ss -tuln
wget下载文件wget http://example.com/file.zip
ifconfig查看网络信息ifconfig enp3s0
ip显示网络信息ip addr
arp查看arp信息arp -a
route查看和配置路由信息route -n
traceroute查看路由信息traceroute www.baidu.com
mtr查看网络状态mtr www.baidu.com
dig查询DNS信息dig www.baidu.com
host查询DNS信息host www.baidu.com
nslookup查询DNS信息nslookup www.baidu.com
iptables配置防火墙iptables -A INPUT -p tcp --dport 80 -j ACCEPT
nmap扫描网络nmap -sP 192.168.0.0/24
tcpdump抓包tcpdump -i enp3s0 host 192.168.0.1

ip

# 配置网络信息
sudo ip addr add 192.168.0.1/24 dev enp3s0

# 启用网络
sudo ip link set enp3s0 up
# 禁用网络
sudo ip link set enp3s0 down

# 显示路由
sudo ip route show

iptables

# 添加防火墙规则
# 从特定IP访问本机22端口
sudo iptables -A INPUT -s tcp 192.168.1.100 -p tcp --dport 22 -j ACCEPT

# 删除防火墙规则
sudo iptables -P INPUT DROP

# 保存防火墙规则
sudo service iptables save

netstat

netstat -tuln
# -t 显示tcp协议
# -u 显示udp协议
# -l 显示监听状态
# -n 显示端口号
# -r 显示路由信息
# -i 显示网络统计信息

nmap

# 指定端口范围扫描
nmap -p 1-100 www.baidu.com
# 指定扫描技术
nmap -sS www.baidu.com  #tcp syn
# 输出扫描结果
nmap -oN scan.txt www.baidu.com
# 探测服务版本
nmap -sV 192.168.0.1

route

# 添加路由
sudo route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.0.1
# 删除路由
sudo route del -net 192.168.2.0 netmask 255.255.25
# 添加默认网关
sudo route add default gw 192.168.0.1

tcpdump

# 抓包
tcpdump -i enp3s0
# 指定抓包过滤条件
tcpdump -i enp3s0 host 192.168.0.1
# 指定抓包的协议和端口
tcpdump -i enp3s0 host 192.168.0.1 and port 80
# 保存抓包结果
tcpdump -r capture.pcap

远程操作

命令说明示例
ssh远程登录ssh user@host
scp远程拷贝scp file user@host:/home/user

系统信息

命令说明示例
uname -a查看全部信息uname -a
whoami显示当前用户名whoami
who查看当前用户who
w查看当前用户w

系统上电

命令说明示例
poweroff关机poweroff
halt关机halt
reboot重启reboot
shutdown关机shutdown -h now
init关机init 0

init

|代号  |含义
|:---:|:---:
|0    |关机
|1    |纯命令行
|5    |含有图形界面
|6    |重启系统

系统备份

命令说明示例
dump备份dump -0aj -f /home/user.backup /home/user
restore还原restore -if /home/user.backup
mkisofs创建iso文件mkisofs -o /home/user.iso /home
cdrecord刻录光盘cdrecord -v -eject /home/user.iso
cpio备份文件cpio -pvd /home > /home/user.backup

磁盘操作

命令说明示例
dd磁盘拷贝dd if=/dev/sda of=/dev/sdb bs=1M count=512
df查看磁盘空间使用情况df -h
du查看目录大小du -sh /home/user
dumpe2fs显示ext2/3/4文件系统信息dumpe2fs /dev/sda1
fdisk分区工具fdisk /dev/sda
mkfs格式化文件系统mkfs -t ext4 /dev/sda1
mkfs.ext4格式化文件系统mkfs.ext4 /dev/sda1
mknod创建设备节点mknod /dev/sda1 b 8 0
mount挂载文件系统mount /dev/sda1 /mnt
umount卸载文件系统umount /dev/sda1
parted分区工具parted /dev/sda
partprobe更新分区表partprobe /dev/sda
sync数据同步写入磁盘sync
badblocks检查坏块badblocks -s /dev/sda1
fsck检查文件系统fsck /dev/sda1
free显示内存使用情况free -m
mkswap创建交换分区mkswap /dev/sda7
swapon启用交换分区swapon /dev/sda7
swapoff禁用交换分区swapoff /dev/sda7
  • 查看系统已加载的文件系统: cat /proc/filesystems

  • Linux读取文件系统通过VFS(Virtual File System)来实现,VFS是Linux内核中的一个文件系统管理模块,它为上层应用提供统一的文件访问接口。

  • 常见设备对应关系

    设备名设备类型
    fd软驱设备
    hdIDE 设备
    sdSCSI设备
    sr光盘设备
    nvmeM2设备

fdisk

# fdisk 使用教程
## 1. 磁盘分区

## 2. 磁盘扩容

mknod

# mknod 设备名 类型 主设备号 辅设备号
# c 字符设备
# b 块设备
# p 管道
mknod /dev/sda1 b 8 0

mkfs

mkfs -t vfat /dev/sdb2

mount

# U盘的挂载
mount -t vfat /dev/sdb4 /media/orig/upan
umount /media/orig/upan

parted

# 查看磁盘分区情况
parted /dev/sda print
# 创建分区
parted /dev/sda mkpart primary 0% 100%    # 创建主分区
parted /dev/sda mkpart extended 100%      # 创建扩展分区
parted /dev/sda mkpart logical ext4 8G 10G # 创建逻辑分区
# 删除分区
parted /dev/sda rm 4

进程管理

命令说明示例
ps进程查看ps -aux
kill杀进程kill -9 12345
killall杀进程killall -9 sshd
jobs显示后台任务jobs -l
fg将后台任务调至前台fg %1
bg将后台任务调至后台bg %1
top显示进程信息top

用户管理

命令说明示例
users显示当前用户users
useradd添加用户useradd -d /home/orig -m orig
userdel删除用户userdel orig
usermod修改用户usermod -d /home/orig orig
passwd修改密码passwd orig
su切换用户su - orig
sudo切换用户sudo -u orig /bin/bash
id显示用户信息id orig
groups显示用户所属组groups orig
groupadd添加用户组groupadd orig
groupdel删除用户组groupdel orig
groupmod修改用户组groupmod -n orig neworig
gpasswd修改用户组密码gpasswd -a orig neworig
newgrp切换用户组newgrp orig
finger显示用户信息finger orig
chfn修改用户信息chfn orig
chage修改用户密码信息chage -d 0 orig
chsh修改用户shellchsh -s /bin/bash orig
chfn修改用户信息chfn orig
chpasswd修改用户密码chpasswd <<EOF
orig:123456<EOF

/etc/passwd文件结构说明如下(按顺序,冒号分割)

字段说明
1用户名
2密码
3用户ID
4组ID
5用户信息
6用户主目录
7用户默认shell

/etc/shadow文件结构说明如下(按顺序,冒号分割)

字段说明
1用户名
2密码
3最近修改密码时间
4密码最小时间间隔
5密码最大时间间隔
6密码到期前警告时间
7密码到期后宽限时间
8密码到期后账号禁用时间
9保留字段

/etc/group文件结构说明如下(按顺序,冒号分割)

字段说明
1用户组名称
2用户组密码
3GID
4组用户列表(逗号隔开)

useradd

# 显示默认值
useradd -D
# 结果如下:
# GROUP=100         # 默认用户组
# HOME=/home        # 默认用户主目录
# INACTIVE=-1       # 密码过期时间
# EXPIRE=           # 账号过期时间
# SHELL=/bin/sh     # 默认shell
# SKEL=/etc/skel    # 默认用户主目录模板
# CREATE_MAIL_SPOOL=no  # 创建邮件文件


usermod

修改用户账号的各项设定

# 更改用户登录目录
usermod -d /home/orig orig
# 更改用户登录shell
usermod -s /bin/bash orig
# 更改用户ID
usermod -u 1000 orig
# 修改用户所归属的附加群组
usermod -G orig root 

其他

命令说明示例
data显示日期和时间date "+%Y/%m/%d %H:%M:%S"
cal显示日历cal 5 2024
bc计算器echo "2+3" | bc

cal

显示日历

cal 7 2018  #显示2018年7月的日历
cal -A 1    #显示当前月和之后的1个月
cal -B 2    #显示当前月和之前的2个月

终端

快捷键说明
CTRL + C终止当前进程
CTRL + D退出当前终端
CTRL + S暂停当前进程
CTRL + Q恢复当前进程
CTRL + U删除当前行
CTRL + R搜索历史命令
CTRL + L清屏

shell

命令说明示例
echo显示变量值echo $HOME
env查看环境变量env
exit退出当前shellexit
export导出变量export var
locale显示语言环境locale
set设置变量/查看所有变量set -o vi
type显示命令类型type -a ls
unset取消变量unset var
ulimit显示/设置资源限制ulimit -a
alias创建别名alias ll='ls -l'
unalias取消别名unalias ll
history显示历史命令history
cut显示行中的指定部分cut -d: -f1 /etc/passwd
sort排序cat /etc/passwd | sort -n
uniq去除重复行cat /etc/passwd | sort -n | uniq
tee双向重定向,可以将数据流同时传输到文件和stdoutls /dev/sd* | tee sd.txt
tr转换字符echo "hello" | tr 'a-z' 'A-Z'
col格式化输出ls -l | col -b
join合并文件join -t: /etc/passwd /etc/shadow
paste合并文件cat /etc/passwd | paste -d: -s
expand转换tab为空格cat /etc/passwd | expand
split分割文件cat /etc/passwd | split -l 10 -d -a 2 passwd.
xargs执行命令ls /etc/ | xargs -n1 ls -l
printf格式化输出printf "%-10s %-8s\n" User Age

管道命令 将前一个命令的输出作为后一个命令的输入

# !!!注意变量和等号之间不能有空格

# 变量赋值
a=$HOME

# echo $var 显示 lange is en_US.UTF-8
var="lang is $LANG"

# 变量引用
cmd=$(uname -r)             # 随后echo cmd相当于调用命令uname -r
cmd="$cmd"\ $(ls)           # 在原cmd内容上累加ls命令

history

!243   # 执行历史命令中的第243条
!gcc   # 执行历史命令前向搜寻到的gcc开头的命令并执行
!!     # 执行上一条命令

# 清空历史命令
history -c

shell脚本

命令说明示例
read读取输入read var
declare声明变量declare -i var
source执行脚本(在脚本的父进程执行)source ./script.sh
echo $PATH
```bash
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# 【从头删除1】从/到:的最小匹配
echo ${PATH#/*:}
#>> /usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# 【从头删除2】从/到:的最大匹配
echo ${PATH##/*:}
#>> /snap/bin



# 【从尾删除1】
echo ${PATH%:*bin}
#>> /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

# 【从尾删除2】
echo ${PATH%%:*bin}
#>> echo ${PATH/sbin/SBIN}



# 【替换第一个】
echo ${PATH/sbin/SBIN}
#>> /usr/local/SBIN:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# 【替换全部】
echo ${PATH//sbin/SBIN}
#>> /usr/local/SBIN:/usr/local/bin:/usr/SBIN:/usr/bin:/SBIN:/bin:/usr/games:/usr/local/games:/snap/bin

脚本基础

#!/bin/bash
echo -e "this is a test script"

# 提示,并等待用户输入。超时时间20秒
read -p"please input your name:" -t 20 name

# 给新建的文件添加时间
date=$(date +%Y%m%d)
filename="${name}-${date}.txt"
touch ${filename}

# 将计算的结果添加到文件中去
echo "3*4 = "$((3 * 4)) >> ${filename}

test命令

命令说明示例
文件类型
-e文件存在-e /etc/passwd
-f文件存在且为普通文件-f /etc/passwd
-d文件存在且为目录-d /etc/passwd
-b文件存在且为块设备-b /dev/sda
-c文件存在且为字符设备-c /dev/sda
-S文件存在且为socket-S /dev/sda
-p文件存在且为FIFO-p /dev/sda
-L文件存在且为符号链接-L /dev/sda
文件权限
-r文件存在且可读-r /etc/passwd
-w文件存在且可写-w /etc/passwd
-x文件存在且可执行-x /etc/passwd
-u文件存在且SUID位设置-u /etc/passwd
-g文件存在且SGID位设置-g /etc/passwd
-k文件存在且SUID/SGID位设置-k /etc/passwd
-s文件存在且不为空-s /etc/passwd
文件比较
-nt文件1比文件2新-nt /etc/passwd /boot/grub
-ot文件1比文件2旧-ot /etc/passwd /boot/grub
-ef文件1和文件2为同一个文件-ef /etc/passwd /boot/grub
整数大小
-eq等于-eq 10 20
-ne不等于-ne 10 20
-gt大于-gt 10 20
-lt小于-lt 10 20
-ge大于等于-ge 10 20
-le小于等于-le 10 20
字符串判断
-z字符串为空-z "abc"
-n字符串不为空-n "abc"
=字符串相等"abc" = "abc"
!=字符串不相等"abc" != "abc"
多重条件判断
-atest -r file -a -w file
-otest -r file -o -w file
!! test -r file

除了上述test命令之外,也可以用[]来代替test命令

# !!! 一定要注意空格
[ -z "$HOME" ];
echo $?

[ "$HOME" == "orig" ]

默认变量

命令说明示例
$#参数个数echo $#
$*所有参数echo $*
$@所有参数echo $@
$0脚本名称echo $0
$1第一个参数echo $1
$2第二个参数echo $2
......
shift参数左移shift

条件判断

# if-else
read -p "你确定吗?(y/n)" answer
if [ "$answer" == "y" ] || [ "$answer" == "Y" ]; then
    echo "yes"
elif [ "$answer" == "n" ] || [ "$answer" == "N" ]; then
    echo "no"
else 
    echo "input error!"
fi

# case
read -p "请输入一个数字:" num
case $num in
    1) 
        echo "one" ;;
    2) 
        echo "two" ;;
    *) 
        echo "other" ;;
esac

循环

# while
num=$1
while [ "$num" -gt 0 ]; do
    echo $num
    num=$(( $num - 1 ))
    sleep 1
done

# uitl 条件成立时,终止循环。
num=5
until [ "$num" -eq 0 ]; do
    echo $num
    num=$(( $num - 1 ))
done

# for
for var in $*; do
    echo $var
done

for (( i=1; i<=3; i++ )); do
    echo $i
done

函数

函数需要放在脚本的开头,并且函数名不能和变量重名。

function print_hello() {
    echo "hello," $1 
}
print_hello "orig"

调试

参数说明
-n不执行脚本,只进行语法检查
-v执行脚本前,先将脚本内容输出到标准输出
-x执行脚本前,先将脚本内容输出到标准输出,并显示执行的命令
bash -x script.sh

环境变量

环境变量说明
HOME用户主目录
LANG语言环境变量
SHELL当前shell
HISTSIZE历史命令记录数
MAIL邮件存放目录
PATH命令搜索路径
RANDOM0~32767随机数
PS1命令行输入提示符
$当前进程号
?上个命令的返回码
OSTYPE操作系统类型
HOSTTYPE主机类型
MACHTYPE主机架构