Commands
文件与文件夹操作
文件夹操作
ls
# 查看文件夹
ls your_dir
ls -F # 显示文件类型,/:文件夹,*:可执行文件,@:链接
ls -F your_dir | grep / # 只显示文件夹
ls -F your_dir | grep -v / # 只显示文件
tree
# 以树形显示文件夹
tree
tree -L 2 # 参看目录层数2以内的文件
tree -f # 显示完整路径
tree -d # 只显示文件夹
pwd
# 显示当前目录
pwd
mkdir
# 创建文件夹
mkdir dir
mkdir -p your_dir/subdir # 创建多级文件夹
tree -fid --noreport your_dir >> your_dir.txt && mkdir tmp && cd tmp/ && mkdir -p `cat ../your_dir.txt` # 复制目录结构
touch
# 创建文件
touch your_file # 创建文件或更新文件时间戳
touch -a|-m your_file # 只更新访问|修改时间
touch -t 202102071200.00|YYYYmmddHHMM.SS # 更新为指定时间戳
cd
# 切换文件夹
cd your_dir
cd ..|~|- # 切换到父文件夹|用户文件夹|上一次文件夹
cp
# 复制文件夹
cp source target
cp -p # 保留源文件所有属性
cp -d # 保留符号链接指向
cp -r # 递归复制文件夹
cp -a # == cp -pdr
mv
# 移动文件夹
mv source target
mv source_1 source_2 source_3 target # 移动多个文件到目标文件夹
rm
# 删除
rm file
rm -rf dir # 你懂的
rename
# 重命名文件
rename .png .jpg ./* # 将所有文件的后缀由 .png 改成 .jpg
ln
# 链接
ln your_target your_link # hard link,多个文件名指向同一个索引节点(inode),只有当文件所有的硬链接都被删除时,文件才真正删除。可以通过创建硬链接防止文件误删
ln -s your_target your_link # soft/symbolic link,相当于创建快捷方式
# 查看链接具体的命令
type ll # 输出:ll is aliased to `ls -l --color=auto'
文件夹路径
basename
# 显示文件名
basename /data/dir1/file1.txt
basename /data/dir1/file1.txt .txt # 不显示后缀 .txt
dirname
# 显示路径
dirname /data/dir1/file1.txt
dirname ./file1.txt # 传入相对路径也会返回相对路径
查看文件信息
ls -l
输出的含义
1|2 |3 |4 |5| 6 | 7 | 8 | 9 | 10
-rw-rw-r-- 1 yzchen yzchen 6 Feb 7 15:23 newfile
drwxrwxr-x 2 yzchen yzchen 4096 Feb 7 15:25 subdir
- 文件(夹)类型
- 文件所属用户权限
- 文件所属用户组权限
- 其他用户权限
- 硬链接个数
- 所属用户
- 所属用户组
- 文件(夹)大小
- 修改时间
- 名称
file
查看文件类型
file file1.txt
wc
统计文件行数、字符数、字节数
wc file.txt # 分别显示文件的行数、字符数、字节数
wc -l file.txt # 显示文件的行数
wc -m file.txt # 显示文件的字符数
wc -w file.txt # 显示文件的单词数
wc -c file.txt # 显示文件的字节数
wc -L file.txt # 显示最长行的长度
who | wc -l # 查看登录系统的用户数
stat
# 查看文件时间戳
stat your_file # access time: 查看文件内容,modify time:修改文件内容,change time:修改文件名、文件内容、文件属性
查找文件
find
find . # 查找当前文件夹
find . -maxdepth 1 # 查找一级目录
# 查找所有名称为src的文件夹
find . -name src -type d
# 查找所有文件夹路径中包含test的python文件
find . -path '*/test/*.py' -type f
# 按时间查找
find . -atime -2 # 查找访问时间在2天以内的文件
find /data/ -mtime +5 # 查找修改时间在5天之前的文件
# 按名称查找
find /var/log/ -name '*.log' # 只支持"*", "?", "[]"三个通配符
find pathname -regex "pattern" # 用正则查找
# 按类型查找
find . -type d # 查找文件夹
# 取反查找
find . ! -type d # 查找非文件夹
# 按权限查找
find /data/ -perm 755
# 按大小查找
find . -size +1000c # 查找大于1000字节的文件
# 按用户查找
find . -user username
find . -group groupname
# 按文件新旧查找
find . -newer file1.txt # 查找更改时间比 file1.txt 新的文件
find . -newer file1.txt ! -newer file2.txt # 查找更改时间比 file1.txt 新的文件但比 file2.txt 旧的文件
# 对查找后的文件执行操作
find . -type f -exec ls -l {} \; # 打印查找到的文件。-exec 后面跟命令,{}指代查找到的内容
find . -type f -ok rm {} \; # -ok 与 -exec功能一样,但是在删除前会给出提示
find . -type f | xargs ls -l
find . -type f | xargs -i mv {} dir
# 对查找到的文件执行命令
# 删除全部扩展名为.tmp 的文件
find . -name '*.tmp' -exec rm {} \;
# 查找全部的 PNG 文件并将其转换为 JPG
find . -name '*.png' -exec convert {} {}.jpg \;
fd
alternative to find
,see github - fd
# 查找文件名带"foo"的
fd foo
# 正则查找文件名
fd "^foo.*"
# 查找扩展名
fd -e avi
locate
快速查找文件路径
locate pwd
locate /etc/sh* # 可以使用通配符
which
查找命令路径
which mysql
which -a mysql # 查找所有包含命令的路径匹配项
文本处理
打印
echo
# 打印内容
echo hello world
echo 'hello world'
echo "hello world"!
# 识别特殊字符
echo -e "hello\tworld"
# 输入文本到文件
echo "hello world" > file.txt
echo "hello world" >> file.txt # 追加
# 打印环境变量
echo $PATH
查看文件
cat
# 合并文件内容
cat file1.txt file2.txt > newfile.txt
# 打印文件内容
cat file.txt
# 打印多行内容
cat << EOF
hello
world
EOF
# 追加多行内容到文件尾部
cat >> file.txt << EOF
hello world.
EOF
# 清空文件内容
cat /dev/null > file.txt
# 显示行号
cat file.txt | nl
# 反向输出文件内容(按行)
tac file.txt
# 反向输出文件内容(按字)
rev file.txt
more / less
more file.txt
more -5 file.txt # 只显示5行
more +10 file.txt # 显示文件从第10行开始的内容
less file.txt
less -N file.txt # 显示行号
head / tail
head file.txt # 显示前10行
head -n 20 file.txt # 显示前20行
tail file.txt # 显示最后10行
tail -n 20 file.txt # 显示最后20行
tail -f file.txt # 实时监控文件变化
tail -F file.txt # 文件不存时不会退出,会一直等待文件生成
tailf file.txt # 与`tail -f`类似
xxd
查看二进制文件
xxd -b file.bin
xxd -u file.bin # hex格式
tee
输出重定向
ls | tee ls.txt # 屏幕打印输出的同时保存到文件中
ls | tee -a ls.txt # 屏幕打印输出的同时追加到文件中
# 主要用于输出到文件的同时,继续传输流到管道
ls -la /etc | tee content.txt | sort -r > sortted.txt
sort
排序
sort file.txt # 默认升序
sort -r file.txt # 降序排序
sort -n file.txt # 按数字大小排序
sort -u file.txt # 去除重复行
# 用-t自定义分隔符,按-k指定的列排序
sort -t " " -k 2 file.txt # 以空格为分隔符,按第二列的值排序
# 先按ip的第三段排序,再按ip的第4段排序,其中,"4.1,4,3"表示第4个字段的第一个字符开始到第三个字符结束
# 192.168.0.151 00:0F:AF:85:6C:F6
sort -n -t "." -k 3,3 -k 4.1,4.3 file.txt
uniq
去除重复行
sort file.txt | uniq # 只能去除相邻重复行,因此一般应先排序再去重
sort file.txt | uniq -c # 显示行重复的次数
sort file.txt | uniq -c | sort -rn # 按行统计次数并倒序展示
diff
比较文件
diff file1.txt file2.txt # "a"表示add,"c"表示change,"d"表示delete
diff -y file1.txt file2.txt # 并排格式输出
diff -u file1.txt file2.txt # 统一格式输出
diff dir1/ dir2/ #比较两个目录下文件的区别
vimdiff file1.txt file2.txt # 用vim打开文件对比
grep
文本过滤
# 输出包含pattern的行
grep "hello" file.txt
# 输出不包含pattern的行
grep -v "hello" file.txt
# 显示行号
grep -n "hello" file.txt
grep -n "." file.txt # 显示所有行与行号
# 不区分大小写
grep -i "hello" file.txt
# 同时过滤两种pattern
grep -E --color=auto "hello|world" file.txt
# 计算匹配pattern的行数
grep -c "hello" file.txt
# 只匹配pattern的单词,例如"female"不会被匹配
grep -w "male" file.txt
# 去除文件中的空行或含注释的行
grep -Ev "^$|#" nginx.conf
# 显示前后5行
grep -C5 "hello" file.txt
# 显示前10后5行
grep -B10 -A5 "hello" file.txt
# 匹配文本
grep -a "hello" file
egrep
等价于grep -E
,可以使用+
,?
,|
等正则语法
egrep -C 0 '(f|g)ile' check_file # 会匹配出file或gile
fgrep
等价于grep -F
,没有任何转义
fgrep -C 0 '(f|g)ile' check_file # 会匹配出(f|g)ile
rg
alternative to grep
,see github - ripgrep
# 正则搜索文件内容
rg 'fast\w+' README.md
# 查找所有使用了 requests 库的文件
rg -t py 'import requests'
# 查找所有没有写 shebang 的文件(包含隐藏文件)
rg -u --files-without-match "^#!"
# 打印匹配的统计信息(匹配的行和文件的数量)
rg --stats PATTERN
json_pp
打印漂漂的json
cat sample.json | json_pp
# utf8
cat sample.json | json_pp -json_opt pretty,utf8
修改文件
cut
截取文本中一段内容
cut -c 2-10 file.txt # 输出第2到10个字符的内容
cut -c 3- file.txt # 输出第3个字符之后的内容
cut -c -3 file.txt # 输出第3个字符之前的内容
cut -c 1,3,5-10 test.txt # 多个位置可以用逗号分隔
cut -b 2-10 file.txt # 以字节为单位分隔
cut -nb 2-10 file.txt # 以字节为单位分隔但不分隔多字节字符
cut -d 2-10 file.txt # 默认以<tab>分隔
cut -d : -f 1 file.txt # 以":"号分隔,并显示第一列
split
分割文件
split -l 10 file.txt new_ # 每10行分隔一个文件,分割文件以new_作为前缀后缀默认是字母
split -l 10 -a 3 file.txt new_ # -a指定后缀长度
split -l 10 -d file.txt new_ # -d使用数字后缀
split -b 500K -d file.txt new_file # 每500K分割一次文件
paste
按行合并文件
paste file1.txt file2.txt # 按行合并文件,以<tab>为分隔符
paste -d : file1.txt file2.txt # 以":"为分隔符
paste -s file1.txt # 将文件合并为1行
paste -s file1.txt file2.txt # 合并多个文件,每个文件为一行
join
合并两个文件具有相同key(第一个字段)的行。要求文件是排序后的。
# file1.txt | file2.txt | result
# > Jack male | > Jack 15 | Jack male 15
# > Jennie female | > Jennie 24 | Jennie female 24
# > Tom male | > Jack 12 | Tom male 12
join file1.txt file2.txt
tr
替换文本中字符
tr 'abc' 'xyz' < file.txt # 将文件中的"a"换成"x","b"换成"y","c"换成"z"
tr '[a-z]' '[A-Z]' < file.txt # 将小写全部替换成大写
tr -d 'abc' < file.txt # 将文件中的"a","b","c"字符删除
tr '[0-9]' '*' < file.txt # 将文件中的数字全部换成"*"
tr -c '[0-9]' '*' < file.txt # 将文件中的非数字全部换成"*"
sed
Stream Editor,流编辑器,可以进行文件的增删查改
# 在文件第2行之后添加文本,"a"表示追加
sed '2a hello world' file.txt
# 在文件第2行之前插入文本,"i"表示追加
sed '2i hello world' file.txt
# 在文件第2行之前插入多行文本,多行由"\n"分隔
sed '2i hello\nworld\n' file.txt
# 删除第2行,"d"表示删除
sed '2d' file.txt
# 删除第2-5行,包括第2行和第5行
sed '2,5d' file.txt
# 替换内容,用第二个"#"后的内容替换第一个"#"后的内容,"s"表示替换,"g"表示全局替换
sed 's#hello#world#g' file.txt
sed 's/hello/world/g' file.txt # 也可以用其他分隔符
# 将修改后的内容保存到原文件,"-i"表示保存
sed -i 's/hello/world/g' file.txt
# 修改文件并创建备份
sed -i.bak 's/hello/world/g' file.txt
# 打印第2行,"p"表示打印,"-n"表示取消默认输出,否则会输出全部内容
sed -n '2p' file.txt
sed -n '2,3p' file.txt # 查看第2-3行
在 Mac 上的 sed (BSD 版本) 命令格式与 linux (GNU 版本) 不一样
# in-place editing
sed -i '' 's/old/new/g' file
# in-place editing of files while creating a backup
sed -i '.bak' 's/old/new/g' file
awk
# 打印第2行,"NR"表示行号
awk 'NR==2' file.txt
# 打印每行行号,"$0"表示一整行的内容,命令要放在"{}"以内
awk '{print NR,$0}' file.txt
# 打印各行的第1、3、最后一列,"-F"表示分隔符,"$1"表示第一列,"$NF"表示最后一列
awk -F ":" '{print $1,$3,$NF}' file.txt
# 替换字符串,使用gsub函数
awk '{gsub("source","target",$0);print $0}' file.txt
编码转换
iconv
转换文件编码
iconv -f gb2312 -t utf-8 GB2312.txt # 将GB2312编码的文件转换为UTF-8编码
dos2unix
将DOS格式文件转换为UNIX格式,适用于在Windows系统下创建的文件上传到Linux系统上运行,将Windows文件中的换行符"\r\n"转换为Linux文件的换行符"\n"
dos2unix script.sh
unix2dos script.sh # 将UNIX文件转换为DOS文件
权限管理
权限管理
chmod
文件权限说明
- r:读取的权限
- w:追加、修改内容的权限
- 如果没有r权限,可以追加或覆盖
- 删除权限受父文件夹权限控制,与文件自身的权限无关
- x:执行的权限
- 通过
source
,. /
,sh
的命令也能执行 - 普通用户还必须要有r权限才能执行
- root只要有x就能执行
- root即使没有x权限,只要其他权限位有x就能执行
- 通过
文件夹权限说明
- r:浏览文件夹及其子文件夹的权限,可以
ls
- 没有x权限不能
cd
- 没有x权限不能
- w:新增、删除、修改文件夹内文件名的权限,也需要x权限配合
- 新增权限指新建文件
- 修该权限指修改文件名,而不是修改文件的权限
- x:进入文件夹的权限
- 没有r权限无法列表
- 没有w权限无法新建文件
chmod -R 755 file.txt # 递归更改权限
# 通过字母更改权限
chmod u+x file1.txt # 给user添加执行权限
chmod g+w file1.txt # 给group添加可写权限
chmod o+r file1.txt # 给other添加可读权限
chmod gu+r,o-r file.txt # 给user和group添加可读权限,给other删除可读权限
chmod a= file.txt # 给所有人(a)设置权限为空
chmod u=rwx,g=rx,o=x file.txt # "="撤销原来所有权限,然后赋予新权限
# 通过数字更改权限,r=4,w=2,x=1,-=0
chmod 000 file.txt # 撤销所有权限
chmod 751 file.txt # 分别赋予user、group、other的rwx、rx、x权限
chown
chown user file.txt # 仅更改用户
chown :group file.txt # 仅更改用户组
chown user:group file.txt # 更改用户与用户组
chown -R user:group dir # 递归更改文件夹及文件夹内文件
文件加锁
chattr / lsattr
chattr +i file1.txt # 使文件只读,即使是 root 用户也不能删除、修改、覆盖
chattr -i file1.txt # 解锁
lsattr file1.txt # 查看文件属性
文件打包与传输
文件打包
tar
# 打包并压缩(-c表示打包,-z表示压缩,-v表示显示过程,-f表示指定压缩文件名字
tar -czvf X.tar.gz dir
# 解压并解包(-x表示解包)
tar -xzvf X.tar.gz # 解压到当前目录
tar -xzvf X.tar.gz -C dir # 解压到指定文件夹
gzip / gunzip
# 压缩文件,不能应用于文件夹,通常会先用tar打包再压缩
gzip file.txt # 会删除源文件,生成file.txt.gz
# 解压
gzip -d *.gz
gunzip -d *.gz
zip / unzip
# 压缩
zip file.zip file.txt # 不会删除源文件
zip -r tmp.zip ./tmp/ # 可以压缩文件夹
# 解压
unzip tmp.zip
unzip -d /tmp tmp.zip # 解压到指定文件夹
unzip -l tmp.zip # 查看包内文件列表
文件传输
scp
# 从本地复制文件到远程
scp local_file remote_username@remote_ip:remote_folder
# 从本地复制文件夹到远程
scp -r local_folder remote_username@remote_ip:remote_folder
# 从远程复制到本地
scp root@remote_ip:/home/root/others/music /home/space/music/1.mp3
# 从远程host1到远程host2
scp -3 host1:~/file host2:~
rsync
增量同步工具
# 拉取文件夹
rsync host:/tmp/ /tmp
# 推送文件夹
rsync /tmp/ host:/tmp/
# 通过ssh模式加密传输
rsync -e 'ssh -p 22' /tmp/ host:/tmp/
# 压缩传输,-a表示以递归方式传输并保持文件属性,-z表示压缩,-v表示verbose
rsync -avz /tmp/ host:/tmp/
md5sum
md5sum test.txt # 生成文件摘要
md5sum -c md5.log # 检查文件是否有修改
系统
系统信息
/proc/*
查看系统版本
cat /proc/version
cat /etc/os-release
查看 CPU 信息
cat /proc/cpuinfo
uname
查看系统版本
uname -a # 显示系统所有信息
uname -m|i|p # 系统架构
uname -n # 主机名
uname -r # 内核发行版本号
uname -s # 内核名称
uname -v # 内核版本号
uname -o # 操作系统名称
hostname
# 显示主机名
hostname
# 显示ip地址
hostname -i
# 修改主机名
vi /etc/hostname
# 修改主机hosts解析
vi /etc/hosts
lscpu
查看 CPU 信息
lscpu
free
# 查看内存
free -h
df
查看系统磁盘空间情况,1K-blocks表示总大小,Used表示分区的使用大小,Avaliable表示可用大小,Use%表示使用百分比,Mounted on表示挂载点
df -h # 显示可读格式
df -T # 显示文件系统类型
df -i # 显示inode使用情况
du
统计文件所占硬盘空间
# 显示所有文件,包括隐藏文件和子文件夹下所有文件
du -a
# 显示当前文件夹总大小
du -s
# 换算成可读格式
du -h
# 查看指定文件夹大小
du -sh dir/
# 查看指定层级文件夹大小
du -h --max-depth=2 dir/
printenv
Print part or all of the environment
printenv
系统服务
systemctl
负责systemd系统和服务的管理,service文件一般放在/etc/systemd/system/
目录下
# 查看所有单元
systemctl list-units
systemctl list-units --all
# 查看服务状态
systemctl status mysql.service
# 操作服务
systemctl show|start|stop|restart|kill|reload mysql.service
# 设置/取消开机自动启动
systemctl enable|disable mysql.service
# 查看日志
journalctl -u mysql.service
配置示例
[Unit]
Description=Your Service Description
After=network.target
[Service]
Type=simple
ExecStart=/path/to/your/executable
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
配置说明:
- After:依赖项
- Basic Targets:
basic.target
: Basic system initialization is complete.multi-user.target
: Multi-user system is up, typical for non-graphical servers.graphical.target
: The system is fully up with a graphical user interface.
- Network-related:
network.target
: Networking is up, but it might not be fully configured.network-online.target
: Networking is up and fully configured.nss-lookup.target
: Name service switch (NSS) lookup is available.
- System Initialization:
sysinit.target
: Early system initialization completed.local-fs.target
: Local filesystems are mounted.remote-fs.target
: Remote filesystems are mounted.
- Hardware:
dev-disk-by\x2did-<device>.device
: A specific device is available.
- User Sessions:
user@.service
: User session services.getty.target
: Login prompts are ready.
- Service-specific:
- Any custom service you have defined, e.g., my-custom.service.
- Basic Targets:
- Restart: 失败时是否重试
no
on-success
: restart if it terminates successfully (exit status 0)on-failure
: restart if it terminates with a non-zero exit status
- RestartSec: 失败重试间隔
- WantedBy: It determines which target unit should include the service when the service is enabled
multi-user.target
: For non-graphical multi-user systems.graphical.target
: For systems with a graphical user interface.network-online.target
: Ensures the service starts only when the network is fully configured and available.
service
在CentOS 7中被systemctl取代
service --status-all # 显示所有服务状态
service crond start|stop|restart|status # 服务操作
/etc/init.d/crond start|stop|restart|status # 服务操作
crontab
# 查看当前用户crontab
crontab -l
# 编辑
crontab -e
# 通过命令添加 cronjob
crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -
格式:(分钟)(小时)(几号)(月份)(星期几)
# 每分钟运行
* * * * * myCommand
# 每晚21:30分运行
30 21 * * * myCommand
# 每周一上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 myCommand
# 每月1、10、22日的4:45执行
45 4 1,10,22 * * myCommand
# 每小时运行一次
* */1 * * * myCommand
# 开机时运行
@reboot myCommand
crontab在线验证
进程管理
ps / pstree
进程快照
ps axu # ax表示显示所有进程,u表示显示进程的用户
ps -ef # -e表示显示所有进程,-f表示显示额外参数
ps -u root # 显示指定用户的进程
# 显示进程树
ps axf
ps -eH
pstree
pstree -p # 显示父子进程PID
jps
查看java进程
jps
top
实时监控系统进程
top
top -a # 按使用内存排序
top -c # 显示进程完整路径
top -d 3 # 指定刷新周期为3秒
top -p 2233 # 显示指定进程信息
lsof
list open files,查看被进程打开的文件
# 显示使用文件的进程
lsof /var/log/messages
# 显示进程打开的文件
lsof -c rsyslog # 进程名
lsof -p 1277 # 进程号
# 查看指定协议、端口等信息的进程,lsof -i [4|6] [protocol][@hostname][:service|port]
lsof -i # 显示全部进程
lsof -i tcp # 显示tcp进程
lsof -i :22 # 显示端口为22的进程
lsof -i tcp:22 # 显示tcp切端口为22的进程
# 查看指定用户使用的文件
lsof -u username
strace
跟踪系统调用
strace {{program}}
strace p {{pid}}
kill / killall / pkill
# 根据进程号pid终止进程
kill -l # 列出全部信号
kill {{pid}} # 默认信号是15,结束进程
kill -9 {{pid}} # 强制结束
kill -0 {{pid}} # 检查进程是否存在
# 根据进程名终止进程
killall {{program}} # 终止进程,可以多执行几次直到没有进程被杀死
killall -w {{program}} # 等待进程被终止
killall -u {{username}} {{program}} # {终止所有归属于{{username}}用户的nginx进程}
# 根据进程名终止进程及其所有子进程
pkill {{program}}
pkill -u {{username}} # 终止用户所有进程
不同信号的差别
SIGTERM
: 请求进程优雅退出,可以被捕获或忽略SIGKILL
:强制退出,可能造成孤儿进程,不能被捕获或忽略SIGQUIT
:通过 Terminal 输入Ctrl-\
发送,请求退出,可以被捕获SIGINT
:通过 Terminal 输入Ctrl-C
发送,请求退出,可以被捕获
Jobs/fg/bg
# 查看jobs
jobs
# 在后台运行job
nohup {{command}} &
# 暂停进程并放到后台
<Ctrl-Z>
# 将进程放回前台
fg
# 将暂停的进程在后台运行
bg
shutdown
Shutdown or reboot the system
shutdown
time
计算命令所耗费的资源(CPU 时间、内存)
# time a go process
time go run main.go
# 统计:用户时间,系统时间,实际时间和最大内存占用
/usr/bin/time -f '%Uu %Ss %er %MkB %C' "$@"
硬盘管理
硬盘格式选择
FAT32 | exFAT | NTFS | |
---|---|---|---|
兼容 | Windows/Linux/MacOS | Windows/Linux/MacOS | Windows,MacOS/Linux只读 |
限制 | 文件4GB,分区8TB | 无 | 无 |
使用 | U盘 | U盘 | Windows内部盘 |
fdisk
查看连接到实例的磁盘
fdisk -l
lsblk
磁盘信息查看
lsblk -f # 显示硬盘、分区及类型
parted
parted /dev/sda print # 显示硬盘格式与分区
mkfs
创建文件系统
# 创建xfs格式的文件系统
mkfs.xfs /dev/sda
mount
挂载硬盘
mkdir /data1
mount /dev/sda1 /data1
设置开机自动挂载
修改文件/etc/fstab
UUID=11263962-9715-473f-9421-0b604e895aaa /data ext4 defaults 0 0
修改完后需要验证配置是否正确,否则重启后系统无法正常启动
sudo mount -a
umount
卸载硬盘
# 通过挂载点卸载
umount -v /data
# 通过设备名卸载
umount -v /dev/sda
如果当前shell位于要卸载的目录内,会提示设备正忙,需要退出该目录才能卸载成功
系统日志
dmesg
Display kernel messages
dmesg
journalctl
# display all log
journalctl
# view log for a specific boot
journalctl -b -1 # previous boot
journalctl -b -2 # the one before previous boot
# list boot
journalctl --list-boots
# filter by time
journalctl --since "2024-07-18 12:00:00" --until "2024-07-18 14:00:00"
# filter by service
journalctl -u ssh.service
# with human readable timestamps
journalctl -o short-iso
时间
date
# 打印日期时间
date
# 打印日期
date +%F
# 打印时间
date +%T
# 打印指定元素(年、月、日、时、分、秒)
date +%Y|m|d|H|M|S
# 打印指定格式时间
date +"%Y-%m-%d %H:%M:%S"
# 接受指定时间输入
date -d "Thu Jul 6 21:41:16 CST 2017"
date -d "-2day" # 2天前
date -d "+24hour" # 24小时后
# 遍历
startdate=20230101
enddate=20230131
d=$startdate
while [ "$d" != $enddate ]; do
echo $d
d=$(date -d "$d + 1 day" +"%Y%m%d")
done
cal
# print calendar
cal
数学
bc
bash calculator
bc
bc -l # 浮点运算
用户
用户管理
/etc/passwd
# 查看用户/用户组
cat /etc/passwd
cat /etc/group
useradd / adduser
创建用户
useradd username
useradd -g group username # 指定用户所属用户组
adduser username
usermod
usermod -l username # 修改用户名称
usermod -d home_dir # 修改用户家目录
usermod -g gourp # 修改用户组
usermod -G gourp1,group2 # 加入多个用户组
usermod -a group # 追加用户到用户组
userdel
删除用户,通常使用在/etc/passwd中注释掉用户的方法来删除用户
userdel username
userdel -r username # 同时删除用户所有相关文件
groupadd
添加用户组
groupadd group
groupdel
删除用户组。无法删除还有用户归属的主用户组
groupdel group
passwd
修改密码。root用户可以修改任何用户的密码,普通用户只能修改自己的密码。
passwd username
# 一行设置密码,常用于脚本中
echo "123456" | passwd --stdin username
su
切换用户
su root # 环境变量还是原来的用户的
su - root # 用户和环境变量都切换成新用户的
su - username -c '/bin/sh /service/scripts/deploy.sh' # 以某个用户的身份执行脚本
sudo
通过su-root提权需要输入root密码,通过sudo只需要输入用户密码
sudo echo hello
visudo
编辑sudo权限
# 添加权限
sudo su
visudo # 相当于vi /etc/sudoers
## 添加一下行
username ALL=(ALL) ALL
username ALL=(ALL) NOPASSWD: ALL
远程登录
ssh
# ssh免密登录
ssh-keygen
cd ~/.ssh
# 将公钥 id_rsa.pub 写入远程服务器的 authorized_keys 中
# 或者直接使用命令
ssh-copy-id username@host-ip
# 远程执行命令
ssh user@host {{command}}
ssh user@host ls | grep 'a' # 可以与管道连接,本地grep
ls | ssh user@host grep 'a' # 远程grep
# 远程保存内容
echo "hello world" | ssh user@host tee "file.txt"
用户信息
id
显示用户信息
id username
whoami
whoami
w
显示已登录用户,及其正在执行的命令
w
who
显示已登录用户的信息
who
who -H -a # 显示标题,显示所有信息
last / lastb /lastlog
显示用户登录列表,读取/var/log/wtmp、btmp、lastlog中的信息。
last
last -10 # 指定显示行数
lastb # 显示用户登录失败信息
lastlog # 显示用户最近登录记录
last -x shutdown # 关机记录
last -x reboot # 开机记录
网络
查看信息
ip address
查看本机ip地址
ip address
ifconfig
ifconfig
netstat
查看进程及端口
netstat -ltnp
传输
curl
HTTP 方法
# GET
curl http://example.com # 默认为 GET
curl -G http://example.com
curl --get http://example.com
# 用 GET 发送数据,它将-d选项指定的数据附加到URL右边,并使用“?”分隔,然后用GET方法发送数据
curl -G -d 'name=admin' http://example.com
# HEAD
curl -I http://example.com
curl --head http://example.com
# POST
# 默认的 POST 会带以下的 header: Content-Type: application/x-www-form-urlencoded
# 以下几种写法等价
curl -d 'name=admin&shoesize=12' http://example.com
curl --data 'name=admin&shoesize=12' http://example.com
curl --data-ascii 'name=admin&shoesize=12' http://example.com
# 上传urlencode后的数据
curl --data-urlencode 'name=admin&shoesize=12' http://example.com
# 上传 json 数据
curl -H 'Content-Type: application/json' -d '{"name":"Tom","age":12}' http://example.com
# 上传二进制文件
curl --data-binary @data.json
# 上传表单数据时默认为 POST,Content-Type 为 multipart/form-data
curl -F person=anonymous -F secret=@file.txt http://example.com/submit.cgi
# PUT
curl -T <file> http://example.com # 上传文件时默认为 PUT
curl -d "data to PUT" -X PUT http://example.com/new/resource/file
# OPTIONS
curl -X OPTIONS --request-target "*" http://example.com/
常用选项
# help
curl -h
curl --help
# verbose
curl -v http://example.com
curl --verbose http://example.com
# silent,不显示进度条
curl -s http://example.com
curl --silent http://example.com
# pretty json
curl -s http://example.com | json_pp
# output
curl -o response.txt http://example.com
curl --output response.txt http://example.com
# remote-output,以远程文件的名字命名
curl -O http://example.com
curl --remote-name http://example.com
# 替换 header
curl -H 'User-Agent: curl/7.63.0' http://example.com
curl --header 'User-Agent: curl/7.63.0' http://example.com
# 修改 method
curl -X HEAD http://example.com
curl -X DELETE http://example.com
# location,重定向
curl -L http://example.com
curl --location http://example.com
# data
curl -d '{"name": "Tom"}' http://example.com
curl --data '{"name": "Tom"}' http://example.com
curl -d @json http://example.com # 通过文件传入数据
# data-urlencode,上传url编码后的参数
curl --data-urlencode "q=status:200 AND ip:127.0.0.1" http://example.com
# user,指定用户
curl -u alice:12345 http://example.com
curl --user alice:12345 http://example.com
curl -u http://example.com # 会在运行时提示用户输入密码
# user-agent,指定agent
curl -A "my-user-agent" http://example.com
curl --user-agent "my-user-agent" http://example.com
代理
curl -x proxy.example.com:80 https://example.com/
curl -proxy proxy.example.com:80 https://example.com/
# socks
curl -x socks4://proxy.example.com http://www.example.com/
curl --socks4 proxy.example.com http://www.example.com/
curl -x socks5://proxy.example.com http://www.example.com/
curl --socks5 proxy.example.com http://www.example.com/
# proxy authentication
curl -U daniel:secr3t -x myproxy:80 http://example.com
curl -proxy-user daniel:secr3t -x myproxy:80 http://example.com
# 设置环境变量,curl会自动配置代理
http_proxy=http://proxy.example.com:80
https_proxy=https://proxy.example.com:80
curl -v www.example.com
# no proxy
curl --no-proxy http://www.example.com
# resolve
curl --resolve foo.example.com:443:127.0.0.1 https://foo.example.com:443/
SSL
curl -v --ssl http://www.example.com # 尝试升级到ssl
curl -v --ssl-reqd http://www.example.com # 强制使用ssl
# 相信自签名证书
curl --insecure https://www.example.com
curl -k https://www.example.com
配置文件
curl -K config http://example.com
curl --config config http://example.com
# 注释,重定向
location
# user-agent
user-agent = "An agent"
# url
url = "http://example.com"
Cookie
# 从文件中读取cookies
curl -L -b cookies.txt http://example.com
# 将cookies写入文件
curl -c cookie-jar.txt http://example.com
# 开始新的session,这会丢弃所有的session cookies,相当于重启浏览器
curl -j -b cookies.txt http://example.com/
连续请求(–next,短格式为-;)
curl --location http://example.com/1 --next
--data "sendthis" http://example.com/2 --next
--head "sendthis" http://example.com/3
URL通配
curl -O http://example.com/[1-100].png
curl -O http://example.com/[001-100].png # 带0前缀
curl -O http://example.com/[0-100:2].png # 指定step
curl -O http://example.com/section[a-z].html
# 列表
curl -O http://example.com/{one,two,three}.html
# 组合
curl -O http://example.com/{web, mail}-log[0-6].html
# 输出变量
curl http://{site, host}.host[1-5].example.com -o "subdir/#1_#2"
Reference
DNS
host
根据域名查询 ip
host www.baidu.com
nslookup
nslookup www.baidu.com
dig
dig www.baidu.com
dig @192.168.3.1 cyzlmh.xyz
加密
加密解密
base64
# encode
echo "test" | base64
# decode
echo "dGVzdAo=" | base64 -d
openssl
参考
查看信息
# 查看版本
openssl version -a
# 帮助
openssl help
# 列出命令
openssl list -commands # 标准命令
openssl list -cipher-commands # 加密命令
openssl list -digest-commands # 摘要命令
对称加密
echo "Hello World" > plain.txt
# encrypt
openssl enc -aes-256-cbc -e -in plain.txt -out encrypted.bin
# decrypt
openssl enc -aes-256-cbc -d -in encrypted.bin -pass pass:your_password
非对称加密
# 创建1024 bits长度的RSA钥匙对
openssl genrsa -out key.pem 1024
# 生成加密私钥文件
openssl rsa -in key.pem -aes-128-cbc -out enc-key.pem
# 生成公钥文件
openssl rsa -in key.pem -pubout -out pub-key.pem
# 用公钥加密文件
openssl pkeyutl -encrypt -pubin -inkey pub-key.pem -in <input_file> -out <output_file>
# 用私钥解密文件
openssl pkeyutl -decrypt -inkey key.pem -in <input_file> -out <output_file>
# 用私钥生成签名文件
openssl pkeyutl -sign -inkey key.pem -in <input_file> -out <output_file>
# 用公钥验证文件和签名
openssl pkeyutl -verify -pubin -inkey pub-key.pem -sigfile <signature> -in <input_file>
摘要
# 生成摘要
openssl dgst -<hash_algorithm> -out <digest> <input_file>
CSR
# 生成CSR(Certificate Signing Request)
openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr
# 为已有的钥匙对生成CSR
openssl req -new -key domain.key -out domain.csr
# 根据过往证书生成CSR
openssl x509 -x509toreq -in domain.crt -signkey domain.key -out domain.csr
# 查看CSR
openssl req -text -noout -verify -in domain.csr
证书
# 生成自签名的x509证书
openssl req -newkey rsa:2048 nodes -keyout domain.key -x509 -days 365 -out domain.crt
# 为已有的钥匙对生成自签名证书
openssl req -key domain.key -new -x509 -days 365 -out domain.crt
# 查看证书
openssl x509 -text -noout -in domain.crt
# 查看证书有效期
openssl x509 -dates -noout -in domain.crt
# 验证证书
openssl verify -verbose -CAFile ca.crt domain.crt
生成密码
openssl passwd # 标准Unix算法生成密码
openssl passwd -1 # 用MD5算法生成密码
openssl passwd -5 # 用SHA256算法生成密码
openssl passwd -6 # 用SHA512算法生成密码
# 制定加盐
openssl passwd -salt <salt>
生成随机数
# 生成8 bytes的随机数,以hex格式显示
openssl rand -hex 8
certtool
安装
yum install gnutls-utils
生成自签名证书
- 准备 template
rootca.cfg
cn = "example.com"
organization = "Example Organization"
serial = 1
expiration_days = 365
ca
signing_key
cert_signing_key
crl_signing_key
- 生成自签名证书
# 生成密钥对
certtool --generate-privkey --outfile ca-key.pem --bits 2048
# 创建(自签名)的CA证书本身
certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem --template rootca.cfg
生成服务端证书
- template
server.cfg
cn = "127.0.0.1"
dns_name = "127.0.0.1"
ip_address = "127.0.0.1"
organization = "Example Organization"
expiration_days = 365
signing_key
encryption_key
tls_www_server
- 生成服务端证书
# 生成密钥对
openssl genrsa -out server.key 2048
# 生成CSR
certtool --generate-request --load-privkey server.key --outfile server.csr --template server.cfg
# 签名
certtool --generate-certificate --load-request server.csr --outfile server.crt --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem --template server.cfg
生成客户端证书
- template
client.cfg
cn = "Client Name"
unit = "Client Unit"
expiration_days = 365
signing_key
encryption_key
tls_www_client
- 生成客户端证书
# 生成密钥对
openssl genrsa -out client.key 2048
# 生成CSR
certtool --generate-request --load-privkey client.key --outfile client.csr --template client.cfg
# 签名
certtool --generate-certificate --load-request client.csr --outfile client.crt --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem --template client.cfg
checksum
cksum
cksum file.txt
其他
软件安装
dpkg
安装deb
文件
sudo dpkg -i path_to_deb_file
汇编
objdump
mac上可以使用otool
objdump -S bin_file
# mac
otool -x -v bin_file
命令行技巧
xargs
将管道或输入转化为 xargs 后面命令的参数
xargs < test.txt # 读取文件输入
echo hello | xargs -i echo {} > test.txt # 以{}代替前面的结果
xargs -n 3 < test.txt # 每行最多输出3个
echo a:b:c:d:e | xargs -d : -n 3 # 自定义分隔符
# 删除文件名里带空格的小技巧,find 输出时以null为分隔符
find . -type f -name "*.txt" -print0 | xargs -0 rm -f
nohup
后台运行进程
# 后台运行,如果关掉终端也不会终止进程,但是会占用当前终端,可以通过Ctrl+C退出
nohup ping cyzlmh.xyz
# 直接后台运行,不占用当前终端
nohup ping cyzlmh.xyz &
# 重定向输出,默认为nohup.out
nohup ping cyzlmh.xyz > nohup.out 2>&1 &
# 后台运行并忽略输出
nohup ping cyzlmh.xyz > /dev/null 2>&1 &
expect
自动交互脚本
自动密码登录
#!/usr/bin/expect -d
# 用expect登录后调整terminal大小后显示会乱掉,所以需要加上这一段
trap {
#fetch rows and cols from controlling terminal
#note [] is tcl way of call and here the stty is expect's not system's which not support "stty rows" to query rows
set rows [stty rows]
set cols [stty columns]
#send "echo size changed to $rows $cols\r"
#according to the man page, the variable spawn_out(slave,name) is set to the name of the pty slave device
stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH
set host {host_ip}
set port {host_port}
set user {username}
set password {password}
spawn ssh $user@$host -oPort=$port
expect "*password:*"
send "$password\r"
interact