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
  1. 文件(夹)类型
  2. 文件所属用户权限
  3. 文件所属用户组权限
  4. 其他用户权限
  5. 硬链接个数
  6. 所属用户
  7. 所属用户组
  8. 文件(夹)大小
  9. 修改时间
  10. 名称

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
  • 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.
  • 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

生成自签名证书

  1. 准备 template rootca.cfg
cn = "example.com"
organization = "Example Organization"
serial = 1
expiration_days = 365
ca
signing_key
cert_signing_key
crl_signing_key
  1. 生成自签名证书
# 生成密钥对
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

生成服务端证书

  1. 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
  1. 生成服务端证书
# 生成密钥对
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

生成客户端证书

  1. template client.cfg
cn = "Client Name"
unit = "Client Unit"
expiration_days = 365
signing_key
encryption_key
tls_www_client
  1. 生成客户端证书
# 生成密钥对
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

References