Linux 命令大放送!(第一辑)
涓涓细流,终汇大海。
在 "Shell 小技能" 一文中,讲到了 Shell 组合 linux 命令的实用小技能。每一条 linux 命令,都是一个小工具。 Shell 可以将很多小工具组合成更强大的实用工具。
本文主要梳理程序员常用到的 linux 命令。
文本命令
使用 lInux 命令处理临时任务,一大用场是文本处理。
文本命令模式,通常是通过 cat 获取文件内容,然后 grep 关键字 过滤出所需要的行,接着用 awk 或 cut 筛选列字段,最后用 sed 进行文本替换 或者 用 awk 格式化生成内容。文本处理的核心技能是正则表达式。
将值用引号括起来
orders.txt 是一个单列文本。每一行都是一个字符串值。
awk 'BEGIN{ORS=","}{print "\""$0"\""}' orders.txt
awk 'BEGIN{ORS=","}{print "\x27"$0"\x27"}' orders.txt
以下是提取日志关键字并构建数据库查询所需的 in 查询条件,常用于问题排查或线上故障后的数据修复。
cat webfileexist.txt | awk -F 'existDetectionId: ' '{print $2}' | grep -v "^$" | awk '{printf "%s%s", (NR>1?",":""), "\""$0"\""} END{print "]"}' | sed 's/^/[/'
筛选列并计数
给定文本格式:text1 = text 2 = 数值,输出满足某种条件的行或列并计数。
file=$1
total=`wc -l $file`
echo "total: $total"
avg=`cat $file | cut -f 3 -d'=' | awk '{a+=$1}END{print a/NR}'` // 求平均值
echo "avg: $avg"
above_num=`cat $file | cut -f 3 -d'=' | awk '{if ($1>=100) print $1}' | wc -l` // 找到大于 100 的行的计数
above_percent=`echo "$above_num $total" | awk '{printf("%0.1f%%\n",100*$1/$2)}'`
echo "more than 100ms percent: $above_percent"
筛选列并用空格分割输出
将 order.txt 的第一列和第二列输出,用空格符分割。
awk -F" " '{print $1" "$2}' order.txt
提取JSON 字符串中的指定字段的值
每一行都是:
{"level":"info","time":"2024-04-07T10:50:44.369Z","caller":"scheduler/cdc_check_task_execute_scheduler.go:131","msg":"build cdc task msg","tenantID":"","method":"(*CdcCheckTaskScheduler).buildTaskMsg","msg":{"fileId":"xxx","md5":"6debc533d08caa6181e2aa2b5682d6b7","sha256":"966d3230586dc211de801a229e333074f5ae7f1082779316ee4b9fadb60c14dd","fileSize":194,"fileType":"PHP","isZip":false,"timeout":300,"engineVersion":"2.5"}}
需要安装 jq 命令。
grep "sha256" cdc_send_messages.txt | jq -r '.msg.sha256'
grep "sha256" cdc_send_messages.txt | jq -r '.msg.sha256' | sort | uniq -d | wc -l
提取字符串
cat xxx.txt | grep -P "field=[a-zA-z]+" -o
cat xxx.log | grep -E "([0-9A-Z]+-)*[0-9A-Z]+" -o
排序去重
cat a.txt | sort | uniq
find . -name "*.java" > /tmp/javafile.txt && sed -E 's?^\./.+/([a-zA-Z]+\.java).*$?\1?g' /tmp/javafile.txt | sort | uniq -d
日志查看
zcat sys.log.5.gz |grep webshell_detection
tail -100f info.log | grep "method="
grep -E "A|B" info.log
ls info.20220616.* | xargs -I {} grep "cdcCheckCache hit is black" {} > /home/blackhit.log
ls info.20220615.* | xargs -I {} grep "send webshell cdc task to kafka, size" {} | cut -f 5 -d ":" | sed 's/^[ \t]*//g' | awk '{sum += $1};END {print sum}'
grep -r "cdcCheckCache hit is black" info.20220616.*
字符替换
cat a.sh | tr -s "a" "c"
cat a.sh | tr "a-z" "A-Z"
cat a.txt | tr -s "," "\n"
cat a.txt | tr -s "\n" " "
sed 替换
sed "s/old/new/g" a.sh // 不会改变 a.sh,
sed -i "s/old/new/g" a.sh // 直接将 a.sh 中的 old 全部替换成 new ,改变 a.sh
sed -E 's?^\./.+/([a-zA-Z]+\.java).*$?\1?g' javafiles.txt // 提取匹配 [a-zA-Z]+\.java 的内容
cat md.txt | sed -e 's/\(#\{1,\}\)$/\<br\/\>/g ; s/^\(#\{1,\}\)/\<br\/\> \1 /g'
sed -i -e 's/\(#\{1,\}\)$/\<br\/\>/g ; s/^\(#\{1,\}\)/\<br\/\> \1 /g' md.txt
sed -i -e 's/\(#\{1,\}\)$//g ; s/^\(#\{1,\}\)/\<br\/\> \1 /g' md.txt
// 在 port 下加一行
sed -i '/^ *port:.*/a\ serviceExecutor: adaptive' net.txt
// 去掉空行
sed '/^$/d' roujia.txt | tr '\n' ' ' | sed 's/ //g'
文件命令
文件命令是 linux 日常任务处理的第二大用武之地。
通常的做法是,是先用 find 命令筛选出符合条件的文件集合,然后结合 xargs 或 while 循环,和其它文件命令进行批量处理。
查找和删除文件
find ~/[0-9]* -name "*.csv" -mtime +29 -type f | while read file; do rm -f $file; done
find . -size +100M | xargs -I {} ls -hl {}
文件Hash
md5 /tmp/hello.txt
shasum -a 1 /tmp/hello.txt
shasum -a 256 /tmp/hello.txt
文件链接
ln
ln -s 要被链接的文件(已存在) 新的链接文件(不存在)
ln -s 源文件 目标链接文件
ln -s /usr/local/go/bin/go /usr/local/bin/go
修改文件权限
ls -d BEAUTYPIC2000* | xargs -I {} chmod 744 {}
文件拷贝
文件拷贝是日常任务处理的一个高频操作。务必要熟练掌握。
从 k8s pod 到宿主机
kcp.sh
#!/bin/bash
# cp files in k8s pod container to k8s host
# 指定Pod名称
POD_NAME=$(kubectl get po -A | grep xxx | awk '{print $2}')
NAMESPACE=$(kubectl get po -A | grep xxx | awk '{print $1}')
# 指定容器名称,默认为Pod的第一个容器
CONTAINER_NAME=main
# 指定宿主机上存放文件的目录
HOST_DIR="/tmp"
# 拷贝文件
kubectl exec ${POD_NAME} -n $NAMESPACE -c ${CONTAINER_NAME} -- bash -c 'cp /tmp/ids_method_costs_*.txt /workspace/ && ls /tmp/ids_method_costs_*.txt' | \
while read -r FILE; do
FILENAME=$(basename ${FILE})
HOST_FILE="${HOST_DIR}/${FILENAME}"
echo "kubectl cp ${POD_NAME}:${FILE} -n $NAMESPACE -c ${CONTAINER_NAME} ${HOST_FILE}"
kubectl cp ${POD_NAME}:${FILE} -n $NAMESPACE -c ${CONTAINER_NAME} ${HOST_FILE}
done
宿主机文件拷贝
bscp.sh
#!/bin/bash
# copy files in host A to local host
# 指定宿主机A的IP地址和登录凭证
HOST_A="someip"
USER_A="root"
PASSWORD_A="qingteng"
# 指定宿主机B上存放文件的目录
HOST_B_DIR="/Users/qinshu/Development/"
# 指定宿主机A上存放文件的目录
HOST_A_DIR="/tmp/"
file_list=$(sshpass -p ${PASSWORD_A} ssh ${USER_A}@${HOST_A} "ls ${HOST_A_DIR}/ids_method_costs_*")
# 拷贝文件
for file in ${file_list}; do
filename=$(basename ${file})
echo "sshpass -p ${PASSWORD_A} scp ${USER_A}@${HOST_A}:${file} ${HOST_B_DIR}/${filename}"
sshpass -p ${PASSWORD_A} scp ${USER_A}@${HOST_A}:${file} ${HOST_B_DIR}/${filename}
done
拷贝文件
kubectl cp -n $(kubectl get po -A | grep ids-detect | awk '{print $1}') -c main $(kubectl get po -A | grep ids-detect | awk '{print $2}'):dump.hprof /tmp/dump.hprof // pod => k8s
kubectl cp /root/arthas-client.jar -c main $(kubectl get po -A | grep ids-detect | awk '{print $1}')/$(kubectl get po -A | grep ids-detect | awk '{print $2}'):/workspace // k8s => pod
scp root@172.16.13.40:/tmp/dump.hprof ~/Documents // scp remote => local
本地拷贝文件和目录
cp file dir
cp -r files dir
cp -r src_dir dest_dir // => dest_dir/src_dir
cp -r src_dir/* dest_dir // => dest_dir/[aa.txt, sub]
cp -r files src/* dest // => dest_dir/[files, aa.txt, sub]
cp -r files src2_dir src/* dest // => dest_dir/[files, src2_dir, aa.txt, sub]
rm -rf dest/* # 删除 dest 下的所有目录和文件,但是不删除 dest 目录本身
远程主机间拷贝
scp file user@ip:dir
scp user@ip:dir file
scp -r eventflow-lib/1.0.0-RELEASE root@someip:/pathto/deploy/repository/com/common/eventflow-lib
批量处理
批量处理增强了 linux 命令处理的威力。
批量处理通常采用 xargs 命令。使用起来也比较简单,就是占位符模式。比如一个命令是 rm -rf somefile, 用 xargs 命令批量处理就是 xargs -I {} rm -rf {}。
批量复制/删除文件
find . -name "*.java" | xargs -I {} cp {} /tmp
find . -name "*.java" | xargs -I {} rm -rf {}
批量执行命令
以下命令先将 tt.py 通过替换文本 tt 为随机值的方式复制 3 个文件,然后找到所有 .py 文件,在 cmd.txt 批量写入命令 python3 xxx.py ,最后并发执行 cmd.txt 里的命令。
go run copy.go -n 3 -f tt.py -r tt && find . -maxdepth 1 -name "*.py" | xargs -I {} echo "python3 {}" > cmd.txt && go run multi_run.go -f cmd.txt
批量杀死符合关键字的进程
bkill.sh
#!/bin/bash
ps aux | grep "$1" | awk '{print $2}' | xargs -I {} sudo kill -9 {}
使用
chmod +x bkill.sh
./bkill python
批量截取列
## 批量处理
```bash
cat a.txt | xargs -I {} grep {} xyz.log | grep "key" | cut -f 2- -d'='
杀进程
杀死占用 80 端口的进程
注意:必须加 sudo 才会展示进程PID。
sudo netstat -lnp | grep :80
sudo kill -9 pid
源代码编译
很多 linux 开源软件,如果没有提供二进制包,就可以用如下三步轻松构建和生成可执行的二进制文件,将源代码变成实用软件。
./configure
make
make install
格式编码转换
图片格式转换
dwebp file.webp -o abc.png
find ./ -name "*.webp" -exec dwebp {} -o {}.png \;
ffmpeg -i file.webp out.png
编码转换
虽然很多时候有更好的图形界面来做音图视频编码或格式转换,但掌握一些命令,或许在特定场景下会更加高效。比如说视频剪切,我发现比图形界面快很多。
iconv -f gb18030 -t utf-8 origin.csv > new_utf8.csv // GB18030 转码为 utf8
iconv -f utf-8 -t gb18030 batch_express.csv > upload.csv // utf8 转 GB18030
ffmpeg
ffmpeg -i aa.rmvb -c:v libx264 -strict -2 aa.mp4 // 视频格式转换
视频剪切
ffmpeg -ss 00:00:00 -i xxx.avi -to 00:53:20 -c copy xxx.mp4
ffmpeg -ss 00:00:00 -i xxx.avi -to 00:53:20 -c copy -copyts xxx.mp4
ffmpeg -ss 00:00:00 -i MANCHENGFENGXU00116.mov -t 270 -c copy MANCHENGFENGXU00116c1.mp4
ffmpeg -i shengongyimeng.mp4 -ss 00:59:20 -to 01:03:17 -c copy shengongyimengc1.mp4
音频转换
ffmpeg -i inputfile.m4a -acodec libmp3lame -ab 93k outputfile.mp3
视频压缩
ffmpeg -i MANCHENGFENGXU00116c1.mp4 -y -vcodec libx264 -preset fast -b:v 5120k -vf scale=1600:1200,setdar=3:4 MANCHENGFENGXU00116c1ys.mp4
-b:v :指定视频的码率
-b:a : 指定音频的码率
1M:码率的值 1M 表示 1Mb/s
-r 20:表示帧率设置为 20fps
-vf scale=1600:1200表示分辨率为1600*200
ls *.mov |while read id;do (ffmpeg -i "$id" -y -vcodec libx264 -preset fast -b:v 5120k -vf scale=1600:1200,setdar=3:4 "${id%%.*}.mp4" );done
加密
gzexe : 加密可执行文件
gzexe a.sh
gzexe -d a.sh
tar + openssl
对filename文件(test.txt)进行加密压缩,生成filename.des3加密压缩文件,123@123为加密的密码
tar -zcf - test.txt | openssl des3 -salt -k 123@123 | dd of=test.txt.des3
将/mnt目录下的所有文件全部加密压缩
tar -zcf - /mnt/* | openssl des3 -salt -k 123@123 | dd of=test.des3
模拟匹配加密压缩
tar -zcf - /mnt/pass_* |openssl des3 -salt -k 123@123 | dd of=test.des3
解压解密:
dd if=test.txt.des3 | openssl des3 -d -k 123@123 | tar zxf -
加密:
tar -czf - * | openssl enc -e -aes256 -out test.tar.gz
enc 使用加密进行编码
-e 用来加密输入文件的 enc 命令选项,这里是指前一个 tar 命令的输出
-aes256 加密用的算法
-out 用于指定输出文件名的 enc 命令选项,这里文件名是test.tar.gz
解密:
openssl enc -d -aes256 -in test.tar.gz | tar xz -C /mnt/
-d 用于解密文件
-C 将加压后的文件提取到目标目录下
shc :脚本加密
shc -r -f text.sh
# 加过期时间
shc -e 28/02/2018 -m "this script file is about to expire" -v -r -f text.sh
zip 加密
zip -e filename.zip filename
zip -re dirname.zip dirname
GnuPG加密
gpg -c test.txt
网络命令
ping & telnet & tracert
ping www.baidu.com -c 4
telnet www.baidu.com 80
tracert www.baidu.com
route
linux: route -n
mac: netstat -nr
tcpdump 抓包
tcpdump -vv -i any -nn port 20881 -A
net config
sudo sysctl -a > ~/netconfig.txt
ports listener
sudo netstat -anp | grep port
ufw & iptables
sudo ufw enable | disable
sudo ufw status
sudo ufw default deny
sudo ufw allow 22/tcp
sudo ufw allow proto udp 192.168.0.1 port 53 to 192.168.0.2 port 53
iptables -nvL
iptables -F (flush 清除所有的已定规则)
iptables -X (delete 删除所有用户“自定义”的链(tables))
磁盘命令
磁盘相关的问题通常是磁盘空间不够了。想知道哪些资源占用磁盘空间大,以下命令很有效。
找到占用空间大的目录
sudo du -s -h /*
sudo du -s -h /var/lib/* | grep G
发现是 /var/lib/docker/overlay2 占用太大。使用
docker system prune
当前目录下的占用空间情况
du -ahx | sort -rh | head -5
du -d 1 -h | sort -rh | head -20
du -ah /var/ | sort -rh | head -10
du -hl --max-depth=1
du -hsx * | sort -rh | head -10
du -hsx .[^.]* | sort -rh | head -10
du -ah /data/ | grep G
df -h
du -h ~ | grep 'G'
du -h /dev/vda1 | grep 'G'
判断是否ssd
开发中,有些 IO 要求高的软件运行性能,会要求 SSD 盘。
cat /sys/block/vda/queue/rotational # 1 固态硬盘
lsblk -d -o name,rota #0 固态硬盘
在Linux系统中,可以使用以下命令来判断磁盘是否为SSD:
lsblk -d -o name,rota
该命令会列出所有磁盘的名称和旋转标志。如果旋转标志为0,则表示该磁盘是固态硬盘(SSD),如果旋转标志为1,则表示该磁盘是机械硬盘(HDD)。
另外,也可以使用以下命令来查看指定磁盘的详细信息,包括磁盘类型:
hdparm -I /dev/sda | grep "Model\|Firmware\|TRIM\|Rotation\|Transport\|SATA\|Form Factor"
其中,“/dev/sda”是要查询的磁盘设备文件名。如果输出结果中包含“Solid State Device”等字样,则表示该磁盘是固态硬盘(SSD)。
需要注意的是,以上命令都需要root权限才能执行。
安装软件
# ubuntu/debian
sudo apt-get install
sudo apt-get update
sudo apt-get remove
sudo dpkg -i xxx.deb
# centos
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install epel-release-latest-7.noarch.rpm
yum install -y nc
# linux
wget some_url | bash
系统服务
sudo service apache2 start
sudo service apache2 stop
sudo service apache2 status
sudo systemctl start NetworkManager
sudo service apache2 stop
sudo systemctl status NetworkManager
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了