Skip to content

[学习]Linux最常见的命令+Bash Shell脚本编程

操作系统版本

# 简要
uname -a
uname -r
cat /proc/version

# 这个结果很全面
apt install -y lsb && lsb_release -a

CPU

# 查看物理cpu个数
grep 'physical id' /proc/cpuinfo | sort -u | wc -l

# 查看核心数量 – CPU cores
grep 'core id' /proc/cpuinfo | sort -u | wc -l

# 查看线程总数 – 也就是逻辑CPU
grep 'processor' /proc/cpuinfo | sort -u | wc -l

# 限制某个进程的 CPU 使用
cpulimit --pid 17918 --limit 80 --background

# CPU占用最多的前10个进程
ps auxw | head -1; ps auxw | sort -rn -k3 | head -10 

网络

# 查看网络端口的使用情况
lsof -i:50001-50010
# 当前iP
curl ip.sb # 更快
curl ip.3322.net # 要慢
ip addr
# 获取dns配置
cat /etc/resolv.conf 

硬盘或文件 find/du/df

find / -name caddy
find / -name ".*jpg"

# 当前目录下(包括子目录)寻找所有大于 200M 的文件
find . -type f -size +200M
# 对查找结果按照文件大小做一个排序
find . -type f -size +200M  -print0 | xargs -0 du -h | sort -nr
# 查看当前目录下某个类型的文件或数量
find . -type f -print | grep php
find . -type f -print | grep php | wc -l

# 只找第二层子目录的文件
find . -maxdepth 2 -mindepth 2 
find . -name '*.gz' -exec tar -zxvf {} \;  

# move all files >4G to the parent folder 
find ./ -size +4G -exec mv {} ../ \;

# 查找的时候忽略某些folder (./data, ./drive等)
find . -path ./data -prune -false -o -size +500M -print0 | xargs -0 ls -l
find . \( -path ./data -o -path ./drive \) -prune -false -o -size +500M -print0 | xargs -0 ll

# 查找文件排序
# -h human-readable
# -S show hidden files
# -d2 2 levels
# -rh reverse sort & human-readable
du -hS -d1 | sort -rh
# 查找当前目录(往下走2层)下前20的大目录
du -hm --max-depth=2 | sort -nr | head -20

内存

# 当前的空闲内存
free -m
# 获取内存相关的信息
cat /proc/meminfo
dmidecode --type memory

# 查看内存占用最多的10个进程
ps auxw | head -1; ps auxw | sort -rn -k4 | head -10

加虚拟内存SWAP

# 创建一个512M的数据类型文件
cd /
dd if=/dev/zero of=swapfile bs=1024 count=1046576
# 把文件变成swap
mkswap swapfile
## 设置该文件仅供所有者读和写
chmod 0600 swapfile 
# 开启
swapon swapfile
# 关闭
swapoff swapfile
# 查看,这两行相同
swapon -s # 等同于 --show
cat /proc/swaps
# 查看swap分区活动状态
free -h 

# 变成自动加载,打开配置文件
vi /etc/fstab
# 在最后加上这行
/swapfile     swap     swap     defaults     0     0

swapon – 一键搜

### 如果合在一起用这条, 2G = 2000000, 100MB = 100000
cd / && dd if=/dev/zero of=swapfile bs=1024 count=1000000 && chmod 0600 swapfile && mkswap swapfile && swapon swapfile && free -h
# 确认无误的话,设置开机自启
echo '/swapfile     swap     swap     defaults     0     0' >> /etc/fstab && tail /etc/fstab

Hostname

# 临时修改当前的主机名
hostname new_name
# 永久性修改主机名 cloud.cfg取决于有没有按照cloud-init
if [-e /etc/cloud/cloud.cfg]; then sed -i "s/^preserve_hostname: false.*/preserve_hostname: true/g" /etc/cloud/cloud.cfg; fi
hostnamectl set-hostname new_name
# 查看当前的主机ip
hostname -I

Sed – Stream Editor 流编辑

sed flag 'range command' input.file

# -n 默认会打印pattern space的每一行;-n to suppress; 通常和p也就是打印命令同时用;只打印相应的行
sed -n '2,4p' input.file # 打印第2行到第4行,注意,共3行
sed -n '2p' input.file
sed -n '2,+3p' input.file # 打印第二行,和之后的3行(所以到第5行)

sed '2d' input.file # 删除第二行

# s是替换,g是s命令的全局标示,把改行当中所有匹配的都替换掉
# 注意,这个不直接修改文件,而是到stdout
sed 's/abc/123/g' input.file 

# -i: in place
# 直接把第47行删除,适合目标机重装系统的情况
sed -ig '47d' /Users/hwang/.ssh/known_hosts

# 将文件当中的所有出现的字符串全部替换掉;并同时生成备份文件 /etc/shadowsocks.json.bak
sed -i.bak 's/aes-256-cfb/aes-256-gcm/g' /etc/shadowsocks.json

# [[:space:]] 可用于linux/mac当中,作为空格,tab键的对应
# -r 用extended regular expression - 这样+就不用写成 \+ 
# + 标示1或多个,也可以写成 {1,}
sed -nr '/^a[[:space:]]+bcd/p' test 
# 等同于 (仅在linux下,mac不work,不知道为什么)
sed -n '/^a[[:space:]]\+bcd/p' test

# 以下等同
# \1 代表第一个()当中捕获的匹配
sed    's/^a[[:space:]]\+\(.*\)/a_and_multiple_space\1/g' test
sed -r 's/^a[[:space:]]+(.*)/a_and_multiple_space_\1/g' test 

# -e可以接多个命令
sed -n -e '2d' -e '3 s/123/abc/g' input.file 


me@banshee:~$ sudo netstat -anp | grep ::80
tcp6       0      0 :::80                   :::*                    LISTEN      4011/apache2  

me@banshee:~$ sudo netstat -anp | grep ::80 | sed 's/.*LISTEN *//'
4011/apache2  

awk – 对行进行分割处理

# think of awk as a column extractor
me@banshee:~$ sudo netstat -anp | grep apache
tcp6       0      0     :::80                   :::*                    LISTEN      4011/apache2    

# output to the 4th tabular column only
me@banshee:~$ sudo netstat -anp | grep apache | awk '{print $4}'
:::80

# 4th & 7th
me@banshee:~$ sudo netstat -anp | grep apache | awk '{print $4, $7}'    
:::80 4011/apache2

# 可以做计算
me@banshee:~$ cat awktext.txt
1 2 3
4 5 6
7 8 9

me@banshee:~$ cat awktext.txt | awk '{SUM+=$2}END{print SUM}'
15

# predefined special variable NR 是默认行数
me@banshee:~$ cat awktext.txt | awk '{SUM+=$2}END{print SUM/NR}'
5

Process

# search by name
ps auwx | grep -i <process_name>
# 全部干掉
pkill -f <process_name>

# top来寻找各种process的资源占用
top
# h: help
# t: cpu stats
# m: memory stats
# R: sort, 然后用 < > 键来选择不同的排序列

Screen – 可以save & resume sessions

# create a new session named session_name or attach if already exists
screen -d -R session_name
# Ctrl + A + D: detach
# 修复乱码
## 可以在全局的screenrc文件里加 (通过whereis screenrc) 
## 也可以在用户 ~/.screenrc 里加入如下设置:
cat >> ~/.screenrc <<EOF
# 编码
defutf8 on
defencoding utf8
encoding UTF-8 UTF-8
# 新建screen,则能正确显示
EOF

安装包清理

# 查看安装包缓存大小
du -sh /var/cache/apt/archives
# 使用如下命令删除已经安装过的deb包; 删除孤儿软件包-已经没有用处的依赖
apt-get clean; apt-get autoclean; apt-get autoremove
# 清除手动安装的依赖包
deborphan
sudo apt-get install deborphan
deborphan | xargs sudo apt-get purge -y

日志

# 控制systemctl服务产生的日志大小和保留ui'jm
journalctl --vacuum-time=8w --vacuum-size=200M

# 使用 ”> 文件名“ 清理日志文件;
root@localhost:/home/wwwlogs# > limbopro.xyz.log
root@localhost:/home/wwwlogs# > access.log 

# 可以在crontab -e 当中添加日志清理
0 0 1,15 * * echo '' > /home/wwwlogs/limbopro.xyz.log; #每月1和15号自动清理日志
0 0 1,15 * * echo '' > /home/wwwlogs/access.log; #每月1和15号自动清理日志

# 用ncdu工具来查看大日志文件
apt install -y ncdu
ncdu /var/log #然后按i键

显示中文

# 让terminal 显示中文 - 在~/.zshrc中加入
export LC_ALL=en_US.UTF-8 

时区

# 查看系统时区
timedatectl
ls -l /etc/localtime
# 显示所有的可选时区
timedatectl list-timezones
# 设置新时区 - 重启后依然有效
timedatectl set-timezone Asia/Shanghai

/sbin /bin /usr/sbin /usr/bin

# /sbin - system commands(shutdown,reboot)
# /bin - common commands(ls, chmod)
# /usr/sbin - user level system commands, 在后期安装的系统管理的必备程式, samba、sendmail
# /usr/bin/ - user level common commands, 在后期安装的一些软件的运行脚本

xargs

# 大多数命令都不接受标准输入作为参数,只能直接在命令行输入参数

# xargs命令的作用,是将前一个命令的标准输出转为后一个命令的命令行参数。
# xargs将换行符和空格作为分隔符,把标准输入分解成一个个命令行参数。
echo "one two three" | xargs mkdir
# =>
mkdir one two three

# -d 改变分隔符
echo -e "a\tb\tc" | xargs -d "\t" echo

# -p参数打印出要执行的命令,询问用户是否要执行。
echo 'one two three' | xargs -p touch
# -t参数则是打印出最终要执行的命令,然后直接执行,不需要用户确认。

# xargs后面的命令默认是echo
# 大多数时候,xargs命令都是跟管道一起使用的。但是,它也可以单独使用。
# 输入xargs按下回车以后,命令行就会等待用户输入,作为标准输入。你可以输入任意内容,然后按下Ctrl d,表示输入结束,echo命令就会把前面的输入打印出来。

find . -type f -name "*.log" -print0 | xargs -0 rm -f
# xargs -0 将 \0 作为定界符。不然默认用空格,可能会影响文件名带有空格的文件。

#如果标准输入包含多行,-L 参数指定多少行作为一个命令行参数。不然是把所有行的输出变成一个输入,执行一次。
find . -name "*.sh" | xargs -L 1 echo
#有几行就执行几次

# -n参数指定每次将多少项,作为命令行参数
echo {0..9} | xargs -n 2 echo
# 把每两个数字作为一个输入项

# 一次将参数传给多条命令
# 自动针对每行输入执行一串命令(echo & mkdir)
echo -e "name1 1.1\n name2 2.1 2.2\n name3 3.1 3.2" | xargs -p -I PlaceHolder sh -c 'echo PlaceHolder; mkdir PlaceHolder'

#xargs默认只用一个进程执行命令。如果命令要执行多次,必须等上一次执行完,才能执行下一次。
#--max-procs参数指定同时用多少个进程并行执行命令。--max-procs 2表示同时最多使用两个进程,--max-procs 0表示不限制进程数。
docker ps -q | xargs -n 1 --max-procs 0 docker kill

Bash Shell脚本编程

# 变量
$? 返回值,0是没问题,其他都有
$0 函数名
$1 第一个参数
$@ 所有变量放在一起
Mac-mini at ~ ❯ function tmpfunc() { echo $0; echo $1; echo $@;}
Mac-mini at ~ ❯ tmpfunc 1 2 3
tmpfunc
1
1 2 3

# 用 [[ ]] 做test比较安全
# 字符串包含
if [[ "$STR" == *"$SUB"* ]]; then
  echo "It's there."
fi

# 赋值
var_name='7'
echo $var_name # === echo ${var_name}

# 列表
name=(A B C) # 对应的index是从1开始
echo ${name[0]} # 空
echo ${name[1]} # A

# while
index=0
while [[ $index -lt ${#id[@]} && -z "$record_id_found" ]]
  if [[ "${name[index]}" == *"$HOSTNAME_TO_FIND"* ]]; then
      record_id_found=${id[index]}
  fi
  index=$[$index+1]
  if 
done
unset index # 取消全局变量

# 直接从程序当中退出
if [ ${#name[@]} != ${#id[@]} ]; then
  echo "Config file Disrupted!!"
  echo "Please re-generate config.json file (run configure.bash)"
  exit
fi

# 取值
${var_name}
# 执行命令,然后将结果输出
echo $(date)
# 计算
echo $[7+1]

# 管道
BESTIP=$(sed -n "2,1p" result.csv | awk -F, '{print $1}')

# 默认所有变量都是全局,需要unset
# 或者用local
local name=($(echo $CF_00IDEA_DOMAINS | jq -r '.result[].name'))

tar压缩打包和解压

-x:解压
-t:查看内容
-r:向压缩归档文件末尾追加文件
-u:更新原压缩包中的文件
-j:有bz2属性的
-Z:有compress属性的

# 参数-f是必须的
# -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。

# 压缩
# -c: 建立压缩档案
# -z:有gzip属性的
# -v:显示所有过程
cd source_parent_folder && tar -czvf file.tar.gz ./source_child_folder

# 解压 自动在当前目录创建 souce_child_folder并解压
cd target_folder && tar -xzvf file.tar.gz

一些技巧

# 把命令的输出放到另外一个命令当中
echo $(hostname -I | awk '{print $1}')
# 上一次重启
last reboot
# 这次活了多久了
uptime

Leave a Reply

Your email address will not be published.