Appearance
Linux 简单有趣的命令
About 3053 wordsAbout 10 min
2022-06-08
本文不定期更新。
网络命令
nc tcp连接工具
nc 可以建立 TCP 连接
nc localhost 6379
连接后可以执行命令
set name jonkee
+OK
get name
$6
jonkee
telnet 端口测试
telnet mycloud 3306
ssh & sshpass 服务器连接
生成密钥对
# -t 指定加密算法
# -b 指定密钥的二进制位数
# -C 注释
ssh-keygen -t rsa -b 4096 -C "qiqiangvae@foxmail.com"
# 查看生成的密钥对
ls ~/.ssh/
上传公钥。也可以在服务器上创建一个~/.ssh/authorized_keys
文件,并修改权限为664,然后在将本地客户端内id_rsa.pub
的内容复制进去。
# -i 指定公钥文件
ssh-copy-id -i ~/.ssh/id_rsa.pub username@host
ssh 命令可以连接服务器,但是连接服务器的时候要输入密码,而sshpass可以免去手动输入密码的操作。
ssh -p 22 {username}@{ip}
sshpass -p {password} ssh -p 22 {username}@{ip}
ssh 还可以实现跳板机隧道功能。
如本机 Local 想要访问 Server 的 Port 端口,但是 Server 是在内网,无法访问,但是跳板机 Jump 可以访问 Server,而 Local 可以访问跳板机,此时可以使用ssh实现隧道功能。
# 要输入 jump 跳板机密码
ssh -N -f -L {localPort}:{ServerIP}:{ServerPort} {JumpUsername}@{JumpIP}
# 使用sshpass免去输入跳板机密码过程
sshpass -p {JumpPass} ssh -N -f -L {localPort}:{ServerIP}:{ServerPort} {JumpUsername}@{JumpIP}
此时连接 Local 的 localPort 就可以连接上 Server 的 ServerPort 了。
通过跳板机连接服务器,然后依次输入跳板机和服务器的密码。
ssh {ServerUsername}@{ServerIP} -p 22 -o ProxyCommand='ssh -p 22 {JumpUsername}@{JumpIP} -W %h:%p'
curl 网络请求客户端
curl 命令可以用来发送 web 请求。
# 发送 get 请求
curl https://www.baidu.com
# 头信息
curl -H 'Authorization:my-token' https://www.baidu.com
# 发送 cookie
curl -b 'name=muan;sex=1' https://www.baidu.com
# 存储响应 cookie
curl -c resp_cookie.txt https://www.baidu.com
# 发送 POST 请求
curl -X POST -d '{"username":"user","password":"pass"}' https://xxx.com/login
# 保存响应信息
curl -o resp.txt https://www.baidu.com
# 获取响应头
curl -I https://www.baidu.com
使用 | 符号 | 说明 |
---|---|---|
代理头 | -A | User-Agent |
请求头 | -H | Header |
发送 cookie | -b | |
存储响应 cookie | -c | |
发送 body | -d | |
指定 Http 请求方式 | -X | |
打印响应头和内容 | -i | |
仅仅打印响应头 | -I | 大写的 i |
保存响应信息 | -o |
scp 服务器间复制文件
在服务器之间复制文件和目录。scp fileName user@ip:fileName2
。
# 将 demo.log 复制到服务器的 /home/dc2-user 目录下
scp demo.log dc2-user@mycloud:/home/dc2-user
如果是复制目录,则需要加上参数-r
masscan & nmap 端口扫描
masscan 和 nmap 都可以扫描服务器开放的端口,nmap 可以扫描域名,masscan不可以。masscan 扫描速度比 nmap 快很多。
sudo masscan -p1-65535 xxx.xxx.xx.xxx
sudo nmap -sS -Pn -p1-65535 www.baidu.com
tcpdump 抓包工具
tcpdump 命令可以抓取指定网卡的指定ip和端口的数据包。
tcpdump -A dst xxx.xxx.x.xxx and port 3306 -w redis_dump.dump
文本命令
xargs 参数转换
xargs 的作用是将标准输入转为命令行参数。
简单的案例
echo "1.txt 2.txt 3.txt" | xargs touch
使用 xargs 批量删除redis key。以下命令的意思是,先找出所有的 key,然后通过 xargs 命令将结果用空格分开,然后删除。
redis-cli -a password -h localhost -p 6379 keys "*" | xargs redis-cli -a password -h localhost -p 6379 del
默认情况下 xargs 会将输入用空格或者换行符分割,也可以用 -d 指定分割符。
# -e 表示解释转义字符
echo -e "韩信\t李白\t百里守约" | xargs -d "\t" echo
输出
韩信 李白 百里守约
参数 | 解释 |
---|---|
-p | 打印需要执行的命令,询问是否执行,输入y或Y确认 |
-t | 打印需要执行的命令,不需要用户确认 |
awk 文本coding
每行按空格或TAB分割,输出文本中的1、4项;
awk '{print $1,$4}' log.txt
输出 java 进程的 pid;
ps -ef|grep java|awk '{print $2}'
输出
67396 69344 75192
-F 指定分隔符;
# -F 指定分隔符为 = awk -F '=' '{print $1,$2}' file.txt
-v 设置变量;
awk -F '=' -v p=2 '{print $1,$2,$2+p}' file.txt
指定列;
# 只输出第列的值等于2的行 awk -F '=' '{if ($2 == 2) print $1,$2}' file.txt # 指定多个分隔符,如 |$| awk -F '[|][$][|]' '{if ($2 == 2) print $1,$2}' file.txt
去重;
# 按=分割并去重 awk -F '=' '{print $3}' filename |awk '!a[$0]++'
分组;
# 多个分隔符,并按字段分组找出所有个数大于 1 的 awk -F '[|][$][|]' '{count[$10]++;} END {for(i in count) { if (count[i]>1){print i,count[i]}}}' filename
NF 代表当前行有多少个字段,即 NF-1代表倒数第二个字段。 NR 代表当前行数。
相关函数:
函数 | 说明 |
---|---|
length(str) | 返回字符串 str 的长度。 |
substr(str, start, length) | 返回字符串 str 从 start 开始,长度为 length 的子串。 |
split(str, arr, sep) | 把字符串 str 以分隔符 sep 分割成若干个部分,并将它们存储到数组 arr 中。 |
gsub(regexp, replacement, str) | 在字符串 str 中,用 replacement 替换所有匹配到的正则表达式 regexp。 |
sub(regexp, replacement, str) | 在字符串 str 中,用 replacement 替换第一个匹配到的正则表达式 regexp。 |
index(str, substr) | 查找字符串 str 中的子串 substr 第一次出现的位置。如果没有找到,则返回 0。 |
tolower(str) | 将字符串 str 转换成小写字母。 |
toupper(str) | 将字符串 str 转换成大写字母。 |
sprintf(format, expr1, expr2, ...) | 类似于 C 语言中的 sprintf() 函数,用于格式化输出。 |
rand() | 返回一个 0 到 1 之间的随机数。 |
grep 过滤神器
-C 10 或者 --context=10 显示前后 10 行的内容;
-A 10 或者 --after-context=10 显示之后 10 行的内容;
-B 10 或者 --before-context=10 显示之前 10 行的内容;
-v 显示不匹配的(忽略匹配的,即取反);
-n 显示行号;
grep -n 'search_txt' filename
-o 提取匹配的字符;
grep -o "pattern" filename
split 文件分割
按行分割,比sed命令截取好用;
split -l 1000 data.csv prefix
按大小分割;
split -b 1000 data.csv prefix
sed 文本编辑命令
注意
注意-i
是在源文件修改,-e
是输出到控制台,如果是修改源文件,需要加上备份文件的后缀,如果不想备份,输入空字符串。
替换字符串
sed 's/原字符串/替换字符串/g'
替换指定行
# 替换第10行的文本 sed '10c hello world' filename
删除行
# 删除第 10 行 sed -i '.bak' '10d' filename # 删除第 10-20 行 sed -i '.bak' '10,20d' filename
截取行数
# 截取第1行到第10行 sed -n '1,10p' filename # 截取第1行到第10行并输出到另一个文件 sed -n '1,10p' filename > new_filename # 截取第11行到文件末尾并输出到另一个文件中 sed -n '11,$p' filename > new_filename
wc 文本统计
- -c 或 --bytes 或 --chars 只显示 Bytes 数。
- -l 或 --lines 显示行数。
- -w 或 --words 只显示字数。
wc -l filename
wc -l命令时发现少了一行
如果在使用 wc -l 命令时发现少了一行,请注意以下几个问题:
- 换行符问题:wc 命令计算行数时,是根据换行符来判断的。如果您的文件最后一行没有以换行符结尾,那么 wc -l 命令就会将该行计算为不完整的一行,从而导致行数少一行。
- 文件编码问题:如果您的文件是以 Unicode 编码(如 UTF-8)保存的,并且文件头部没有明确指定编码格式,则 wc -l 命令可能会误判换行符的位置,导致行数计算错误。
- 行尾空格问题:如果您的文件最后一行有多余的空格或制表符,那么 wc -l 命令就会将这些空格或制表符也计算为一行的内容,从而导致行数计算错误。
如果您遇到了以上问题,可以尝试以下解决方案:
- 检查文件是否以换行符结尾,如果没有,请添加一个换行符。
- 如果文件使用 Unicode 编码,请在文件头部添加明确的编码格式,例如 # -- coding: utf-8 --。
- 检查最后一行是否有多余的空格或制表符,如果有,请删除它们。
vim 快捷键
按键 | 功能 |
---|---|
h 或者 ← | 向左移动 |
j 或者 ↓ | 向下移动 |
k 或者 ↑ | 向上移动 |
l 或者 → 或者空格 | 向右移动 |
[n]+空格 | 向右移动 n 格 |
[n]+方向 | 向某个方向移动n次 |
ctrl+f | 向下翻页 |
ctrl+b | 向上翻页 |
0 或者 home | 移动到该行的第一个字符处 |
$ 或者 end | 移动到该行的最后一个字符处 |
G | 移动到最后一行 |
H | 移动到第一行 |
[n]G | 跳转到第 n 行 |
/key | 向下搜索关键字 |
?key | 向上搜索关键字 |
n 或者 N | 根据/key或者?key的方向重复查找某个关键字。n和N方向相反 |
x 或者 X | x 向后删除,X 向前删除 |
[n]x | 连续删除 |
dd | 删除当前光标所在行 |
[n]yy | 复制一(多)行 |
p | 粘贴 |
:w [filename] | 另存为 |
:%d | 清空所有的内容 |
压缩命令
tar
加-z
表示 gzip,-c
压缩,-x
解压,-v
显示过程。
# 从文件 foo 和 bar 创建归档文件 archive.tar。
tar -cf archive.tar foo bar
# 详细列举归档文件 archive.tar 中的所有文件。
tar -tvf archive.tar
# 展开归档文件 archive.tar 中的所有文件。
tar -xf archive.tar
# 解压到指定文件夹
tar -xf archive.tar -C targetDir
系统命令
其它命令
nohup 不挂断运行
no hang up 不挂断。
nohup command > myout.log 2>&1 &
0 标准输入;
1 标准输出;
2 标准错误;
2>&1
是将标准错误2
重定向到标准输出&1
,&1
再重定向到myout.log
中。
编写一个脚本nohup_demo.sh
循环打印。
count=0
while [ $count -lt "100" ]; do
echo 'hello muan'
sleep 1s
count=$(expr $count + 1)
done
测试
# 启动
$ nohup sh nohup_demo.sh > demo.log 2>&1 &
80306
# 查看日志
$ tail -f demo.log
hello jonkee
hello jonkee
hello jonkee
hello jonkee
# 停止
$ kill -9 80306
mv 命令冷知识
mv 命令可以用来移动文件和改名,那么什么时候是移动文件什么时候是改名呢
# 新建两个文件夹
$ mkdir d1 d2
# 在d1里面新建两个文件
$ touch d1/f1 d1/f2
# 将d1改为d3
$ mv d1 d3
$ ls d3
f1 f2
# 将d3移入d2
$ mv d3 d2
$ ls d2/d3/
f1 f2
为什么最后一个命令不是将 d3 改名为 d2 呢?因为d2目录已经存在来,所以不会改名。
总结:目标文件不存在则改名,目标文件存在则移动。
tldr 最好用的命令文档
这个命令是Too Long; Didn't Read的缩写,这个名字很有趣
# mac 安装
brew install tlrc
# npm 安装
npm install -g tldr
# pip
pip3 install tldr
安装好之后可以查看命令,比如
tldr curl
curl
向 / 从一个服务器传输数据。
支持大多数协议,包括 HTTP, FTP, 和 POP3.
更多信息:https://curl.se/docs/manpage.html.
将指定 URL 的内容下载到文件:
curl http://example.com --output 文件名
将文件从 URL 保存到由 URL 指示的文件名中:
curl --remote-name http://example.com/filename
下载文件,跟随 重定向,并且自动 续传(恢复)前序文件传输:
curl --fail --remote-name --location --continue-at - http://example.com/filename
发送表单编码数据(application/x-www-form-urlencoded 的 POST 请求):
curl --data 'name=bob' http://example.com/form
发送带有额外请求头,使用自定义请求方法的请求:
curl --header 'X-My-Header: 123' --request PUT http://example.com
发送 JSON 格式的数据,并附加正确的 Content-Type 请求头:
curl --data '{"name":"bob"}' --header 'Content-Type: application/json' http://example.com/users/1234
使用用户名和密码,授权访问服务器:
curl --user 用户名 http://example.com
为指定资源使用客户端证书和密钥,并且跳过证书验证:
curl --cert client.pem --key key.pem --insecure https://example.com
简单的脚本案例
循环读取文件每一行并处理
无法读取最后一行
[[ -n ${line} ]]
加上这个判断是为了解决最后一行无法读取的问题
cat field.txt| while read line || [[ -n ${line} ]];
do
echo '- value:' $line
done