公共基础
主机名
hostnamectl set-hostname xr
# 重新加载主机名
source /etc/profile && exec bash
ssh配置
vi /etc/ssh/sshd_config
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 0
systemctl restart sshd.service
环境变量
vi /etc/profile
历史记录
# 启用历史记录 需要重新登陆生效
export HISTCONTROL=ignorespace:ignoredups
export HISTSIZE=10000
export HISTFILESIZE=100000
export HISTTIMEFORMAT='%F %T '
shopt -s histappend
命令行特殊颜色
# 命令行特殊颜色
export PS1="\[\e[34m\][\u\[\e[m\]@\h \[\e[33m\]\w]\[\e[m\] \$ "
# 不执行命令也不超时退出
export TMOUT=0
操作命令搜索
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
常用命令别名
# 全盘搜索文件名
alias fn='find / -name 2>/dev/null'
# 常用操作简化
alias ccp='cp -rf'
alias rrm='rm -rf'
alias ll='ls -Alh --color=auto'
# 展示当前文件夹内所有文件和文件夹的实际大小
alias sp='du -sh *'
alias ttail='tail -200f'
# 递归搜索包含指定文本的文件并显示文件名和行号
alias gf='grep -inHr'
# 直接下载文件,忽略证书校验
alias wg='wget --no-check-certificate'
# 监控网络io
alias jkw='sar -n DEV 1 | grep -E "IFACE|eth0"'
# 监控磁盘io
alias jkc='sar -dp 1'
# yum专用
# 安装库
alias yi='yum -y install'
# 打印已安装的库
alias yl='yum list installed'
# 查找镜像库
alias ys='yum search'
# 查找已安装的库
alias yq='yum list installed | grep'
# 编译
alias by='make -j $(nproc)'
alias mi='make install'
alias rri='rpm -ivh'
go命令别名
# 命令别名
alias gb='go build'
alias gc='go clean -cache'
alias gcb='go clean -cache && go build -gcflags="-N -l"'
docker命令别名
alias dpg='docker ps |grep'
alias dif='docker images |grep'
K8S命令别名
alias kb='kubectl'
alias kbd='kubectl describe'
alias kbdp='kubectl describe pod'
alias kbds='kubectl describe service'
alias kbg='kubectl get'
alias kbgp='kubectl get pod'
alias kbgs='kubectl get service'
alias kbgd='kubectl get deployment'
alias kp="kubectl get pods -A -o wide"
alias kpv="kubectl get pods -n verse -o wide"
alias ks="kubectl get service -A -o wide"
alias ksv="kubectl get service -n verse -o wide"
alias kbe="kb exec -it"
alias kbev="kb exec -it -n verse"
PATH
# go
export GOROOT=
export PATH=$PATH:$GOROOT/bin
export GO111MODULE=on
export GONOSUMDB=*
export GOSUMDB=off
export GOPROXY=
export GOPATH=
export JAVA17_HOME=
export JAVA11_HOME=
export JAVA8_HOME=
export JAVA_HOME=$JAVA17_HOME
export PATH=$PATH:$JAVA_HOME/bin
export HELM_HOME=
export PATH=$PATH:$HELM_HOME/
export DOCKER_CONTENT_TRUST=0
更新环境变量
source /etc/profile && source ~/.bashrc
VIM行号
/etc/virc或者/etc/vimrc
echo "set number" >> /etc/virc
HISTTIMEFORMAT去掉只读
sudo sed -i 's/^EulerOS_variable_readonly HISTTIMEFORMAT/# EulerOS_variable_readonly HISTTIMEFORMAT/' /etc/profile.d/zzz_euleros_history.sh
生成ssh公私钥
ssh-keygen -t ed25519
用户管理
创建个人用户
useradd -g root -d /home/test -m -s /bin/bash test
磁盘管理
使用llvm机制,优点:
- 可以将多个物理分区合并到一个卷组,卷组可以理解为抽象出来的磁盘
- 如果将物理磁盘直接挂载,那么每个物理磁盘都需要一个挂载点,如果一个挂载点需要的容量超过了单个物理磁盘容量,那么就只能在业务代码中混入选挂载点再读写的逻辑,增加了业务复杂性
- 云上物理磁盘在线不停机扩容后,可以在物理分区上再创建分区,然后将新建的分区合入到卷组,卷组上的lv再动态扩容,这样就实现单个挂载点手动不停机扩容
查看磁盘挂载情况
lsblk
物理分区管理
fdisk -l
fdisk /dev/vda
新建物理分区
fdisk /dev/vda
格式化物理分区
这种只适合物理分区直接挂载的场景
fdisk -l
mkfs -t ext4 /dev/vda3
物理卷PV管理
新建物理卷PV
pvcreate /dev/vda3
pvdisplay
删除物理卷PV
需要保证pv上没有vg
pvdisplay
pvremove /dev/vda3
卷组VG管理
新建VG
vgcreate xplay /dev/vdc
将物理卷加入VG
fdisk -l
vgextend VolGroup /dev/vda3
从VG中删除物理卷
vgreduce -y VolGroup /dev/vda3
从VG中删除丢失的物理卷
vgreduce --removemissing
逻辑卷LV管理
扩容LV
前提是VG有剩余空间
# 将lv_root扩容VG剩余空间
lvextend -l +100%FREE /dev/VolGroup/lv_root
# lv_root扩容10G
lvextend -l +10G /dev/VolGroup/lv_root
缩容LV
lvreduce -L 5G /dev/VolGroup/lv_root
保存容量调整
resize2fs -f /dev/mapper/VolGroup-lv_root
删除lv
删除lv需要先停止当前lv的读写进程
lsof /var/log
fuser -vm /var/log
systemctl stop sysmonitor
systemctl stop ntpd
systemctl stop rsyslog
systemctl stop auditd
systemctl stop systemd-journald.socket
systemctl stop systemd-journald-dev-log.socket
systemctl stop systemd-journald.service
systemctl stop tuned
fuser -vm /var/log
umount -f /var/log
kill -9 1105 && umount -f /var/log
umount /var/log
lvremove /dev/VolGroup/lv_log
mkdir -p /var/log
vi /etc/fstab
# 删除/dev/mapper/VolGroup-lv_log /var/log
新建lv
vgdisplay
lvcreate -l +100%FREE -n lv_data VolGroup
mkdir /opt
mkfs -t ext4 /dev/mapper/VolGroup-lv_data
resize2fs -f /dev/mapper/VolGroup-lv_data
mount /dev/mapper/VolGroup-lv_data /opt
vi /etc/fstab
/dev/mapper/VolGroup-lv_data /opt ext4 defaults 1 1
重装系统盘后修复lv
sudo pvscan
sudo vgscan
sudo lvscan
mkdir /opt
mount /dev/xr/opt /opt
镜像包管理
挂载镜像
mkdir -p /opt/repository/iso/euler2.12-dvd
mkdir -p /opt/repository/iso/euler2.12-dev
mount -o loop EulerOS-V2.0SP12-x86_64-dvd.iso /opt/repository/iso/euler2.12-dvd
mount -o loop EulerOS-V2.0SP12-x86_64-DevelTool.iso /opt/repository/iso/euler2.12-dev
mkdir -p /opt/repository/iso/euler2.10-dvd
mkdir -p /opt/repository/iso/euler2.10-dev
mount -o loop EulerOS-V2.0SP10-x86_64-dvd.iso /opt/repository/iso/euler2.10-dvd
mount -o loop EulerOS-V2.0SP10-X86_64-DevelTool.iso /opt/repository/iso/euler2.10-dev
cd /etc/yum.repos.d/
vi EulerOS.2.10.repo
[EulerOS-2.10-dvd]
name=EulerOS-2.10-dvd
baseurl=file:///opt/repository/iso/euler2.10-dvd
enabled=1
gpgcheck=0
[EulerOS-2.10-dev]
name=EulerOS-2.10-dev
baseurl=file:///opt/repository/iso/euler2.10-dev
enabled=1
gpgcheck=0
vi EulerOS.2.12.repo
[EulerOS-2.12-dvd]
name=EulerOS-2.12-dvd
baseurl=file:///opt/repository/iso/euler2.12-dvd
enabled=1
gpgcheck=0
[EulerOS-2.12-dev]
name=EulerOS-2.12-dev
baseurl=file:///opt/repository/iso/euler2.12-dev
enabled=1
gpgcheck=0
重新构建缓存
yum clean all
yum makecache
脚本工具包
links.sh
将当前目录的脚本自动软链接到PATH
#!/bin/bash
#set -x
if [ $# -eq 0 ];
then
BASE_PATH=./
else
BASE_PATH=$1
fi
export BASE_PATH=$(cd "${BASE_PATH}"; pwd)
cd ${BASE_PATH}
TARGET_LN_PATH=/usr/local/bin
for file_name in $(ls *.sh)
do
short_file_name="${file_name%.*}"
temp=$(command -v "${short_file_name}")
if [ $? -ne 0 ];
then
if [ -f ${TARGET_LN_PATH}/${short_file_name} ] || [ -h ${TARGET_LN_PATH}/${short_file_name} ];
then
rm "${TARGET_LN_PATH}/${short_file_name}";
fi
ln -s "${BASE_PATH}/${file_name}" "${TARGET_LN_PATH}/${short_file_name}"
echo "[Info] added new soft link ${BASE_PATH}/${file_name} to ${TARGET_LN_PATH}/${short_file_name}"
fi
done
ulinks.sh
删除当前目录的脚本在PATH中的软连接
#!/bin/bash
#set -x
if [ $# -eq 0 ];
then
BASE_PATH=./
else
BASE_PATH=$1
fi
export BASE_PATH=$(cd "${BASE_PATH}"; pwd)
cd ${BASE_PATH}
TARGET_LN_PATH=/usr/local/bin
for file_name in $(ls *.sh)
do
short_file_name="${file_name%.*}"
temp=$(command -v "${short_file_name}")
if [ $? -eq 0 ];
then
echo "${short_file_name} exist"
elif [ -f ${TARGET_LN_PATH}/${short_file_name} ] || [ -h ${TARGET_LN_PATH}/${short_file_name} ];
then
rm ${TARGET_LN_PATH}/${short_file_name}
echo "[Info] removed soft link ${TARGET_LN_PATH}/${short_file_name}"
fi
done
hash -r # 清除所有缓存的命令路径
cf.sh
速记:content find
忽略带小写在指定目录下查找内容
#!/bin/bash
#set -x
if [[ $# -lt 1 ]];
then
BASE_NAME=$(basename $0)
echo "Usage: $BASE_NAME [path] <content>"
echo
echo "Find case-ignored <content> from all files in [path] and print match result. Default path: ."
exit 1
elif [[ $# -eq 1 ]];
then
FIND_PATH=.
FIND_CONTENT=$1
else
FIND_PATH=$1
FIND_CONTENT=$2
fi
grep -inHrT ${FIND_CONTENT} ${FIND_PATH}
样例
cf FIND
cf ./ FIND
ff.sh
速记:file find
在指定目录下查找文件
#!/bin/bash
#set -x
FIND_PATH=/
if [[ $# -lt 1 ]];
then
BASE_NAME=$(basename $0)
echo "Usage: $BASE_NAME [path] <fileName>"
echo
echo "Find <fileName> in [path] and child directories recursively. Default path is /"
exit 1
elif [[ $# -eq 1 ]];
then
FIND_NAME=$1
else
FIND_PATH=$1
FIND_NAME=$2
fi
find $FIND_PATH -name $FIND_NAME 2>/dev/null
ffe.sh
速记:file find except path
在指定目录下查找文件,并排除某个目录
#!/bin/bash
#set -x
if [[ $# -lt 3 ]];
then
BASE_NAME=$(basename $0)
echo "Usage: $BASE_NAME <path> <excludePath> <fileName>"
echo
echo "Find <fileName> in <path> and child directories recursively but not find in <excludePath>"
exit 1
fi
FIND_PATH=$1
EXCLUDE_PATH=$2
FIND_NAME=$3
find "$FIND_PATH" -type d -path "$EXCLUDE_PATH" -prune -o -name "$FIND_NAME" -print 2>/dev/null
用法:
ffe / /opt "*.sh"
kkm.sh
速记:kill kill memory
清理操作系统缓存
#!/bin/bash
sync;
echo 1 > /proc/sys/vm/drop_caches;
sync;
echo 2 > /proc/sys/vm/drop_caches;
sync;
echo 3 > /proc/sys/vm/drop_caches;
free -m
loop.sh
循环执行某个命令
#!/bin/bash
#set -x
if [[ $# -le 1 ]];
then
echo "<Usage> $0 <seconds> <command>"
exit 1
fi
WAIT_TIME="$1"
# 获取要执行的命令(从第二个参数开始)
shift # 移除第一个参数(等待时间)
COMMAND="$*" # 将所有剩余参数作为命令
#echo ${command}
# 无限循环,每隔5秒执行一次 dapr list
while true; do
echo "-----------------------------------------------------------------------------------------------------------------"
echo "------> $(date +'%Y-%m-%d %H:%M:%S')"
echo "------> ${COMMAND}"
# 执行 dapr list 命令
eval ${COMMAND}
# 等待5秒
sleep "$WAIT_TIME"
done
用法
loop 4 ps -ef
loop 4 'echo "hello world"'
ftar.sh
速记:file tar
选择最快的可用压缩方式并发压缩,并打印实际压缩的命令。压缩方式的顺序:zstd、lz4、pigz、gzip、tar
#!/bin/bash
set -x
# 检查是否提供了输入
if [ -z "$1" ]; then
echo "Usage: $0 <input_file_or_directory> [output_file]"
exit 1
fi
# 输入文件或文件夹
input="$1"
# 输出压缩文件
if [ -z "$2" ]; then
output_file="${input}"
else
output_file="$2"
fi
# 压缩函数
compress_with_tool() {
local tool="$1"
local input="$2"
local output="${output_file}.tar"
local compress_command
case "$tool" in
lz4)
echo "Using lz4 for compression..."
compress_command="tar cf - '$input' | lz4 -1 -f > '${output}.lz4'"
;;
pigz)
echo "Using pigz for compression..."
compress_command="tar cf - '$input' | pigz -p $(nproc) -f > '${output}.gz'"
;;
zstd)
echo "Using zstd for compression..."
compress_command="tar cf - '$input' | zstd -T0 -f > '${output}.zstd'"
;;
gzip)
echo "Using gzip for compression..."
compress_command="tar cf - '$input' | gzip -f > ${output}.gz"
;;
tar)
echo "Using tar for compression..."
compress_command="tar czf '${output}.gz' '$input'"
;;
*)
echo "No supported compression tool found!"
exit 1
;;
esac
# 打印使用的完整命令
echo "Compress Command: $compress_command"
eval "$compress_command"
}
# 检查工具是否安装并按照优先级选择
tools=("zstd" "lz4" "pigz" "gzip" "tar")
for tool in "${tools[@]}"; do
if command -v "$tool" &> /dev/null; then
compress_with_tool "$tool" "$input"
break
fi
done
# 检查压缩是否成功
if [ $? -eq 0 ]; then
echo "Compress successful: $output_file"
else
echo "Compress failed"
exit 1
fi
untar.sh
并发解压所有格式的压缩包,并打印实际解压的命令
#!/bin/bash
# 检查是否传入了文件名
if [ -z "$1" ]; then
echo "Usage: $0 <filename>"
exit 1
fi
FILENAME="$1"
EXTENSION="${FILENAME##*.}" # 获取文件后缀
# 检查是否安装了多线程工具
check_command() {
if command -v "$1" >/dev/null 2>&1; then
return 0 # 已安装
else
return 1 # 未安装
fi
}
# 根据文件后缀选择解压方法
CANNAND=""
case "$EXTENSION" in
gz)
if check_command "pigz"; then
CANNAND="tar -I pigz -xf $FILENAME"
else
CANNAND="tar -xzf $FILENAME"
fi
;;
bz2)
if check_command "pbzip2"; then
CANNAND="tar -I pbzip2 -xf $FILENAME"
else
CANNAND="tar -xjf $FILENAME"
fi
;;
xz)
if check_command "pxz"; then
CANNAND="tar -I pxz -xf $FILENAME"
else
CANNAND="tar -xJf $FILENAME"
fi
;;
tar)
CANNAND="tar -xf $FILENAME"
;;
zip)
CANNAND="unzip $FILENAME"
;;
rar)
CANNAND="tar -zxf $FILENAME"
;;
tgz)
CANNAND="tar -zxf $FILENAME"
;;
zstd)
CANNAND="zstd -d -c $FILENAME | tar -xf -"
;;
lz4)
CANNAND="lz4 -d -c $FILENAME | tar -xf -"
;;
*)
echo "Unsupported file extension: .$EXTENSION"
exit 1
;;
esac
echo "Command: ${CANNAND}"
eval "$CANNAND"
# 检查是否解压成功
if [ $? -eq 0 ]; then
echo "Extraction completed successfully."
else
echo "Extraction failed."
exit 1
fi
up.sh
查找当前用户的某个java进程
#!/bin/bash
CurrentUser=`whoami`
SearchWord=$1
ps -u $CurrentUser -f | grep -v grep | grep java | grep $SearchWord
ups.sh
打印当前用户的所有java进程
#!/bin/bash
CurrentUser=`whoami`
ps -u $CurrentUser -f | grep -v grep | grep java
cost.sh
执行一个shell命令并显示实际花费的秒数,不过实际效果和time命令差不多
#!/bin/bash
#set -x
if [[ $# -lt 1 ]];
then
echo "<Usage> $0 <command>"
exit 1
fi
COMMAND="$*"
# 记录开始时间
echo "------> Starttime: $(date +'%Y-%m-%d %H:%M:%S')"
echo "------> ${COMMAND}"
start_time=$(date +%s)
# 执行命令
"$@"
# 记录结束时间
end_time=$(date +%s)
# 计算耗时
duration=$((end_time - start_time))
echo "------> Endtime: $(date +'%Y-%m-%d %H:%M:%S')"
echo "------> Cost: ${duration}"
用法
cost tar czf test.tar.gz test/