言成言成啊 | Kit Chen's Blog

那些年,我玩过的Bash脚本

发布于2022-05-26 15:39:29,更新于2025-03-26 22:21:27,标签:devops shell  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

一些bash脚本的条件,可以通过man test查询手册或者在线linux手册

以下脚本均为原创,在实际工作中总结而出的!

一、前置环境

1.1 脚本头

对于shell脚本而言,可以支持多种编程语言,比如bash、dash、python、php等。

运行 shell 脚本,有两种方式。

第一种,执行 sh test.sh 这是直接指明解释器是 sh 了,如果 sh 映射的是 dash,那么就使用 dash 执行。

第二种,授予可执行权限 chmod +x test.sh,执行命令 ./test.sh,这个会根据脚本首行去找对应的解释器。

像下面该行代码,是定义在脚本的第一行,通过环境变量寻找指定的解释器来执行。

1
#!/usr/bin/env bash or dash or python or php

CentOS 中默认的 shell 是指 bash

Debian 中默认的 shell 是指 dash

1.2 常用工具包

安装常用命令,像ifconfig、zip、unzip、wget、vim、yum-plugin-downloadonly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env bash

set -e
# 更换yum源,参考[centos镜像-centos下载地址-centos安装教程-阿里巴巴开源镜像站](https://developer.aliyun.com/mirror/centos)
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 基础repo
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 备用repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 清空旧缓存、生成新缓存
yum clean all
yum makecache

yum -y install net-tools vim zip unzip wget yum-plugin-downloadonly telnet expect

echo "更换yum base、epel源为阿里repo"
echo "安装常用工具"

1.3 yum仓库切换至归档Vault

本文大部分是基于 CentOS7 总结而来的,自从 CentOS7 停止维护后,yum 使用就受到了影响。因此需要将 yum 源切换到 Vault 归档库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env bash
set -e

# 日志打印函数
function log() {
echo "$(date +"%Y-%m-%d %H:%M:%S"): $1"
}

# ==== 检测系统版本 ====
detect_centos_version() {
log "正在检测当前系统版本..."

# 获取 CentOS 版本号
if [[ -f /etc/centos-release ]]; then
vault_version=$(awk '{print $4}' /etc/centos-release)
else
log "未找到 /etc/centos-release,无法确定版本。"
exit 1
fi

log "检测到 CentOS 版本:$vault_version"
}

# ==== 备份已有 repo 文件 ====
backup_existing_repos() {
log "正在备份旧的 *.repo 文件..."

backup_dir="/etc/yum.repos.d/backup-$(date +%Y%m%d%H%M%S)"
mkdir -p "$backup_dir"
mv /etc/yum.repos.d/*.repo "$backup_dir"

log "已备份至 $backup_dir"
}

# ==== 创建 Vault repo 文件 ====
create_vault_repo() {
log "正在创建新的 CentOS-Base.repo..."

cat <<EOF > /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$vault_version - Base (Vault)
baseurl=http://vault.centos.org/$vault_version/os/\$basearch/
enabled=1
# 禁用下载软件包时,进行gpgkey的校验
gpgcheck=0
priority=1

[updates]
name=CentOS-$vault_version - Updates (Vault)
baseurl=http://vault.centos.org/$vault_version/updates/\$basearch/
enabled=1
gpgcheck=0
priority=1

[extras]
name=CentOS-$vault_version - Extras (Vault)
baseurl=http://vault.centos.org/$vault_version/extras/\$basearch/
enabled=1
gpgcheck=0
priority=1
EOF

log "CentOS-Base.repo 创建完成"
}

# ==== 刷新 yum 缓存 ====
refresh_yum_cache() {
log "正在清理并刷新 yum 缓存..."
yum clean all
yum makecache
log "yum 缓存已刷新"
}

# ==== 主流程 ====
main() {
detect_centos_version
backup_existing_repos
create_vault_repo
refresh_yum_cache
log "已完成 Vault 仓库切换,当前使用版本:$vault_version"
}

# 将命令行传入的参数,传给main函数。此处实际没用到
main "$@"

二、一键脚本

2.1 vsftpd

一键安装vsftpd,ftp主动模式与被动模式_brother小果的博客-CSDN博客_ftp被动模式和主动模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/env bash

# 安装vsftp
installVsftpd() {
yum -y install vsftpd ftp
status=$?
if [ ${status} != 0 ]; then
echo "请检查是否能连接网络 or 是否能连接到yum仓库 or 强制退出"
exit 1
fi
# >表示覆盖 >>表示追加
cat >> /etc/vsftpd/vsftpd.conf <<EOF
#FTP访问目录
local_root=/data/ftp/
# 配置只能访问指定目录,chroot_list文件中列出的用户,可以切换到其他目录;未在文件中列出的用户,不能切换到其他目录。
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
allow_writeable_chroot=YES
# 配置时区
use_localtime=YES
# 被动模式端口范围,如果防火墙需要暂时放行30000-30010端口,需要firewall-cmd --zone=public --add-port=30000-30010/tcp
pasv_max_port=30010
pasv_min_port=30000
# 默认就是支持被动模式
# pasv_enable=yes
# 监听端口,默认是21
listen_port=66
# 主动传输端口
ftp_data_port=68
# 开启用户操作日志
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
# 设置连接数
max_clients=1000
max_per_ip=1000
EOF
mkdir -p /etc/vsftpd/chroot_list
mkdir -p /data
useradd -d /data/ftp/ ftpadmin
chown -R ftpadmin /data/ftp
systemctl restart vsftpd
echo "vsftpd安装成功"
echo "通过 systemctl [status|start|stop|restart|enable|disable] vsftpd 进行操作"
echo "成功创建用户ftpadmin,通过 passwd ftpadmin 进行配置密码"
}

# 关闭selinux
disableSeLinux(){
# -s file 文件大小非0时为真
if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
# 将SELINUX=enforcing更换为SELINUX=disabled
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
echo "关闭selinux"
fi
}


ls /usr/lib/systemd/system/vsftpd.service
status=$?
# 0表示找到了服务 非0表示没有服务 判断相等带空格
if [ $status == 0 ]; then
echo "vsftpd安装成功"
echo "通过 systemctl [status|start|stop|restart|enable|disable] vsftpd进行操作"
else
disableSeLinux
installVsftpd
fi

之后通过如下命令,配置密码。

1
passwd ftpadmin

然后就可以直接连接了。

1
2
3
4
5
6
# 连接
ftp 127.0.0.1
# 查询
ls
# 上传
put 本地文件 远程文件

2.2 openjdk

一键安装jdk11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/user/bin/env bash
set -e

# 安装jdk 参数为jdk版本
function installJdk() {
yum -y install java-$1-openjdk java-$1-openjdk-devel
cat > /etc/profile.d/java$1.sh <<EOF
# readlink读取到javac软连接,再读取软连接获取到真实链接,然后往上级目录走两次,走一次是java/bin,再走一次是java
export JAVA_HOME=\$(dirname \$(dirname \$(readlink \$(readlink \$(which javac)))))
export PATH=\$PATH:\$JAVA_HOME/bin
export CLASSPATH=.:\$JAVA_HOME/jre/lib:\$JAVA_HOME/lib:\$JAVA_HOME/lib/tools.jar
EOF
# 刷新环境变量
source /etc/profile.d/java$1.sh

java -version
javac -version
echo $JAVA_HOME
}

echo "可选java-openJdk版本如下:"
echo "java-1.8.0-openjdk 1"
echo "java-11-openjdk 2"
printf "输入你要安装的openJdk版本"
# 读取键盘输入信息
read -p "(Default: 1):" select
# 默认赋值
[ -z "${select}" ]&&select=1

# 判断选项
if [ "${select}" == 1 ];then
select="1.8.0"
else
select="11"
fi
installJdk ${select}

2.3 mongo

一键安装mongo4.4.14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env bash
set -e
# >全覆盖写入 \可以进行转义
cat > /etc/yum.repos.d/mongodb-org-4.4.repo <<EOF
[mongodb-org-4.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc
EOF

yum install -y mongodb-org-4.4.14 mongodb-org-server-4.4.14 mongodb-org-shell-4.4.14 mongodb-org-mongos-4.4.14 mongodb-org-tools-4.4.14

if [ -s /etc/mongod.conf ] && grep '127.0.0.1' /etc/mongod.conf; then
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mongod.conf
fi

systemctl restart mongod
echo "=================================================================================================================================="
echo "mongo数据库已经启动,命令行输入mongo即可连接"

2.4 kafka

一键安装kafka

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env bash
set -e

metadata="kafka-metadata"

# 获取局域网ip 已有函数取值用$(getIp)
function getIp() {
ip addr | grep inet | grep -v inet6 | grep -v docker | grep -v 127.0.0.1 | awk '{print $2}' | sed 's|/.*||'
}

# 下载kafka
function downKafka() {
curl -o kafka.tgz https://archive.apache.org/dist/kafka/3.3.1/kafka_2.13-3.3.1.tgz
}

# 解压kafka
function decompressKafka() {
if [ -s $1 ]; then
tar -zxvf kafka.tgz > tar.log
cat tar.log|head -n 1|tr -d "/"
fi
}

# 初始化kafka配置
function initKafkaConfig() {
if [ -s $1 ]&&grep "localhost" $1 ; then
sed -i "s/localhost/$(getIp)/g" $1
echo "kafka监听地址:$(getIp):9092"
fi

if [ -s $1 ]&&grep "tmp" $1 ; then
sed -i "s/tmp/${metadata}/g" $1
echo "kafka元数据地址:/${metadata}"
fi
}

# 创建shell脚本
function createShell() {
# 已有函数变量取值用$(),自定义变量取值用${}
cat > ${root}/kafka-start <<EOF
${root}/$1/bin/kafka-storage.sh format -t T1CYXg2DQPmdSYSUI-FNFw -c ${root}/$1/config/kraft/server.properties
nohup ${root}/$1/bin/kafka-server-start.sh ${root}/$1/config/kraft/server.properties >/dev/null 2>&1 &
EOF
chmod +x ${root}/kafka-start
echo "启动命令: sh ${root}/kafka-start "

cat > ${root}/kafka-stop <<EOF
${root}/$1/bin/kafka-server-stop.sh -c ${root}/$1/config/kraft/server.properties
EOF
chmod +x ${root}/kafka-stop
echo "关闭命令: sh ${root}/kafka-stop"
}

root=$(pwd)
downKafka
kafkaPackage=$(decompressKafka "${root}/kafka.tgz")
initKafkaConfig "${root}/${kafkaPackage}/config/kraft/server.properties"
createShell "${kafkaPackage}"
rm -rf tar.log kafka.tgz

2.5 postgresql

一键安装psql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env bash
#set -e

PSQL_VERSION=11
PGIS_VERSION=30

# 安装postgisClient
function installPostgisClient() {
yum -y install postgis${PGIS_VERSION}_${PSQL_VERSION}-client
}

# 安装postgis
function installPostGis() {
yum -y install epel-release
yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum -y install postgis${PGIS_VERSION}_${PSQL_VERSION}
}

# 安装pgRouting
function installPgRouting() {
yum -y install pgrouting_${PSQL_VERSION} osm2pgrouting_${PSQL_VERSION}
}

# 安装postgresql
function installPsql() {
# 安装 RPM:
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# 安装 PostgreSQL:
sudo yum install -y postgresql${PSQL_VERSION}-server
# 初始化数据库并设置开机自启动
sudo /usr/pgsql-${PSQL_VERSION}/bin/postgresql-${PSQL_VERSION}-setup initdb
sudo systemctl enable postgresql-${PSQL_VERSION}
# 开启远程访问
psqlConf="/var/lib/pgsql/${PSQL_VERSION}/data/postgresql.conf"
if [ -s ${psqlConf} ];then
cat >> ${psqlConf} <<EOF
# 开启postgresql的远程可访问
listen_addresses = '*'
EOF
else
echo "psql没有该配置文件${psqlConf},可能是脚本已不适用!"
echo "码农最伟大的地方就是能够实现他的完美!"
exit 1
fi
pghbaConf="/var/lib/pgsql/${PSQL_VERSION}/data/pg_hba.conf";
if [ -s ${pghbaConf} ]; then
cat >> ${pghbaConf} <<EOF
host all all 0.0.0.0/0 md5
EOF
else
echo "psql没有该配置文件${pghbaConf},可能是脚本已不适用!"
echo "码农最伟大的地方就是能够实现他的完美!"
exit 1
fi
sudo systemctl restart postgresql-${PSQL_VERSION}
}

printf "使用postgresql-11与postgis-30? (y/n "
read -p "Default: y):" select
[ -z "${select}" ]&&select="y"
case ${select} in
"n")
printf "输入你要安装postgresql的版本 "
read -p "(Default: 11):" PSQL_VERSION
printf "输入你要安装的postgis的版本 "
read -p "(Default: 30):" PGIS_VERSION
;;
esac

echo "可选安装如下:"
echo "postgresql 1"
echo "postgis 2"
echo "pgrouting 3"
echo "postgis-client 4"

# 读取键盘输入信息
printf "输入你要安装的内容,不选输入n"
read -p "(Default: n):" select
# 默认赋值
[ -z "${select}" ]&&select="n"

# 安装
# 判断选项
case ${select} in
"n")
echo "本次不安装"
exit 0
;;
"1")
echo "本次安装postgresql"
installPsql
;;
"2")
echo "本次安装postgis"
installPostGis
;;
"3")
echo "本次安装pgrouting"
installPgRouting
;;
"4")
echo "本次安装postgis-client"
installPostgisClient
;;
esac

2.6 nginx

一键安装nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env bash

set -e

NGINX_VERSION="1.22.0"
NGINX_TARBALL="nginx-${NGINX_VERSION}.tar.gz"
NGINX_SRC_DIR="nginx-${NGINX_VERSION}"
NGINX_INSTALL_DIR="/usr/local/nginx"
NGINX_SERVICE_FILE="/etc/systemd/system/nginx.service"


# 修改响应头Server内容
MODIFY_SERVER_HEADER=true
NEW_NAME="Pingora"
NEW_VER="0.1.0"
# src/core/nginx.h
# src/http/ngx_http_header_filter_module.c
# src/http/ngx_http_special_response.c
# src/http/v2/ngx_http_v2_filter_module.c

# 日志打印函数
function log() {
echo "$(date +"%Y-%m-%d %H:%M:%S"): $1"
}

# 下载 nginx
function downloadNginx() {
log "正在安装必要依赖..."
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

log "正在下载 nginx-${NGINX_VERSION}..."
curl -k -L "https://nginx.org/download/${NGINX_TARBALL}" -o nginx.tgz
}

# 解压 nginx
function decompressNginx() {
if [ ! -f "$1" ]; then
log "错误:未找到 $1"
exit 1
fi

log "正在解压 nginx..."
# 将其内容提取到 nginx 目录,去掉文件路径中的前一级目录(即 --strip-components=1)
tar -zxvf "$1" --strip-components=1 -C nginx
log "解压完成"
}

# 编译 nginx
function makeNginx() {
if [ ! -d "$1" ]; then
log "错误:未找到 $1 目录"
exit 1
fi

cd "$1"

if [ "$MODIFY_SERVER_HEADER" = true ]; then
log "修改 nginx Server 头信息..."
sed -i "13s/1.22.0/$NEW_VER/" src/core/nginx.h
sed -i "14s/nginx/$NEW_NAME/" src/core/nginx.h
sed -i "22s/\"NGINX\"/\"$NEW_NAME\"/" src/core/nginx.h
sed -i "49s/nginx/$NEW_NAME/" src/http/ngx_http_header_filter_module.c
sed -i "36s/nginx/$NEW_NAME/" src/http/ngx_http_special_response.c
replace_text="if (nginx_var[0] == '\\\0') {\
p = ngx_http_v2_write_value(nginx_var,\
(u_char *) NGINX_VAR,\
sizeof(NGINX_VAR) - 1, tmp);\
nginx_var_len = p - nginx_var;\
}\
pos = ngx_cpymem(pos, nginx_var, nginx_var_len);"
sed -i "505s|.*|$(printf '%s' "$replace_text")|" src/http/v2/ngx_http_v2_filter_module.c
sed -i '271s/.*/len += 1 + nginx_var_len;/' src/http/v2/ngx_http_v2_filter_module.c
sed -i '151s/.*/static size_t nginx_var_len = ngx_http_v2_literal_size(NGINX_VAR);static u_char nginx_var[ngx_http_v2_literal_size(NGINX_VAR)];/' src/http/v2/ngx_http_v2_filter_module.c
fi

log "配置编译选项..."
./configure --with-http_stub_status_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_v2_module
#--prefix="$NGINX_INSTALL_DIR" \

log "开始编译 nginx..."
# make是单线程编译。make -j$(nproc)是多线程编译。
make -j$(nproc)
make install
log "nginx 编译安装完成"
}

# 配置 systemd
function configNginx() {
log "配置 nginx systemd 服务..."
cat > "$NGINX_SERVICE_FILE" <<EOF
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
ExecStart=$NGINX_INSTALL_DIR/sbin/nginx
ExecReload=$NGINX_INSTALL_DIR/sbin/nginx -s reload
ExecStop=$NGINX_INSTALL_DIR/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
log "systemd 配置完成"

log "配置nginx环境变量..."
cat > /etc/profile.d/$NGINX_SRC_DIR.sh <<EOF
# readlink读取到javac软连接,再读取软连接获取到真实链接,然后往上级目录走两次,走一次是java/bin,再走一次是java
export PATH=\$PATH:$NGINX_INSTALL_DIR/sbin
EOF
# 刷新环境变量
source /etc/profile.d/$NGINX_SRC_DIR.sh
log "配置nginx环境变量完成"
}

# 执行安装流程
mkdir -p nginx
downloadNginx
decompressNginx nginx.tgz
makeNginx nginx
configNginx

log "nginx 安装成功,版本号 ${NGINX_VERSION}"
log "nginx 运行命令:"
log "-- 启动/关闭/重启: systemctl start|stop|restart nginx"
log "-- 设置开机自启: systemctl enable|disable nginx"

2.7 httpd

由于httpd版本迭代太频繁,特地做了个离线包,存储在我的个人云盘

一键安装httpd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env bash
#
# 安装httpd服务器
# Copyright 2022 meethigher
set -e

# 安装apr
function installApr() {
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-1.7.0.tar.gz
tar -zxf apr-1.7.0.tar.gz
cd apr-1.7.0
# ./configure --prefix=/etc/apr/
./configure
make && make install
cd ..
}

# 安装apr-util
function installAprUtil() {
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-util-1.6.1.tar.gz
tar -zxf apr-util-1.6.1.tar.gz
cd apr-util-1.6.1
#./configure --prefix=/etc/apr-util --with-apr=/etc/apr
./configure --with-apr=/usr/local/apr
make && make install
cd ..
}

# 安装httpd
function installHttpd() {
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/httpd/httpd-2.4.54.tar.gz
tar -zxf httpd-2.4.54.tar.gz
cd httpd-2.4.54
#编译
./configure \
--with-include-apr \
--disable-userdir \
--enable-headers \
--with-mpm=worker \
--enable-modules=most \
--enable-so \
--enable-deflate \
--enable-defate=shared \
--enable-expires-shared \
--enable-rewrite=shared \
--enable-static-support \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr/bin \
--with-ssl \
--with-z

make && make install
cd ..

configHttpd "/usr/local/apache2/bin/httpd"
}

function configHttpd() {
if [ -s $1 ]; then
cat >/usr/lib/systemd/system/httpd.service <<EOF
[Unit]
Description=httpd
After=network.target

[Service]
Type=forking
ExecStart=$1 -k start
ExecReload=$1 -k restart
ExecStop=$1 -k stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
# 重新加载systemd
systemctl daemon-reload
fi
}

mkdir test
cd test
yum -y install wget gcc zlib zlib-devel pcre-devel openssl openssl-devel expat-devel perl
installApr
installAprUtil
installHttpd
cd ..
rm -rf test
echo "httpd安装成功"
echo "httpd运行命令:"
echo "--启动/关闭/重启:systemctl start|stop|restart httpd"
echo "--自启动/非自启动: systemctl enable|disable httpd"
echo "--测试配置文件:/usr/local/apache2/bin/httpd -t"

2.8 php

由于php版本迭代太频繁,特地做了个离线包,存储在我的个人云盘

一键安装php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env bash
set -e
function downloadPhp() {
# wget --no-check-certificate https://www.php.net/distributions/php-7.4.30.tar.gz
yum -y install libxml2 libxml2-devel sqlite-devel libtool libcurl libcurl-devel libpng-devel libjpeg-devel freetype freetype-devel
# curl -o libzip-1.3.2.tar.gz https://libzip.org/download/libzip-1.3.2.tar.gz
tar -zxvf libzip-1.3.2.tar.gz
cd libzip-1.3.2
./configure
make && make install
# 不配置这个编译php时,是找不到zip的
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/"
cd ..
tar -zxf php-7.4.30.tar.gz
cd php-7.4.30
path=$(pwd)
./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-pdo-mysql --with-curl --with-openssl --enable-gd --with-jpeg=/usr/local/libjpeg/ --with-freetype=/usr/local/freetype/ --with-zip=/usr/local/lib/libzip
make && make install
# cp php.ini-production /usr/local/lib/php.ini
# 隐藏X-Powered-By: PHP,编辑php.ini expose_php = Off
# 查看php配置文件路径: php --ini
# 更新apache使用的php7 module
libtool --finish "$path/libs"
}

downloadPhp

2.9 mysql

一键安装mysql8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env bash
# https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html
set -e
yum -y install https://dev.mysql.com/get/mysql80-community-release-el7-6.noarch.rpm
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
yum -y install mysql-community-server
# 查看临时密码
systemctl restart mysqld
pwd=$(cat /var/log/mysqld.log | grep 'temporary password'|awk '{print $13}')
echo "临时密码${pwd}"
echo "选择数据库use mysql;"
echo "修改密码策略set global validate_password.policy=LOW;"
echo "修改用户密码ALTER USER 'root'@'localhost' IDENTIFIED BY 'meethigher';"
echo "设置远程登录update user set host='%' where user='root';"
echo "刷新权限flush privileges;"
echo "远程登录权限grant all privileges on *.* to 'root'@'%';"
echo "操作mysql服务systemctl restart mysqld"
mysql -u root -p

2.10 maven

一键安装maven3.6.3

3.8以上不支持http,对使用者不友好,经常需要手动拉包。建议不用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env bash
# maven3.8以上不再支持http,所以使用次新版3.6
# 下载maven
curl -X GET --output apache-maven-3.6.3-bin.tar.gz https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.tar.gz
# 解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz
mv apache-maven-3.6.3 /usr/local/maven/

# 环境变量
cat > /etc/profile.d/maven.sh <<EOF
export PATH=\$PATH:/usr/local/maven/bin
EOF
# 刷新环境变量
source /etc/profile
# 查看版本
mvn -v
rm -rf apache-maven-3.6.3-bin.tar.gz

2.11 openssl升级

yum安装的默认是1.0.2版本,该版本会存在CVE-2016-2183漏洞。

因此需要升级到1.1.1进行解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
yum -y install wget gcc zlib zlib-devel pcre-devel openssl openssl-devel perl
curl -L -X GET -o openssl-1.1.1l.tar.gz https://www.openssl.org/source/openssl-1.1.1l.tar.gz
tar -zxvf openssl-1.1.1l.tar.gz
cd openssl-1.1.1l
./config shared zlib
make && make install
# 备份
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
# 软链接
ln -s /usr/local/bin/openssl /usr/bin/openssl
ln -s /usr/local/include/openssl /usr/include/openssl
# 软链接,旧版lib不用清掉,只要上面的bin修改,就会自动引用相应版本的lib
ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
openssl version -a

2.12 history显示时间

临时添加环境变量history带时间

1
export HISTTIMEFORMAT="$(whoami) %Y/%m/%d %T "

临时取消环境变量

1
unset HISTTIMEFORMAT

查看环境变量

1
env

三、常用操作

3.0 基础

内核版本

查看centos系统版本

1
2
cat /etc/centos-release
cat /proc/version

过滤查看文件

查看匹配行以及匹配行的上下文

1
2
3
4
5
6
7
8
# 查看包含4的行
cat log|grep 4
# 查看包含4的行,并附带匹配行的前2行。before-context
cat log|grep 4 -B 2
# 查看包含4的行,并附带匹配行的后2行。after-context
cat log|grep 4 -A 2
# 查看包含4的行,并附带匹配行的前后2行。context
cat log|grep 4 -C 2

查看log文件倒数10行内容

1
cat log|tail -n 10

查看log文件前10行内容

1
cat log|head -n 10

每秒监控内容打印控制台

1
watch -n 1 "cat log|tail -n 10"

vi编辑时,向下搜索/关键字回车

vi编辑时,向上搜索?关键字回车

vi全局替换时,输入:1,$s/原始字符/替换字符/g回车

编辑网卡信息

1
2
3
vi /etc/sysconfig/network-scripts/ifcfg-ens33
# 重启网络
systemctl restart network

查看ip地址

1
2
3
ip addr
# 该命令需安装yum -y install net-tools
ifconfig

如果配置了静态ip,但是没生效。

ONBOOT是指明在系统启动时是否激活网卡。

将配置文件里的参数onboot改为yes即可。

测试连通

1
ping 10.0.0.10

测试端口连通

yum -y install telnet

1
telnet 10.0.0.10 9090

netstat端口

查看进程占用的端口

netstat 若没有,需安装

yum -y install net-tools

1
netstat -nplt

控制台打印结果并将结果保存到文件

1
netstat -nplt|tee log

查看与8031端口建立的连接

1
2
3
4
5
6
7
netstat -ano | grep 8031
# 查看所有建立的连接
netstat -ano | grep 8031| grep ESTABLISHED
# 统计所有建立的连接的行数
netstat -ano | grep 8031| grep ESTABLISHED | wc -l
# 与上个命令相同作用的Windows命令
netstat -ano | findstr 8031 | findstr ESTABLISHED | find /c /v ""

在Windows cmd中计算行数_cmd 统计行数_aban-mtd的博客-CSDN博客

ps进程

查看进程-查看当前连接bash的进程

1
ps -ef|grep bash

查看进程的详细信息

1
ps -efv|grep bash

关机重启运维

关机

1
poweroff

重启

1
reboot

定时执行

1
2
3
4
# 10min后重启
shutdown -r +10
# 10min后关机
shutdown -P +10

自动输入密码

《Centos系统——Expect自动化交互式程序应用》_逻辑思维菜鸟的博客-CSDN博客_expect简介 centos

Centos expect spawn、linux expect 用法 - 人艰不拆_zmc - 博客园

先安装expect

1
yum -y install expect

创建自动脚本

1
vi pull

输入以下内容,以git为例,git pull并自动输入密码,timeout单位是秒

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/expect
set user "dasini"
set pass "dasini"
set timeout 10

spawn git pull origin
expect "Username*"
send "$user\n"
expect "Password*"
send "$pass\n"
expect eof

执行命令

1
expect -f pull

立即释放磁盘空间

方法一:

删除文件,并关闭使用文件的对应进程。

1
2
3
rm -rf 文件名
lsof | grep deleted | grep 文件名
kill -9 pid

详细的lsof命令可以查看3.9

方法二:

写入空内容。

1
echo > 文件名

3.1 磁盘

查看磁盘空间

1
df -h

查看当前路径下占用大小

1
du -h -x --max-depth=1

查看超过1G以上文件夹

1
du -h -x --max-depth=1|grep G

3.2 内存

查看内存空间

1
free -h

动态内存空间(进程下所有线程状态)

1
htop

htop不存在的话,需要通过yum -y install htop安装

字段含义

  • PID:进程号

  • USER:发起该进程的用户

  • PRI:进程优先级

  • NI:进程的优先级别

  • VIRT:进程占用的虚拟内存

  • RES:进程占用的物理内存

  • SHR:进程占用的共享内存

  • S:进程的状态

    1. R:正在运行

    2. S:休眠

    3. Z:僵死

    4. N:线程优先级是负数

  • CPU%:进程占用的总cpu百分比

  • MEM%:进程占用的总内存的百分比

  • TIME%:进程占用cpu的时长

  • Command:进程的启动命令

3.3 全局搜索

全局搜名字是nginx的文件

1
find / -name nginx

3.4 防火墙

firewalld是centos7新增的防火墙管理工具,旧版的是iptables

基本的防火墙开启/关闭/重启/状态/自启动/非自启动命令

1
systemctl start|stop|restart|status|enable|disable firewalld

查看防火墙的所有zone

1
firewall-cmd --get-zones

查看防火墙默认的zone

1
firewall-cmd --get-default-zone

防火墙的zone共有9个,详细查看firewalld-zone概念介绍 - 春分拂柳 - 博客园

添加开放端口

1
2
3
4
# 暂时打开,不需要重启
firewall-cmd --zone=public --add-port=21/tcp
# 永久打开,需要重启
firewall-cmd --zone=public --add-port=21/tcp --permanent

删除开放端口

1
2
3
4
# 暂时删除,不需要重启
firewall-cmd --zone=public --remove-port=21/tcp
# 永久删除,需要重启
firewall-cmd --zone=public --remove-port=21/tcp --permanent

不关闭服务的刷新防火墙

1
firewall-cmd --reload

查看防火墙所有放行内容

1
firewall-cmd --list-all

查看防火墙放行端口

1
firewall-cmd --zone=public --list-ports

3.5 语言与时区

更换时区

1
2
3
4
5
6
7
8
9
10
11
12
# 查看当前时间
date -R
# 设置当前时间
date -s "2023-11-11 10:10:10"
# 查看当前时区
timedatectl
# 查看亚洲时区
timedatectl list-timezones | grep "Asia/S"
# 更换时区为亚洲/上海
timedatectl set-timezone "Asia/Shanghai"
# 重启
reboot

与网络时间同步

1
2
3
yum -y install ntp ntpdate
# 后面的时间地址即win系统的时间服务
ntpdate time.windows.com

更换系统语言

1
2
3
4
5
6
7
8
# 查看当前语言
localectl
# 查询中文
localectl list-locales |grep CN
# 更改系统语言
localectl set-locale LANG=zh_CN.utf8
# 重启
reboot

3.6 ssh登录日志

修改配置文件

1
vi /etc/ssh/sshd_config

操作ssh服务

1
systemctl [start|stop|restart|enable|disable] sshd

快捷查看方式

1
2
3
4
5
6
7
8
9
# 查看ssh在线用户
who
# 查看最近登录记录,或者直接查看文件/var/log/lastlog
last
# 查看最近登录失败记录,或者直接查看文件/var/log/btmp
lastb
# 取出攻击次数最多的前三个ip(两种)
lastb | head -n -2 | awk '{print $3}' | sort | uniq -c | sort -nr | head -3
lastb | tr -s ' ' | cut -d" " -f3 | sort | uniq -c | sort -nr | head -3

3.7 ab压测工具

apache-bench压测工具

安装

1
yum -y install httpd-tools

使用get与post执行一个压测,总共20个请求,开两个线程执行

执行post请求

1
ab -n 20 -c 2 -p test -T "text/plain" -H "token:test" https://meethigher.top/upload

执行get请求

1
ab -n 20 -c 2  -H "origin-referer:test" https://meethigher.top/

执行post请求,压测60秒

1
ab -t 60 -c 10 -p empty https://meethigher.top/

3.8 局域网最大带宽

使用iperf3工具测试局域网最大带宽

1
2
3
4
5
yum install -y iperf3
# 在一台机器上运行此命令作为服务器
iperf3 -s
# 在另一台机器上运行此命令作为客户端,其中<server_ip>为服务器的IP地址
iperf3 -c <server_ip>

windows版地址

3.9 lsof简记

lsof全名为list open files

在 Linux 操作系统中,几乎所有的事物(如文件、目录、网络套接字、设备等)都被当作文件来处理,因此 lsof 可以用于监视和调试多种资源的使用情况。

  1. 查看进程打开的文件lsof 可以显示特定进程或所有进程当前打开的文件。这对于调试和监控非常有用,尤其是在处理文件锁定问题或资源泄露时。

    1
    lsof -p <pid>   # 显示特定进程 ID (<pid>) 打开的文件
  2. 查看文件被哪个进程打开:当需要知道某个特定文件正在被哪些进程使用时,lsof 是一个非常方便的工具。

    1
    lsof <filename>   # 显示指定文件 (<filename>) 被哪些进程打开
  3. 网络套接字监控lsof 可以显示网络相关的信息,如哪个进程在使用哪个端口,哪些网络连接处于打开状态等。

    1
    2
    lsof -i   # 显示所有打开的网络套接字
    lsof -iTCP:80 # 显示所有使用 TCP 80 端口的连接
  4. 查看用户打开的文件:可以查看特定用户打开的所有文件,有助于监控用户活动。

    1
    lsof -u <username>   # 显示特定用户 (<username>) 打开的文件
  5. 检测删除但仍被占用的文件:有时候文件被删除了,但系统中某些进程仍在使用它们,这会占用磁盘空间。lsof 可以帮助找到这些文件。

    1
    lsof | grep deleted   # 查找被删除但仍在使用的文件

四、致谢

shell中 set 指令的用法_曹灰灰的博客-CSDN博客_set shell

强大的一键部署网站架构工具Oneinstack_延瓒@yankerp的博客-CSDN博客_oneinstack

fengyuhetao/shell: Linux命令行与shell脚本编程大全案例

hi-dhl/fast_guides: 10分钟入门Shell脚本编程

在IDEA编写Shell脚本_1024GB的博客-CSDN博客_idea编写shell脚本

Linux Shell脚本参数传递的2种方法_残风乱了温柔的博客-CSDN博客_shell脚本传递参数命令

Linux shell条件判断if中的-a到-z的意思 - 简书

shell脚本中$0 $1 $# $@ $* $? $$ 的各种符号意义详解 - 一口Linux - 博客园

shell local命令_qq_28391549的博客-CSDN博客_local命令

shell命令之 tr_不是杠杠的博客-CSDN博客_shell命令tr

Linux - Shell 脚本中获取本机 ip 地址方法_栗少的博客-CSDN博客_linux获取ip地址shell

centos 7 查看所有登录用户的操作历史_代码浪人的博客-CSDN博客_centos7查看登录记录

linux shell中’’,””和``的区别 其实``跟$()作用一样

Linux shell 中$() ``,${}作用与区别_ai_xiangjuan的博客-CSDN博客_linux shell {}

liunx 中如何删除export设置的环境变量_weixin_33775582的博客-CSDN博客

history 命令带时间显示 - 简书

Linux Shell系列教程之(十三)Shell分支语句case … esac教程 - 走看看

Linux Shell case语句_zh521zh的博客-CSDN博客

Linux shell脚本 (十二)case语句_青豆1113的博客-CSDN博客

linux全局搜索文件_m0_54853420的博客-CSDN博客_linux全局搜索

Centos防火墙开放端口_波波仔86的博客-CSDN博客_centos防火墙开放端口

ftp主动模式与被动模式原理

vsftpd的主动模式与被动模式防火墙端口配置

发布:2022-05-26 15:39:29
修改:2025-03-26 22:21:27
链接:https://meethigher.top/blog/2022/onekey-shell/
标签:devops shell 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏