UP | HOME

Linux 常用命令

Table of Contents

1 日常使用

  • ctrl-x ctrl-e 调用编辑器来编辑长命令
  • ctrl-r 回溯历史命令
  • 暴露服务器当前目录的文件:
    • Python 2: python -m SimpleHTTPServer 7777
    • Python 3: python -m http.server 7777

1.1 帮助文档

# 查看 topic 的相关文档
man topic
# 搜索 keyword 的 topic
man -k keyword

2 用户管理

2.1 查看用户信息

# 显示当前用户名
whoami
# 显示已经登录的用户,三种命令显示风格不同
who
w
users

# 查看用户指纹,用户 id,名字,登录状态
finger user
# 查看用户的各种 id,uid,gid
id user
# 打印 uid
id -u user
# 打印 gid
id -g user

# 查看最近登录用户日志
last
# 查看 user 的最近登录日志
last user
# 查看最近登录失败的日志
lastb

2.2 修改用户信息

# 添加用户
useradd user
useradd -m user # 创建用户,同时创建家目录;但不设置用户密码
# 删除用户 -r 选项删除用户并移除家目录和邮箱
userdel user
userdel -r user

# 添加用户,1. 调用 useradd 新建用户; 2. 创建用户的家目录; 3. 为用户设置密码
adduser user
# 删除用户,2. 动员 userdel 删除用户;2. 删除用户的家目录
deluser user

# 修改密码, 重置密码
passwd
sudo passwd user

2.3 修改用户组

# 新建一个组
groupadd group

# 将 user 添加到 group 中
usermod -aG group user
# 将当前用户添加到 group 中
usermod -aG group $USER

# 修改用户的登录 shell
usermod -s /bin/zsh user

3 文件系统

3.1 目录操作

3.1.1 查看目录信息

# 列出当前目录的内容
ls
# 只显示文件名
ls -1
# 显示隐藏文件
ls -a
# 按招时间由新到旧排序
ls -t

3.1.2 修改目录

# 进入 dir 目录
cd dir
# 打印当前目录
pwd
# 返回到家目录
cd
# 返回之前的目录
cd -
# 返回之前第 N 个目录, cd -2 返回倒数第二个目录
cd -N
# 返回到 git 根目录
cd $(git rev-parse --show-toplevel)

# 新建目录
mkdir dir
# 递归新建多级目录
mkdir -p dir1/dir2/dir3

# 目录栈的入栈和出栈
pushd dir
popd
# 列出当前目录栈
dirs -v

3.2 文件操作

3.2.1 查看文件信息

# 打印文件内容
cat file
# 查看文件行数
wc -l file
# 打印文件头部行数
head file
head -n 3 file
# 打印文件尾部行数
tail file
tail -n 3 file

# 文件的名字(不包含路径)
basename file
# 文件的路径(不包含名字)
dirname file

# 检测文件类型和编码
file file
# 文件的详细信息
stat file

# 分页查看, less is more, less 可以往回翻页, more 不行
less file
more file

# less 查看文件,直接跳到 120 行
less -n+120 /pass/to/file
less +120 /pass/to/file

3.2.2 文件复制、移动和删除

# 复制文件
cp src dest
# 递归复制文件
cp -rf src dest
# 更新模式复制文件,即 src 比 dest 新则复制
cp -u src dest
# 移动文件,重命名文件
mv src dest
# 删除文件
rm file
# 递归删除,非常小心地用这个命令
rm -rf dir

# 创建软连接, dest 是所指向的文件,link 是软连接
# 例如: ln -s /tmp ~/Public/tmp 相当于在 ~/Public 中建了一个 tmp 软连接,指向 /tmp
ln -s dest link

3.2.3 大文件分割和合并

# 按行数分割
split -l 300 largefile.txt new_file_prefix.
# 按字节大小分割
split -b 10m largefile.zip new_file_prefix.

# 合并文件
cat new_file_prefix.* > largefile.zip

3.2.4 更新文件信息

# 更新一下文件
touch file

# 更新文件权限为 644,-R 可以递归修改
chmod 644 file
# 更新文件的组/用户,-R 可以递归修改
chgrp group file
chown user file
# 同时更改文件的组合用户,-R 可以递归修改
chown user:group file

3.2.5 重定向

# 将 cmd 的 stdout 重定向到 file 中
cmd > file
# 将 cmd 的 stderr 重定向到 file 中
cmd 2> file
# 将 cmd 的 stdout 和 stderr 重定向到 file 中, 2>&1 的必须放在 > file 后面
cmd > file 2>&1

# 将 cmd 的 stdout 和 stderr 重定向到 /dev/null 中,并挂载成后台任务
cmd >/dev/null 2>&1 &

4 进程管理

4.1 查看进程

# 以不同模式查看进程
ps
ps -ef
ps aux
# 查看用户名 user 的进程
ps -u user
# 指定格式查看进程
ps -eo pid,user,command
# 查看父进程 ppid 为 1 的子进程
ps -eo ppid,pid,user,command | awk '$1 ~ /^1$/'

4.2 监控进程

# 进程监视器
top

# 进程监视器, 仅仅监控 user 的进程
top -u user
top -u $USER

# htop 和 top 类似,但是比 top 要好看一点,需要安装
htop

# 内存监视器
vmstat
# 每 3 秒打印一行内存和 CPU 使用情况
vmstat 3
# 查看内存和 swap 的使用情况
free
# 每 3 秒刷新显示
while sleep 3; do clear && free; done

4.3 后台进程

# & 符号表示将进程挂在后台运行
cmd &
# 查看所有后台进程
jobs
# 查看后台进程,并切换过去
bg
# 切换后台进程到前台
fg
# 切换指定的 job 到前台
fg jid

# 长期运行后台进程,退出 shell 后任然保持运行
nohup cmd
# 在后台长期运行程序
nohup cmd &
# 将指定 pid 或者 jid 从后台任务列表移除
disown pid|jid
# 等待所以后台进程任务结束
wait

5 远程交换

5.1 ssh

# 远程登录
ssh user@host
# 指定 ssh 端口为 2222 登录到远程机器上
ssh -p 2222 user@host

# 生成 ssh 公钥和私钥
ssh-keygen -t rsa -b 4096 -C "hujinghui@buaa.edu.cn"

# 复制 ssh 公钥到远程机器上
ssh-copy-id user@host
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host

# ssh 到远程机器上,并执行 cmd 命令
ssh user@host cmd

5.2 scp 和 rsync

# 本地到远程复制文件, -r 选项表示递归复制
scp file user@host:path
scp user@host:path file
scp -r file user@host:path

# 增量同步文件
rsync -av dir user@host:path
# 增量同步文件,显示同步的进度
rsync -av --progress dir user@host:path
# 增量同步文件,忽略 *.log 文件
rsync -av --exclude='*.log' dir user@host:path
# 增量同步文件,删除远程中多余的文件
rsync -av --delete dir user@host:path
# 增量同步文件,删除远程中多余的文件, *.log 文件会被忽略,不会被删除
rsync -av --exclude='*.log' --delete dir user@host:path

6 软件包管理器

6.1 rpm & yum

# 直接安装
rpm -ivh package-name.bla.rpm
# 忽略报错,强制安装
rpmrpm --force -ivh your-package.rpm
# 查询 rpm
rpm -ql tree
# 卸载 rpm 软件包
rpm -e tree

# 返回软件包的全名
rpm -qf `which git`
# 返回软件包的有关信息
rpm -qif `which git`
# 返回软件包的文件列表
rpm -qlf `which git`
# 安装指定的安装包 package
yum install package
# 全部更新
yum update
# 删除程序包 package
yum remove package
# 下载包缓存信息
yum makecache

6.2 dpkg & apt-get

# 安装软件包
dpkg -i package.bal.deb
# 从软件包里面读取软件的信息
pkg -A package.bla.deb
# 安装一个目录下面所有的软件包
dpkg -R /path/to/folder
# 删除软件包(保留其配置信息)
dpkg -r avg71flm

简单来说就是 apt = apt-get、apt-cache 和 apt-config 中最常用命令选项的集合

# 刷新存储库索引
apt update
apt-get update
# 升级所有可升级的软件包
apt upgrade
apt-get upgrade
# 安装软件包
apt install package
apt-get install package
# 移除软件包
apt remove package
apt-get remove package
# 移除软件包及配置文件
apt purge package
apt-get purge package
# 自动删除不需要的包
apt autoremove
apt-get autoremove
# 搜索应用程序
apt search text
apt-cache search text
# 显示装细节
apt show package
apt-cache show package

7 网络管理

7.1 route

# 打印路由表
route -n

# 添加默认网关为 192.168.1.1, 即默认路由
route add default gw 192.168.1.1
# 添加一条普通路由项
route add 192.168.1.0/32 gw 192.168.1.1

# 删除默认路由
route del default gw 192.168.1.1

7.2 ifconfig

# 显示所有网卡和接口信息
ifconfig

# 显示所有网卡(包括开机没启动的)信息
ifconfig -a

# 指定设备显示信息
ifconfig eth0

# 激活网卡
ifconfig eth0 up
# 关闭网卡
ifconfig eth0 down

# 给网卡配置 IP 地址
ifconfig eth0 192.168.120.56
# 配置 IP 并启动
ifconfig eth0 192.168.120.56 netmask 255.255.255.0 up
# 修改 MAC 地址
ifconfig eth0 hw ether 00:aa:bb:cc:dd:ee

7.3 netstat

# 列出所有端口
netstat -a
# 查看所有连接信息,不解析域名
netstat -an
# 查看所有连接信息,包含进程信息(需要 sudo)
netstat -anp
# 查看所有监听的端口
netstat -l
# 查看所有 TCP 链接
netstat -t
# 显示所有正在监听的 TCP 和 UDP 信息
netstat -lntu
# 显示所有正在监听的 socket 及进程信息
netstat -lntup
# 显示网卡信息
netstat -i
# 显示当前系统路由表,同 route -n
netstat -rn

7.4 ping/traceroute/whois 网络连通性和 DNS

# 连通性
ping host/ip
ping -c 3 host/ip

# 路由跳转追踪
traceroute host

# 查看暴露的外网 ip
curl http://httpbin.org/ip

# DNS 查询
host domain
whois domain
dig domain

7.5 nmap 网络和端口扫描

# 扫描一个主机的所有信息
nmap 192.168.0.110

# 扫描主机是否开机
nmap -sn 192.168.0.0/24

# 扫描特定范围的 IP
nmap -F 192.168.0.0/24
nmap -F 192.168.0.*
nmap -F 192.168.0.110,111,112
nmap 192.168.0.100-199

# 扫描特定的端口号
nmap -p 80 192.168.0.*
nmap -p 9000-9999 192.168.0.110

7.6 ssh 代理

# 在本地 9595 端口开启一个 socks5 的代理服务
ssh -N -D 9595 user@proxyer

# 测试连通性: --socks5-hostname 表示使用代理机的 DNS 来解析域名
curl --socks5-hostname 127.0.0.1:9595 http://httpbin.org/ip

# 优雅地启动 socks5 代理
# -f 挂后台, -q 静默, -n 屏蔽 stdin, -T 阻止分配 tty, -C 压缩
# -N 不执行 ssh 命令,只作端口转发, -D 指定本地监听端口号
ssh -fqnCTN -D 9595 user@proxyer

# 反向代理:将外网主机(202.115.8.1)端口(8443)转发到内网主机 192.168.1.2:443
ssh -qnCTN -R 0.0.0.0:8443:192.168.1.2:443  user@202.115.8.1

# 正向代理:将本地主机的 8443 端口,通过 192.168.1.3 转发到 192.168.1.2:443
ssh -qnCTN -L 0.0.0.0:8443:192.168.1.2:443  user@192.168.1.3

8 文本处理

8.1 普通处理

简单的文本处理使用 tr/cut/paste 等,复杂的文本处理使用 sed/awk

# 截取每行头 16 个字符
cut -c 1-16
# 截取指定文件中每行头 16 个字符
cut -c 1-16 file
# 截取每行从第三个字符开始到行末的内容
cut -c3-
# 截取用冒号分隔的第五列内容
cut -d':' -f5
# 截取用分号分隔的第二和第十列内容
cut -d';' -f2,10
# 截取空格分隔的三到七列
cut -d' ' -f3-7

# 显示 hel
echo "hello" | cut -c1-3
# 显示 sir
echo "hello sir" | cut -d' ' -f2
# cut 搭配 tr 压缩字符
ps | tr -s " " | cut -d " " -f 2,3,4
# 打印 PATH 变量
echo $PATH | tr : '\n'

8.2 sed

sed 是 Linux 下著名的行编辑器

# 替换文件中首次出现的字符串并输出结果
sed 's/find/replace/' file
# 替换文件第 10 行内容
sed '10s/find/replace/' file
# 替换文件中 10-20 行内容
sed '10,20s/find/replace/' file

# 替换文件中所有出现的字符串
sed -r 's/regex/replace/g' file

# 替换文件中所有出现的字符并且覆盖文件
sed -i 's/find/replace/g' file
# 在文件的匹配文本前插入行
sed -i '/find/i\newline' file
# 在文件的匹配文本后插入行
sed -i '/find/a\newline' file

# 先搜索行特征再执行替换
sed '/line/s/find/replace/' file
# 执行多次替换
sed -e 's/f/r/' -e 's/f/r' file

# 使用 # 替换 / 来避免 pattern 中有斜杆
sed 's#find#replace#' file

# 删除第 1 行内容
sed -i '1d' file
# 删除文件每行头部空格
sed -i -r 's/^\s+//g' file
# 删除文件空行并打印
sed '/^$/d' file
# 删除文件每行末尾多余空格
sed -i 's/\s\+$//' file

# 打印文件第二行
sed -n '2p' file
# 打印文件第二到第五行
sed -n '2,5p' file

# 使用词界 (word boundary), 这里 \b 是词界的锚点符号
sed 's/\bfoo\b/bar/g' file

8.3 awk

awk 一般用于文本预处理,并且支持编程

# -F 选项指定分隔符, 默认以空格分隔
awk -F ':' '{print $1}' file

# 使用正则表达式匹配过滤结果
awk '/reg/ {print $5}' file
awk '$1 ~ /reg/ {print $5}' file
# 打印用户名以 b 开头的用户名
awk -F ':' ' $1 ~ /^b/ {print $1}' /etc/passwd

# 打印文件中以空格分隔的第五列
awk '{print $5}' file
# 打印文件中以逗号分隔的第五列
awk -F ',' '{print $5}' file
# 打印文件中包含 str 的所有行的第二列
awk '/str/ {print $2}' file
# 打印逗号分隔的文件中的每行最后一列
awk -F ',' '{print $NF}' file
# 打印文件中的每行倒数第三列
awk '{print $(NF-2)}'
# 计算所有第一列的和
awk '{s+=$1} END {print s}' file
# 从第一行开始,每隔三行打印一行
awk 'NR%3==1' file
# 跳过第一行
awk 'NR>1 {print $0}' file

8.4 jq

jq 可以处理 JSON 文本

# Identity: .
echo '{"a":1, "b": "bla"}' | jq '.'

# Object Identifier-Index: .foo, .foo.bar,
echo '{"a":1, "b": "bla"}' | jq '.b'

# Generic Object Index: .["foo.bar"]
echo '{"a":1, "b": "bla", "c": { "k": "kill"}}' | jq '.["b"]'

# Optional Object Identifier-Index: .foo?
echo '{"a":1, "b": "bla"}' | jq '.b?'

# Array Index: .[2]
echo '[1, 2, 3]' | jq '.[1]'

# Array Slice: .[0:1]
echo '[1, 2, 3]' | jq '.[0:2]'

# Array/Object Value Iterator: .[]
echo '[1, 2, 3]' | jq '.[]'
echo '{"a":1, "b": "bla"}' | jq '.[]'

# Comma: ,
echo '{"a":1, "b": "bla", "c": 3}' | jq '.a,.b'

# Pipe: |
echo '{"a":1, "b": "bla", "c": [1, 2, 3]}' | jq '.c|.[]'

# Array construction: []
# Object Construction: {}

去除字符串的双引号,jq 在输出 json 时遇到字符串会添加上双引号,可以使用 -r 选 项来去除双引号

~ $ echo '["a", "b", "c"]' | jq '.[]'
"a"
"b"
"c"
~ $ echo '["a", "b", "c"]' | jq -r '.[]'
a
b
c

8.5 文本排序

# 排序文件
sort file
# 反向排序(降序)
sort -r file
# 使用数字而不是字符串进行比较
sort -n file
# 按 passwd 文件的第三列进行排序, -t 表示分隔符
sort -t: -k 3n /etc/passwd
# 去重排序
sort -u file

9 杂项

# 查看文件系统的结构和定义
man hier
# 查看 ASCII 表
man ascii

# 在线查看速查表
curl -L cheat.sh
curl -L cheat.sh/find

# 查看系统是 32 位还是 64 位
getconf LONG_BIT

# 快速备份文件
cp file.txt{,.bak}

# 从网络上的压缩文件中解出一个文件来,并避免保存中间文件
wget -qO - "http://www.tarball.com/tarball.tar.gz" | tar zxvf -
# 下载 zip 文件并解压,注意: unzip 6.00 后不能从 stdin 中读取,需要存成本地文件
curl -sL -o a.zip "http://localhost/a.zip" && unzip a.zip && rm -f a.zip

# 使用光盘制作 iso 文件
cp /dev/cdrom /path/to/file.iso
dd if=/dev/cdrom of=/path/to/file.iso
# 使用目录制作 iso 文件
mkisofs -r -o /path/to/file.iso /home/Public
# Linux 下挂载一个 iso 文件
mount -o loop /path/to/file.iso /mnt/cdrom

# 按日期范围查找文件
find . -type f -newermt "2010-01-01" ! -newermt "2010-06-01"

# Vim 中保存一个没有权限的文件
:w !sudo tee > /dev/null %

# 获取终端的一些基本信息:宽度,长度等
stty -a

# 将 list 的输出转化成二维矩阵显示方式
ls | column

# 时间戳 -> 字符串, 1564848000
date -d '2019-08-04 00:00:00' +%s
# 字符串 -> 时间戳, 2019-08-04 00:00:20
date -d @1564848200 +'%Y-%m-%d %H:%H:%S'

# 设置命令超时,超时的时长为 10 秒,如果发送命令后 5 秒任然运行则直接 kill
timeout -s INT -k 5 10 sh -c "sleep 8 && echo hello"

10 参考链接

Last Updated 2020-12-27 Sun 00:10. Created by Jinghui Hu at 2019-02-18 Mon 11:04.