个人笔记,只会列出我自己容易忘掉的命令,方便查阅。
内容比较多,适合当参考手册用。可能不太适合从头读到尾…
本文主要介绍 Linux 命令,顺带介绍下 Windows/MacOSX.
其中 awk 只需要学会些常用的用法就够了,这类命令行工具比较适合临时处理一些文本,可读性与维护性都比较差。对于需求比较复杂,而且需要长期使用的脚本,建议使用 Python/Go 等语言编写。
1
2
| # 1. 后台运行命令
nohup python xxx.py &
|
也可以使用 tmux,tmux 提供的 session 功能比 nohup 更好用,后面会介绍 tmux
grep 常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| ## 只在目录中所有的 .py 和 .dart 文件中递归搜索字符"main()"
# -r 表示递归搜索
grep "main()" . -r --include *.{py, dart}
cat xxx | grep -10 "main()" # 显示匹配行的前后 10 行
cat xxx | grep -A 10 -B 5 "main()" # 显示匹配行的前 5 行和后 10 行
## 在 .js 文件中搜索关键字 xxxxx 并仅展示关键字前后 40 个字符(用在 .js 等被压缩过的文本文件上很有效)
cat *.js | grep -o -P '.{0,40}xxxxx.{0,40}'
# 正则搜索(`egrep` 是 `grep -E` 的简写,表示使用扩展正则表达式)
cat xxx | egrep 'pattern1|pattern2|pattern3'
# 反向搜索(不包含某个关键字)
cat xxx | grep -v 'pattern'
# 高亮显示搜索结果
cat xxx | grep --color 'pattern'
# 通过 find 查找所有子文件夹中的 config.xml 文件,并在其中查找包含关键字 <recipients> 的行
# 再通过 awk 提取出文件名和需要的关键字
# -maxdepth 2 表示最大递归深度为 2(子文件夹)
# -exec echo \'{}\' \; 表示将 find 命令的输出使用 echo 命令添加单引号包裹起来,防止文件名中有空格导致 grep 命令出错
# xargs grep '<recipients>' 表示将 find 命令的输出作为 grep 命令的输入
# awk -F '[:<>]' '{print $1,$4}' 表示使用 : < > 作为分隔符,打印出第 1 列和第 4 列
find -maxdepth 2 -name "config.xml" -exec echo \'{}\' \; | xargs grep '<recipients>' | awk -F '[:<>]' '{print $1,$4}'
# 在文件夹中递归查找所有中文字符(在做中英双语内容维护时比较有用)
# -P 表示使用 Perl 正则表达式,[\x{4e00}-\x{9f5a}] 表示匹配所有中文字符
grep -P '[\x{4e00}-\x{9f5a}]' -r .
|
更 morden 的命令是 ripgrep,它的速度比 grep 快很多,而且默认就是正则匹配、递归搜索、高亮显示搜索结果:
1
2
3
4
5
6
7
8
9
10
11
12
| # 在当前文件夹递归搜索所有包含关键字 "main()" 的文件
# 注意 rg 默认使用 rust 的正则匹配库
# 也可通过 -P 参数使用 PCRE2 正则匹配库
rg "main\(\)"
# 在指定文件夹递归搜索所有包含关键字 "main()" 的文件
rg "main\(\)" <path>
# 类似 sed 的功能,替换文件中的字符串
# -N 表示不输出匹配的行,只输出替换后的结果
# -r 表示 replace 替换
rg --passthru -N 'and' -r '&' ip.txt > ip2.txt
|
sed 常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| ## 1) 全文搜索并替换
### -i --in-place 原地替换(修改原文件)
### -i=SUFFIX 替换后的文件添加 SUFFIX 这个后缀
### -r 使用拓展的正则表达式,注意此正则不支持 \d\w\s 等语法,必须使用 [0-9] [a-zA-Z] 等来替换!!!
sed -ri "s/pattern_str/replace_str/g" `grep "key_pattern" 'path_pattern' -rl`
## 2)文件名搜索,替换文件内容
sed -ri "s/pattern_str/replace_str/g" `find . -name "pattern"`
## 3)批量转换大小写
# 将当前文件夹内,所有的 gitlab URL 都转换成小写
# \L 转小写 \U 转大写
sed -ri 's@http://GITLAB.*.git@\L&@g' `find . -name pubspec*`
# 只有包含 2 的行才会替换逗号为破折号
printf '1,2,3,4\na,b,c,d\n' | sed '/2/ s/,/-/g'
# 只打印出被替换成功的行
sed -n 's/warm/cool/gp' rhymes.txt
# 删除掉第 3-8 行,保留其他行
seq 15 24 | sed '3,8 d'
# 删除除 3-8 行之外的所有行
seq 15 24 | sed '3,8! d'
# 删除掉第 3 行到第 11(3+8) 行,保留其他行
seq 15 24 | sed '3,+8 d'
# 对于所有包含 2 的行,都替换逗号为破折号
printf '1,2,3,4\na,b,c,d\n' | sed '/2/ s/,/-/g'
# 对于所有不包含 2 的行,都替换逗号为破折号
printf '1,2,3,4\na,b,c,d\n' | sed '/2/! s/,/-/g'
# 在第 2 行之后插入一行,内容为 hello
seq 1 3 | sed '2a hello'
# 将第 2 行的内容改为 hello
seq 1 3 | sed '2c hello'
# 将能匹配上指定正则表达式的行,改为 hello
seq 1 5 | sed -E '/(11|22)/c hello'
# 在第二行的前面插入一行,内容为 hello
seq 1 3 | sed '2i hello'
# 将第 2-4 行的内容改为 hello(改完后只有一行,而不是 3 行)
seq 5 | sed '2,4c hello'
# 将第 2-4 行每一行的内容都改为 hello(改完后是 3 行)
seq 5 | sed '2,4 s/.*/hello/'
# 一次使用多条指令
seq 4 | sed -e '2c hi' -e '3a bye'
## 4) 拷贝文件,并且保持文件夹结构(--parents 表示保持文件夹结构)
cp --parents `find <src-dir> -name *.py` <dst-dir>
|
awk 用于按列处理文本,它比 sed 更强大更复杂,常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| ## 1. 单独选出第 1 列的文本
cat xxx.txt | awk -F '{print $1}' | head
## 2. 可以使用 -F 指定分隔符,打印出多列
awk -F ',' '{print $1,$2}'| head
### -F 也可以使用正则表达式指定多个分隔符
awk -F '[,;]' '{print $1,$2}'| head
# 在文件开头与末尾分别添加字符串
seq 2 | awk 'BEGIN{print "---"} 1; END{print "%%%"}'
## 3. 打印出行数
cat log_test | awk '{print NR,$1}' | more
## 4. if 判断语句
cat log_test | awk '{if($11>300) print($1,$11)}'
cat log_test | awk '{print $11}' | sort -n | uniq -c
# 求和
cat data|awk '{sum+=$1} END {print "Sum = ", sum}'
# 求平均
cat data|awk '{sum+=$1} END {print "Average = ", sum/NR}'
# 求最大值
cat data|awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'
# 求最小值(min的初始值设置一个超大数即可)
awk 'BEGIN {min = 1999999} {if ($1<min) min=$1 fi} END {print "Min=", min}'
|
jq/yq 常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 1. jq 是一个命令行 json 处理工具
## 从 json 中查询某一个字段的值
jq -r '.message' xxx.json
## 也可从 stdin 读取 json
cat xxx.json | jq -r '.message'
## 从 json 内容中删除多个 key
## -r 表示输出文本采用 raw 格式
jq -r "del(.dataplane.insync, .dataplane.outdated)" xxx.json
## 更多 jq 的用法参见官方文档:https://stedolan.github.io/jq/tutorial/
# 2. yq 是用于处理 yaml 配置的命令行工具,参数跟 jq 高度相似
## 从 yaml 配置中删除多个 key
yq "del(.dataplane.insync, .dataplane.outdated)" xxx.yaml
## 或者从 stdin 读取输入
cat xxx.yaml | yq "del(.dataplane.insync, .dataplane.outdated)"
## 原地更新某 yaml 配置文件
yq -i '.a.b[0].c = "cool"' file.yaml
## yq 的更多用法参见官方说明: https://github.com/mikefarah/yq
|
1
2
3
4
5
| # 直接 cat 压缩文件的内容
zcat xxx.gz | more # gzip
xzcat xxx.xz | more # xz
tar -axvf xxx.tar.* # 通过后缀识别压缩格式,智能解压
|
以及日常可通过压缩 + bas64 编码来通过 IM 等聊天软件快速传输数据量不多的文件夹:
1
2
3
4
5
| # 压缩文件夹并通过 base64 编码
tar czv <folder-name> | base64 > xxx
# 解压消息到文件夹
cat "xxx" | base64 -d | tar zxv
|
更多命令参见常见压缩格式的区别,及 Linux 下的压缩相关指令
各种 Linux 发行版都自带 scp/ssh,这两个工具功能简单,一般够用。
另外就是更强大也更复杂的 rsync,部分发行版会自带 rsync。
下面分别介绍下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 如果使用 ssh 命令进行文件传输,可安装 pv 命令查看传输速度(pipeviewer)
## ubuntu
sudo apt-get install pv
## centos
sudo yum install epel-release
sudo yum install pv
## 1)从本地上传到服务器
### 使用 ssh 的好处是流式传输不会占用目标机器的存储空间,适合传输可能引起空间不足的大文件,并在目标机器上实时处理该文件。
cat <filename> | pv | ssh <user>@<host> -p 22 "cat - > <new-filename>"
tar cz <filename or foldername or glob> | pv | ssh <user>@<host> -p 22 "tar xz" # 压缩传输
## scp 命令比 ssh 命令更简洁(但是不适合用于传文件夹,它会破坏文件的权限设置,把文件夹弄得一团糟)
scp -P 22 <filename> <user>@<host>:<folder-name or filename> # 通过 scp 传输,传文件夹时记得添加 -r 参数(recursive)
## 2) 从服务器下载到本地
ssh <user>@<host> -p 22 "tar cz <filename or foldername or glob>" | pv | tar xz # 压缩传输
scp -P 22 <user>@<host>:<folder-name or filename> <filename> # 通过 scp 传输,传文件夹时记得添加 -r 参数(recursive)
|
rsync 的功能其实和前面的 scp/(tar+ssh) 是一样的,将文件从一个地方拷贝到另一个地方。区别在于它只做增量同步,在多次拷贝文件时,只拷贝(同步)修改过的部分,很多场景下可以大大加快拷贝
/备份速度。
rsync 的常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # 将一个文件夹归档、压缩,并通过 ssh 协议(默认)同步到另一个地方
# -a, --archive # 归档模式,保留文件的所有元信息,等同于 `-rlptgoD`
# -r, --recursive # 递归复制文件夹,`-a` 隐含了这个参数,通常都用 -a。
# -v, --verbose # 输出详细信息
# --progress # 显示传输进度
# -z, --compress # 传输文件时进行压缩
rsync -avz --progress src host:dest
rsync -avz --progress -e "ssh -p225" /path/src user@host:dest # 使用非默认的 ssh 端口进行传输
rsync -avz --progress -e "ssh -i id_xxx" /path/src user@host:dest # 使用指定的私钥连接 ssh 服务端,其他各种 ssh 参数都可以在这里指定
# --exclude 排除掉某些不需要的文件(夹)
rsync -avz --progress --exclude "foor/bar" src user@host:dest
# 有时我们希望在同步数据时修改文件的 user/group
# --chown # 设置文件的 user:group,必须与 `-og`/`--owner --group` 同时使用!(`-a` 隐含了 `-og`)
rsync -avz --progress --chown=root:root src user@host:dest # 传输时修改 user/group 为 root
# 详细说明 src 和 dest 的位置
rsync -avz --progress path/src user@host:/tmp # 将 src 拷贝到远程主机的 /tmp 中(得到 /tmp/src)
## 注意 src 结尾有 /
rsync -avz --progress path/src/ user@host:/tmp/src # 将 src 目录中的文件拷贝到远程主机的 /tmp/src 目录中(同样得到 /tmp/src)
# 有时候我们在传输文件时不希望保留文件的元信息
# rsync 默认不会删除 dest 中多余的文件,使用 --delete 可让 rsync 删除这部分无关的文件
# 对 src 文件夹进行完全镜像,保证两个文件夹的内容一模一样,不多不少
rsync -avz --progress --delete src user@host:dest
# 也可以使用 --ignore-existing 让 rsync 忽略掉 dest 已经存在的文件。就是只同步新增的文件。
rsync -avz --progress --ignore-existing src user@host:dest
|
另外也有使用双冒号 ::
分隔的传输命令,这种命令使用 rsync
协议进行传输,要求目标主机启用 rsync-daemon。用得会比 ssh 少一些,暂时不做介绍。
rsync 详细文档参见 https://rsync.samba.org/documentation.html,或者 man rsync
.
- 输入
tmux
启动一个 tmux 会话。(或者用 tmux new -s <session-name>
启动一个命名会话) - 输入
python xxx.py
,python 进程开始运行。 - 按快捷键
ctrl+b
,然后再按一下 d
脱离(detach)当前会话。此时 python 进程进入后台运行,关闭当前终端对 python 进程没有影响。 - 输入
tmux ls
可以查看当前正在后台运行的会话。(命名会话会显示名称,否则只显示 id) - 通过
tmux attach -t <session-name/id>
重新接入后台会话。- 缩写
tmux a -t <session>
- 或者通过
tmux kill-session -t <session-name/id>
杀死一个后台会话。
常用快捷键:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # prefix 表示 `ctrl`+`b`
# pane 的切分与选择
prefix " # 在下方新建一个 pane
prefix % # 在右侧新建一个 pane
prefix `方向键` # 光标移动到指定方向的 pane 中
# 使用方向键滚动窗口内容
prefix [ # 进入翻页模式,可使用 page up/down,或者方向键来浏览 pane 的内容
# 使用鼠标滚轮来滚动窗口内容(也可以把此命令添加到 `~/.tmux.conf` 中使它永久生效)
prefix `:` 然后输入 `set-window-option -g mode-mouse on`
# (调整 pane 大小)将当前的 pane 向给定的方向扩容 5 行或者 5 列
# 按住 ALT 时快速重复敲击「方向键」,能快速调整,否则就得从 prefix 开始重新输入
prefix `Alt` + `方向键`
# 将当前窗格全屏显示,第二次使用此命令,会将窗格还原
prefix z
# 交换 pane 的位置
prefix { # 当前窗格与上一个窗格交换位置
prefix } # 当前窗格与下一个窗格交换位置
# session 相关操作
prefix s # 查看 session 列表,并通过方向键选择 session
prefix `number` # 通过数字标签选择 session
# window 相关操作(关系:每个 session 可以包含多个 window,每个 window 里面又可以有多个 pane)
prefix c # 新建 window
prefix w # 通过数字标签选择 window
|
参考文档:
目标:能使用 shell 编写 10 行以内的脚本。更长的脚本可以使用 Python 编写,就没必要折腾
Shell 了。
单行 for 循环,有时候很有用:
1
2
3
4
5
6
7
8
9
10
11
| # 数字枚举
for i in $(seq 1 5); do echo $i; done # sh/bash 都支持
for i in {1..5}; do echo $i; done # sh 不支持此语法
# 文件枚举,可使用 glob 语法进行文件匹配
for f in *; do echo $f; done
for f in /etc/*.py; do echo $f; done
# 使用 find 进行文件枚举
for f in $(find . -name *.py); do echo $f; done
|
单行 for 循环加几个换行就得到多行 for 循环,格式如下:写脚本用得到,不过更建议用 python:
1
2
3
4
| for i in $(seq 1 5)
do
echo $i
done # sh/bash 都支持
|
1
2
3
4
5
6
7
8
9
10
| # 单行 if 语句
if [ true ]; then <command>; fi
# if else
if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
|
参见:Shell 脚本中的 set 指令,比如 set -x 和 set -e
1
2
3
4
5
6
7
| # URL 编解码
alias urldecode='python3 -c "import sys, urllib.parse as ul; print(ul.unquote_plus(sys.stdin.read()))"'
alias urlencode='python3 -c "import sys, urllib.parse as ul; print(ul.quote_plus(sys.stdin.read()))"'
# 使用方法
echo "xxx" | urldecode
cat file | urlencode
|
临时版:
1
2
| # 查询命令行历史记录,并带上时间
HISTTIMEFORMAT="%F %T %z " history
|
一劳永逸版:
1
2
3
4
5
6
| # 将环境变量加入 .bashrc
echo 'HISTTIMEFORMAT="%F %T "' >> ~/.bashrc
source ~/.bashrc
# 查询历史记录
history
|
7. socket 连接查询 - ss/netcat/lsof
查看 socket 信息可以帮我们回答下列问题:
- 我的程序是不是真的在监听我指定的端口?
- 我的程序是在监听 127.0.0.1(本机),还是在监听 0.0.0.0(整个网络)
- 进程们分别在使用哪些端口?
- 我的连接数是否达到了上限?
现在较新版本的 Ubuntu 和 CentOS 都已经使用 iproute2
替换掉了 net-tools
,如果你还需要使用陈旧的 route
netstat
等命令,需要手动安装 net-tools
。
我们可以使用 ss(socket statistics) 或者 netstat 命令来查看 socket 信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| # 查看 socket 连接的统计信息
# 主要统计处于各种状态的 tcp sockets 数量,以及其他 sockets 的统计信息
ss --summary
ss -s # 缩写
# 查看哪个进程在监听 80 端口
# --listening 列出所有正在被监听的 socket
# --processes 显示出每个 socket 对应的 process 名称和 pid
# --numeric 直接打印数字端口号(不解析协议名称)
ss --listening --processes --numeric | grep 80
ss -nlp | grep 80 # 缩写
ss -lp | grep http # 解析协议名称,然后通过协议名搜索监听
## 使用过时的 netstat
### -t tcp
### -u udp
netstat -tunlp | grep ":80"
# 查看 sshd 当前使用的端口号
ss --listening --processes | grep sshd
## 使用过时的 netstat
netstat -tunlp | grep <pid> # pid 通过 ps 命令获得
# 列出所有的 tcp sockets,包括所有的 socket 状态
ss --tcp --all
# 只列出正在 listen 的 socket
ss --listening
# 列出所有 ESTABLISHED 的 socket(默认行为)
ss
# 统计 TCP 连接数
ss | grep ESTAB | wc -l
# 列出所有 ESTABLISHED 的 socket,并且给出连接的计时器
ss --options
# 查看所有来自 192.168.5 的 sockets
ss dst 192.168.1.5
# 查看本机与服务器 192.168.1.100 建立的 sockets
ss src 192.168.1.5
|
TCP 连接数受 Linux 文件描述符上限控制,可以通过如下方法查看已用文件句柄的数量。
1
2
3
4
| # 已用文件描述符数量
lsof | wc -l
# 文件描述符上限
ulimit -n
|
主要是 iproute2 dhclient lsof 等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 查看路由表
routel # 旧的 net-tools 包中的命令
ip route ls # iproute2 提供的新命令
# DHCP,先释放旧租约,再建立新租约
sudo dhclient -r eth0 && sudo dhclient eth0
# 查看 DHCP 租期
cat /var/lib/dhcp/dhcpd.leases
# 清理 DNS 缓存
## 1. 如果你使用的是 systemd-resolve,使用此命令
sudo systemd-resolve --flush-caches
sudo systemd-resolve --statistics # 查看缓存状态
## 2. 如果使用的是 dnsmasq,使用此命令
sudo systemctl restart dnsmasq
sudo killall -HUP dnsmasq # 直接发送 HUP 信号也可以
|
Docker 容器有自己的 namespace,直接通过宿主机的 ss 命令是查看不到容器的 socket 信息的。
比较直观的方法是直接通过 docker exec
在容器中通过 ss 命令。但是这要求容器中必须自带 ss
等程序,有的精简镜像可能不会自带它。
通过 nsenter
可以直接进入到容器的指定 namespace 中,这样就能直接查询容器网络相关的信息了。
1
2
3
4
5
6
7
8
9
| docker ps | grep xxx
echo CONTAINER=xxx # 容器名称或 ID
# 1. 查询到容器对应的 pid
PID=$(docker inspect --format {{.State.Pid}} $CONTAINER)
# 2. nsenter 通过 pid 进入容器的 network namespace,执行 ss 查看 socket 信息
nsenter --target $PID --net ss -s
|
nsenter
这个工具貌似是 docker 自带的或者是系统内置命令,只要装了 docker,ubuntu/centos
都可以直接使用这个命令。
nsenter 是一个进入名字空间的工具,功能不仅仅局限在「网络诊断」,还有更多用法。
1
2
3
4
5
6
| ## 查看用户属于哪些群组
groups <user-name> # 方法一
id <username> # 方法二,它会额外列出 gid/uid
cat /etc/group | grep <user-name> # 方法三,直接查看配置
## 查看群组中有哪些用户,第一列是群组,最后一列是用户名
cat /etc/group | grep <group-name>
|
Powershell 是微软推出的一款新一代 shell,它的特点之一是,命令都有一致的命名规则:谓词-名词,谓词表示动作:Get/Set/Stop/Start 等,名词指示操作对象:Service/Member/ChildItem/Command 等。
这样的命名格式使我们可以很容易地猜测到自己需要的命令的名称。
为了使用方便,powershell 还提供了一些常用命令的缩写,并且添加了大量类似 Linux 命令的别名。
还有就是,Windows 默认不区分字母大小写,日常使用可以全部小写。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| # 删除文件/文件夹
remove-item xxx -confirm
ri xxx # 别名1
rm xxx # 别名2
rmdir xxx # etc...
# 复制
copy-item xxx xx -r
cp -r xxx xx
# 显示工作目录
get-location
gl
pwd
# 切换工作目录
set-location xxx
sl xxx
cd xxx
# 查看环境变量
get-childitem env:
gci env:
gci env:PATH # 查看 PATH 变量
$env:XXX="value" # 临时设置环境变量
$env:Path += ";SomeRandomPath" # 临时在 Path 末尾添加新路径
## 以下三行命令只对 windows 有效,linux 下无效
[Environment]::SetEnvironmentVariable("XXX", $env:XXX + ";value", [EnvironmentVariableTarget]::User) # 修改当前用户的环境变量(永久),只对新进程有效
[Environment]::SetEnvironmentVariable("XXX", "value", [EnvironmentVariableTarget]::Machine) # 给这台电脑设置环境变量(永久),只对新进程有效,需要管理员权限
[Environment]::SetEnvironmentVariable("XXX", $env:XXX + ";value", "User") # target 也可用字符串指定
# 删除文件/文件夹
rm xxx # 删除文件夹时会进入交互界面,按提示输入就行。
# 查看命名位置(类似 Linux Shell 的 which)
get-command xxx
gcm xxx
# 通过关键字查找 powershell 命令
gcm | select-string <keyword>
# 通过关键字查找 powershell 命令和环境变量中的程序,比较慢
gcm * | select-string <keyword>
# 查看别名对应的真实命令
get-alias
# 类似 linux 的 find/ls 命令
get-childitem -Recurse -Include *.py
gci -r -i *.py
# 清空终端的输出
clear-host
clear
# 查看文件内容
get-content xx.py | more
get-content xx.py | out-host -paging
cat xx.py
gc xx.py
# 字符串搜索,不能对对象使用
# 类似 linux 的 grep 命令
cat xxx.log | select-string <pattern>
gci env: | out-string -stream | select-string <pattern> # 需要先使用 out-string 将对象转换成 string
gci env: | where-object {$_.Name -like <pattern>}
# 计算输出的行数/对象个数
gci env: | measure-object
gci env: | measure # 这是缩写
# 关机/重启
stop-computer
restart-computer
# windows 计算 hash 值
# 功能等同于 linux 下的 sha256sum/sha1sum/sha512sum/md5sum
Get-FileHash -Path /path/to/file -Algorithm SHA256
Get-FileHash -Path /path/to/file -Algorithm SHA256 | Format-List # 用 format 修改格式化效果
# base64 编解码
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("xxx")) # base64 编码
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("eHh4")) # 解码
|
另外 windows 同样自带 ssh/scp 命令,参数也和 linux 一致
1
2
3
4
5
6
7
8
9
10
11
12
| # 查看所有进程
get-process | more
ps | more # 别名
# 查找某进程(替代掉 tasklist)
get-process -name exp*,power* # 使用正则查找进程
get-process | select-string <pattern> # 效果同上
# 通过 id 杀掉某进程(替代掉 taskkill)
# 也可以通过 -Name 用正则匹配进程
stop-process <pid>
kill <pid> # 别名
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| ## 1. dns 相关(dns-client)
Clear-DnsClientCache # 清除 dns 缓存(替换掉 `ipconfig /flushdns`)
Get-DnsClientCache # 查看 dns 缓存
Resolve-DnsName baidu.com # 解析域名
# 更新 DHCP 租约
ipconfig /renew
## 2. TCP/IP 相关命令
Get-Command Get-Net* # 查看所有 TCP/IP 相关的命令
Get-NetIPAddress # 查看 IP 地址
Get-NetIPInterface # 查看 IP 接口
Get-NetRoute # 查看路由表
Get-NetNeighbor # 获取链路层 MAC 地址缓存
Get-NetTCPConnection # 查看 TCP 连接
### 也可以对 TCP/IP 的 IP 地址、接口、路由表进行增删改
New-NetRoute
Remove-NetNeighbor # 清除 MAC 地址缓存
|
Windows 系统和 macOS 一样,也没有 ss
,但是自带 netstat
,该命令和 Linux 下的 netstat
有一定差别,具体使用方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| netstat -? # 查看使用帮助,很清晰易懂
# 查看那个进程在监听 80 端口,最后一列是进程的 Pid
netstat -ano | findstr 80 # windows 命令
netstat -ano | select-string 80 # powershell 命令,就是把 findstr 替换成 select-string
# 不仅列出 Pid,还给出 Pid 对应的可执行文件名称(需要管理员权限)
netstat -ano -b | select-string 80 # powershell 命令
# 列出所有 ESTABLISHED 的 socket(默认行为)
netstat
# 列出所有正在监听的端口
netstat -ano | findstr LISTENING
# 只列出 TCP 连接
netstat -ano -p TCP
# 查看路由表
route -? # 查看使用帮助,很清晰易懂
route print # 查看所有路由信息
route print -4 # 仅 ipv4
|
比如我们遇到端口占用问题时,就可以通过上述命令查找到端口对应的 Pid,然后使用 kill <Pid>
命令(powershell stop-process
的别名)杀死对应的进程。
Mac OS X 系统也是 unix-like 系统,也使用 zsh/bash,因此大部分命令基本都跟 Linux 没啥区别,
可以直接参考前面 Linux 一节的内容。
但是要注意一些坑:
- macos 自带的 tar 并不是 gnutar,命令使用方式不一样!
- 解决:
brew install gnu-tar
,安装好后通过 gtar
调用,参数就跟 linux 一致了。
- 网络相关的命令区别较大,后面会详细介绍。
- MacOSX 使用 launchpad 作为系统服务管理器,跟 systemd 区别很大。
Mac OS X 系统目前没有 ss
,但是自带 netstat
,该命令和 Linux 下的 netstat
有一定差别,
而且还很慢,还不能显示 pid.
所以 stackoverflow 上更推荐使用 lsof
,几条常用命令记录如下
1
2
3
4
5
6
7
8
9
10
11
| # -n 表示不显示主机名
# -P 表示不显示端口俗称
# 不加 sudo 只能查看以当前用户运行的程序
# 通用格式:
sudo lsof -nP -iTCP:端口号 -sTCP:LISTEN
# 查看所有 tcp 连接
lsof -nP -iTCP
# 查看所有监听端口相关的信息(command/pid)
lsof -nP -iTCP -sTCP:LISTEN
|
清理 DNS 缓存:
1
2
3
4
5
| # macos 10.10+
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# 其他版本请自己网上搜...
|
1
2
3
4
5
| # 查看所有网络接口及相关参数(ip/mac/type...)
ifconfig
# 查看路由表
netstat -nr
|
移动:
0
/^
回到行首,$
去到行末- w 跳到下个单词的首部,e 跳到下个单词末尾
删除 d
或修改 c
:
- dw 删除单词,d2w 删除两个单词
- d$ 删除到行末,
d0
/d^
删除到行首 d(
/d{
/d[[
删除到文件首部,d)
/d}
/d]]
删除到文件末尾r
替换一个字符,R
持续往后替换
多行插入,主要用于加注释之类的:
- 光标停留在你需要插入文本的地方
ctrl
+v
进入 visual block 模式,选中多行- 输入
I
,进入编辑模式 - 输入
#
注释或者其他字符,但是注意不能输入换行符!也不能删除? - 按两下
Esc
,依次退出 Insert 和 visual block 模式,就插入成功了
多行删除:
v
进入 visual 模式,在第一行,选中你想要删除的文本块- 或者也可以先进入 visual block 模式,再通过左右方向键选择文本。
ctrl
+v
进入 visual block 模式,选中多行- visual block 的特点是它是垂直选择,而 visual 模式是段落选择
- 按
d
键就能删除被选中的所有内容。
多行行首插入注释符号 #
:1,6 s/^/#/g
:2,$ s/^/#/g 注:此为2行至尾行
:% s/^/#/g 注:此为所有行
这里使用了正则表达式 ^
匹配行首,改成 $
就可在行尾进行批量修改。
此外,它的分隔符也不仅限于 \
,也可以用 @
等符号,方便阅读。比如:
:1,6 s@^@#@g
:2,$ s@^@#@g 注:此为2行至尾行
:% s@^@#@g 注:此为所有行
使用 vim 的这个正则匹配功能,不仅能进行插入,也能完成删除、替换的功能。
- 首先按
v
进入 visual 模式,选中需要的内容 - 按
:
,应该会显示 :'<,'>
,表示对选中部分进行操作 - 输入内容
w new.txt
,此时显示效果应该是 :'<,'>w new.txt
- 回车就能完成文件写入
解决方法:在命令模式下输入 :set paste
进入粘贴模式,然后再粘贴 yaml 内容。
注意行首可能会丢失几个字符,需要手动补上。