Linux服务器初始化

94 阅读4分钟

公共基础

主机名

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/