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

posted @ 2024-06-15 22:56  琴水玉  阅读(18)  评论(0编辑  收藏  举报