总结常用的Linux命令~

实用技巧和工具

ssh自动登录

sshpass

1
sshpass -p 'password' /usr/bin/ssh -o "StrictHostKeyChecking no"  -o "UserKnownHostsFile /dev/null" root@192.168.1.8
1
alias loginroot1='sshpass -p 'password' /usr/bin/ssh -o "StrictHostKeyChecking no"  -o "UserKnownHostsFile /dev/null" root@192.168.1.1'

设置命令行的超时

timeout设置命令行的超时,如

1
timeout 60s ping jd.com

网络流量查看

非UI环境下,实时查看网络流量nload,

1
nload

通过↑↓键切换设备。

实时查看进程流量nethogs,

1
nethogs

目录查看和分析

Ubuntu系统下,有一个目录浏览的UI工具,

1
nautilus ${your_dir}

如果要分析目录的使用情况,baobab是不错的工具,

1
baobab ${your_dir}

如果是命令行环境,推荐使用ncdu,例如

1
2
3
4
5
6
7
ncdu $HOME/desktop

--- /desktop --------------------------------------------------------------------------------
5.3 GiB [##########] /a
2.4 GiB [#### ] /b
806.6 MiB [# ] /c
508.3 MiB [ ] /d

后台和系统

Target就是一个包含许多相关Unit的组

编写systemd配置文件,以sshd为例,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit] # 用来定义 Unit 的元数据
Description=OpenSSH server daemon # 简短描述
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service # 如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
Wants=sshd-keygen.service # 与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
Requires= # 当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败,是一种强依赖,即如果该服务启动失败或异常退出,本服务也退出。
Before= # 如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动

[Service] # 用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块
EnvironmentFile=/etc/sysconfig/sshd # 指定当前服务的环境参数文件
ExecStart=/usr/sbin/sshd -D $OPTIONS # 定义启动进程时执行的命令
ExecReload=/bin/kill -HUP $MAINPID # 重启服务时执行的命令
Type=simple
KillMode=process
Restart=on-failure
RestartSec=42s

[Install] # 定义如何安装这个配置文件
WantedBy=multi-user.target # 说明sshd 所在的 Target 是multi-user.target

systemd相关命令总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
systemctl enable ${service} # 允许开机启动服务,即建立启动链接/usr/lib/systemd/system/->/etc/systemd/system/
systemctl disable ${service} # 取消开机启动,即取消建立启动链接
systemctl stop ${service} # 停止服务
systemctl start ${service} # 启动服务
systemctl kill ${service} # 杀掉,处理卡死情况
systemctl restart ${service} # 重启服务,修改配置后
systemctl reload ${service} # 重新加载service的配置文件
systemctl cat ${service} # 查看service的配置文件
systemctl daemon-reload # reload所有修改过的配置文件
systemctl status ${service} # 显示状态,不加service显示系统状态
systemctl list-dependencies ${service} # 依赖关系
systemctl list-unit-files # 列出所有配置文件
systemctl list-unit-files --type=service # 列出所有service配置文件
systemctl list-units
systemd-analyze blame # 查看每个服务的启动耗时
hostnamectl # 主机信息
localectl # 查看本地化设置
timedatectl # 查看当前时区设置
loginctl list-users # 列出当前登录用户
loginctl list-sessions # 列出当前session

jobs

1
2
3
4
ping ${IP}
Ctrl + Z
jobs
fg

进程相关

1
2
3
4
5
6
7
ps aux | sort -nk +4 | tail # 列出头十个最耗内存的进程
pstree
nohup
top
htop
iostat
dstat # 网络、CPU、DSK

硬件或驱动程序的信息dmesg

1
dmesg
1
dmidecode -t memory # 内存信息

t参数还可以取bios/system/baseboard/chassis/processor/memory/cache/connector/slot

调试与分析

1
2
ltrace
gdb

/proc 目录中记录的整个操作系统的运行统计和信息

文件

通配符

命令行提供通配符(wildcards),类似bash中正则表达式的用法,可以简洁地表示复杂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ll ?.py # ?表示单个字符但是不能匹配空字符,??表示两个字符,以此类推。通配符是先解释,再执行
ll *.py # *表示数量任意的字符,可以匹配空字符。只能用于单层路径
ls */*.py # 匹配包括子目录
ll [xyz].py # 表示匹配[xyz]中任意字符,如果找不到匹配,[xyz]变成一个单纯的字符串
ll *[xyz].py # 匹配后续为[xyz].py字符
ll [1-9].py
ll [a-z].py
ll [^xyz].py # 匹配不在[xyz].py里的文件
ll [!xyz].py # 同上
ll [^x-z].py # 同上,使用[x-z]表达
echo *.pyc # 如果无法解释,会输出*.pyc
echo {a,b,c} # a b c
echo {a,b,c}xyz # axyz bxyz cxyz
echo {a,b,c}{x,y,z} # ax ay az bx by bz cx cy cz
echo {{0..9},{a..z}} # 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z
ll {x,y,z}.py # 匹配[xyz].py,如果无法匹配也会展开
echo {1..9}a # 1a 2a 3a 4a 5a 6a 7a 8a 9a
echo {a..z}{1..9} # a1 a2 a3 ... z7 z8 z9

这里需要注意,[...]如果无法匹配,会当做普通字符串,而{...}无论如何也会展开。

ll *.py会先被bash解析,进行匹配扩展如x,然后再执行普通命令ll x.py

文件操作

1
2
3
4
5
6
7
8
9
touch ${file} # 创建文件
> ${file} # 创建文件
file -i $filename # 文件编码
wc -l
cd - # 回到上一次目录
cd ~ # 回到HOME
du -s * | sort -n | tail # 列出当前目录里最大的10个文件
ldd ${file} # 可执行文件使用的动态链接库

创建文件

1
2
3
dd if=/dev/zero of=${file} bs=10M count=100 # 创建10*100M大小的${file}内容从/dev/zero读取
dd if=/dev/zero of=${file} bs=1M count=0 seek=100 # 同上,但用seek跳过,但并不占用实际空间,可以用du -s ${file}来测试

查找命令

1
2
3
4
5
6
7
8
9
10
find ${path} ${cond} ${act} # find的用法模板
find . -name '*.py' # 在当前目录和子目录查找py后缀文件,默认搜索普通文件+特殊文件+目录
find . -type f -name "python" # 同上,不过type指定是普通文件
find . -type d -name "python" # 同上,指定目录
find . -ls -name '*.py' # 在当前目录和子目录查找py后缀文件并列出详细信息
locate /etc/docker # 搜索/etc/docker为前缀的文件。locate命令不遍历目录,而是搜索/var/lib/locatedb数据库
updatedb # 更新/var/lib/locatedb数据库
whereis ${program} # 搜索program所在位置
which ${program} # 搜索program所在位置
type ${program} # 判别是shell还是二进制执行文件

whereis vs which vs type

1
2
3
4
5
6
7
8
$ whereis docker
docker: /usr/bin/docker /etc/docker /usr/libexec/docker /usr/share/man/man1/docker.1.gz
$ which docker
/usr/bin/docker
$ type docker
docker 是 /usr/bin/docker
$ type ll
ll 是“ls -alF”的别名

apt包

1
2
3
4
5
6
7
8
9
apt install # 安装软件包
apt remove # 移除软件包
apt purge # 移除软件包及配置文件
apt update # 刷新存储库索引
apt upgrade # 升级所有可升级的软件包
apt autoremove # 自动删除不需要的包
apt full-upgrade # 在升级软件包时自动处理依赖关系
apt search # 搜索应用程序
apt show # 显示装细节9

yum

1

文件防伪

1
2
3
md5sum ${file}
sha1sum ${file}
sha256sum ${file} # MAC OS使用shasum -a256

https://www.ruanyifeng.com/blog/2013/07/gpg.html

压缩与解压

网络操作

net-tools网络工具

1
2
3
4
5
6
7
8
9
ifconfig -a # ifconfig是net-tools网络工具的命令
netstat -a # 列出所有端口
netstat -at # 列出所有tcp端口
netstat -au # 列出所有udp端口
netstat -l # 只显示监听端口
netstat -lt # 只列出所有监听 TCP 端口
netstat -lu # 只列出所有监听 UDP 端口
netstat -lx # 只列出所有监听 UNIX 端口
netstat -tlnp # 列出本机进程监听的端口号

iproute2套装工具

1
2
3
4
5
6
7
8
ip addr # 网卡细节,地址
ip link # LINK
ip -s link
ip addr add 192.168.0.193/24 dev wlan0 # 为设备wlan0设置IP地址
ip addr show wlan0
ip addr del 192.168.0.193/24 dev wlan0
ip route show # 列出路由表条目

网络质量测试

网速测试、网络流量,

1
2
nload ${device} # 查看网卡流量,可以用`ip addr show`获得网卡信息
nethogs # 查看进程流量
1
2
3
4
5
nmap {IP} # 扫描端口
nmap -sn 192.168.1.0/24
traceroute ${address} # 跟踪路由
mtr ${address} # 类似于traceroute,但是动态监控信息
lsof -i # 本机网络服务的活动实时状态

DNS有关的操作

1
2
3
4
cat /etc/resolv.conf
( nmcli dev list || nmcli dev show ) 2>/dev/null | grep DNS # 获取DNS
systemd-resolve --status | grep DNS
resolvectl dns ${device} 8.8.8.8 # 使用resolvectl设置DNS

rsync

rsyn同时支持本地和远程目录的增量同步

1
2
3
4
5
6
7
8
9
sync -r ${source} ${destination} # r表示递归,从source到destination,后者可以是username@remote_host:destination格式,进而支持远程同步
sync -a ${source} ${destination} # a表示递归+同步元信息,从source到destination
sync -avn ${source} ${destination} # v表示将操作结果输出到终端,n表示模拟从source到destination
rsync -av --delete ${source} ${destination} # delete参数表示删除只存在于destination目录(副本)、不存在于source目录的文件
rsync -av --exclude='*.pyc' ${source} ${destination} # 排除*.pyc文件
rsync -av --exclude='__pycache__/*' ${source} ${destination} # 排除__pycache__目录里的文件(不包括目录)
rsync -av --exclude={'*.pyc','*.pyo'} ${source} ${destination} # 排除多个模式文件,当模式很多,可以用--exclude-from指定存放模式的文件
rsync -av -e 'ssh -p 8899' ${source} ${destination} # 指定具体的ssh参数
rsync -av ${source} ${IP}::${module}/${destination} # 和${IP}上的rsync进程通信,${module}使其资源名

curl & wget

curl用来请求Web服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
curl ${address} # 访问地址
curl ifconfig.me # curl查看本机外网地址
curl --referer ${x_address} ${address} # 指定中x_address到address访问
curl --user-agent ${UA} ${address} # 指定UA
curl --user name:password ${address}
curl --header "Content-Type:application/json" ${address}
curl --cookie "${key}=${value}" ${address} # 指定cookie
curl -c ${file} ${address} # 保存cookie到文件
curl -b ${file} ${address} # 加载文件作为cookie
curl -o ${file} ${address} # 保存到文件
curl -i ${address} # 支持显示HTTP的Response信息
curl -V ${address} # 显示HTTP通信的整个过程,包括端口连接和Request、Response信息
curl -L ${address} # L支持自动跳转
curl --trace ${file} ${address} # 更详细的信息输出到文件
curl ${address}?a=b # GET方法发送表单,例如curl -L www.google.com/search?q=curl
curl -X POST --data "${key}=${value}" ${address} # 通过POST方法提交表单,X表示HTTP访问方法,如DELETE、POST。--data-urlencode编码表单

如果不想用命令行,Postman是推荐的UI工具。

ssh相关

ssh登录过程:

  • 服务器收到用户的登录请求,其把自己的公钥发给用户
  • 用户收到公钥后,将登录密码使用公钥加密后,发送到服务器
  • 服务器用自己的私钥,解密用户的登录密码,验证密码通过,用户登录成功

这个过程有中间人攻击风险,攻击者冒充服务器,伪造假的公钥发送给用户,用户无法辨别公钥真伪,攻击者进而接管登录过程,获取用户密码。因此,使用公钥指纹来辨别公钥的所有者是一种简单的用法。只需要服务器的所有者公开公钥的指纹即可。

1
2
3
4
5
6
7
8
ssh ${user}@${host} # 默认用法,端口是22
ssh -l ${user} ${host} # 同上
ssh -p ${port} ${user}@${host} # 指定端口
tar czv src | ssh user@host 'tar xz'
ssh user@host 'tar cz src' | tar xzv
ssh user@host 'ps ax | grep [h]ttpd'
ssh user@host cat /path/to/remotefile | diff /path/to/localfile - # 比较一个远程文件和一个本地文件
ssh user@server bash < /path/to/local/script.sh # 在远程机器上运行一段脚本。这条命令最大的好处就是不用把脚本拷到远程机器上

为避免每次登录服务器进行的公钥验证,用户可以使用公钥登录:

  • 用户首次登录将自己的公钥储存到服务器上
  • 下次登录的时候,服务器向用户发送一段随机字符串,用户用自己的私钥加密后该字符串,再发回来服务器
  • 远程主机用已经储存的公钥进行解密,验证随机字符串是否匹配,匹配就证明用户是可信,于是登录成功
1
2
3
4
ssh-keygen
ssh-copy-id ${user}@${host}
ssh-keygen -R ${hostname} # 将原来的公钥指纹从~/.ssh/known_hosts文件清除
ssh-keygen -l -f ${key}.pub # 查看公钥的指纹和加密方式

避免SSH连接超时而断开或卡死,

1
2
3
4
5
cat /etc/ssh/ssh_config # 修改一下参数,连接SSH到服务器后,每60秒会发一个KeepAlive请求
ServerAliveInterval 60

cat /etc/ssh/sshd_config # 另外一个参考选择
ClientAliveInterval 60

端口转发

1
2
ssh -D ${port} ${user}@${host} # 绑定本地端口
ssh -L ${local_port}:${target_host}:${target_port} ${forward_host} # 本地端口转发,SSH隧道

远程端口转发

限制sshd的登录IP地址的方法

/etc/hosts.allow添加如下项目,

1
sshd: ${your_address}:allow

可以允许${your_address}登录。

/etc/hosts.deny输入

1
sshd: ${your_deny_address}

于是,可以限制登录${your_deny_address}地址

如果两个文件的配置有冲突,以/etc/hosts.deny为准

日志和数据处理

1
2
3
4
5
6
tail -f /var/log/xx/yy.log
cat ${file}
nl ${file} # 类似于cat但带行号
tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q' # 实时监控并过滤log是否出现了某条记录
sort
uniq

awk

awk用于处理文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
awk ${act} ${file} # awk的使用模板
awk ${cond act} ${file} # 允许指定输出条件,只输出符合条件的行
echo ${string} | awk ${act}
echo ${file} | awk ${act}
echo 'a b c' | awk '{print $0}' # $0表示把标准输入直接输出
echo 'a b c' | awk '{print $1}' # $1表示以空格为分割,输出第一个元素,以此类推,如果超出范围返回空
echo 'a b c' | awk '{print $NF}' # NF变量表示最后一个元素,即c
echo 'a b c' | awk '{print $(NF-1)}' # 返回倒数第二个即b,以此类推
echo 'a:b:c' | awk -F ':' '{print $1}' # 可以指定分隔
echo 'a:b:c' | awk -F ':' '{print $1}{print $2}' # 可以指定多个命令,返回ab(ab之间换行)
echo 'a:b:c' | awk -F ':' '{print $1, $2}' # 可以指定多个命令,返回a b(不换行)
echo 'a:b:c' | awk -F ':' '{print $1 $2}' # ab(中间没有空格)
echo 'A B C' | awk '{print tolower($1)}' # 执行tolower函数
cat *.py | awk '/import/ {print $2}' # /import/表示条件,输出只包括import的行
history|awk '{print $2}'| awk 'BEGIN {FS="|"} {print $1}'|sort|uniq -c|sort -rn|head -10 # 统计命令

NR变量表示输出的行序号,从1开始计数

1
2
3
4
5
6
7
8
9
10
11
$ ps -aux | head | awk '{print NR "-" $2}'
1-PID
2-1
3-2
4-3
5-4
6-6
7-9
8-10
9-11
10-12

sed

sed是流编辑器,比awk出现早几年。

总结

转载请包括本文地址:https://allenwind.github.io/blog/6329
更多文章请参考:https://allenwind.github.io/blog/archives/