我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统。陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户。
虽然我编写了非常详细的在线文档,说明如何在不同系统环境下安装部署,但依然不时收到用户的咨询,我想,能否搞个 真一键部署 的脚本出来呢?
摸索了几天,真给搞定了,我通过 Linux Bash 实现了以下几个功能:
- 支持从 Ubuntu 裸机状态部署。
- 实现一条命令搞定一切,不再需要手敲命令一步一步操作。
- 参数配置部分,支持图形界面。
- 自动安装 Nginx、MySQL 等所需组件。
- 自动配置 Nginx 站点、MySQL 数据库。
- 自动启动主程序服务。
我将在本文详细介绍我是如何编写这样一个 bash 脚本的,并且在文章后方列出了总结的 base 脚本编写常见问题。
效果展示 💡
Ubuntu 一键部署:
if [ -f /usr/bin/curl ]; then curl -sSO https://files.shengxunwei.com/kf/installscript/install.sh; else wget -O install.sh https://files.shengxunwei.com/kf/installscript/install.sh; fi; chmod +x install.sh; bash install.sh
如何编写实现一键安装脚本
Linux Bash(Bash 是 "Bourne Again Shell" 的缩写)是一个命令行解释器和脚本语言,它是大多数 Linux 系统的默认 shell(命令行界面)。Shell 是一个程序,它允许用户通过输入命令来与操作系统交互,进行文件管理、程序运行等操作。
Bash 提供了强大的功能,比如:
- 命令行交互:可以输入命令来执行各种操作,如文件操作、程序启动、网络配置等。
- 脚本编程:可以将一系列命令写入脚本文件,并批量执行。常用于自动化任务和系统管理。
- 管道和重定向:支持通过管道将一个命令的输出作为另一个命令的输入,或者将输出重定向到文件中。
- 变量与控制结构:Bash 脚本支持变量、循环、条件判断等结构,帮助构建复杂的脚本。
- 强大的编辑功能:可以使用历史命令、自动补全、命令替换等功能,提高效率。
编写 .sh
脚本(Shell 脚本)其实很简单,主要是写一系列的 Linux 命令,通过脚本自动执行:
1. 创建一个 .sh
脚本文件
首先,你需要在 Linux 系统中创建一个文件,扩展名通常是 .sh
,例如 myscript.sh
。
touch myscript.sh
2. 编写脚本命令
在脚本文件中,你可以写下需要执行的命令和逻辑。比如:
#!/bin/bash
# 打印欢迎消息
echo "Hello, World!"
# 定义一个变量
my_variable="This is a shell script!"
# 打印变量
echo $my_variable
# 使用条件判断
if [ -f /path/to/file ]; then
echo "File exists"
else
echo "File does not exist"
fi
# 使用循环
for i in {1..5}; do
echo "Iteration $i"
done
3. 设置文件权限
你需要确保脚本文件具有可执行权限。使用 chmod
命令:
chmod +x myscript.sh
4. 运行脚本
一旦你完成了脚本并且设置了可执行权限,就可以通过以下命令运行它:
./myscript.sh
示例:一个简单的 Shell 脚本
下面是一个稍微复杂一些的示例,展示了如何使用输入参数、文件操作和简单的循环:
#!/bin/bash
# 检查用户是否提供了输入
if [ -z "$1" ]; then
echo "Usage: $0 <filename>"
exit 1
fi
# 获取传入的文件名
filename=$1
# 检查文件是否存在
if [ -f "$filename" ]; then
echo "File $filename exists."
# 打印文件的内容
cat "$filename"
else
echo "File $filename does not exist."
fi
# 遍历目录中的所有文件
echo "Listing files in the current directory:"
for file in *; do
if [ -f "$file" ]; then
echo "$file"
fi
done
常用的 Shell 脚本基础命令:
echo
:打印文本到终端。if
/else
:条件判断。for
/while
:循环。mkdir
:创建目录。touch
:创建空文件。cat
:显示文件内容。cp
/mv
/rm
:复制、移动、删除文件。exit
:退出脚本。
6. 调试脚本
如果脚本没有按预期工作,可以使用 -x
选项来调试脚本。比如:
bash -x myscript.sh
这将显示每个命令和它的输出,帮助你找到问题。
如何在脚本中自动安装 Nginx 和 MySQL
要在一个 Shell 脚本中自动安装 Nginx 和 MySQL,首先你需要确保你的脚本可以运行必要的安装命令:
# 更新软件包列表
echo "Updating package lists..."
sudo apt update
# 安装 Nginx
echo "Installing Nginx..."
sudo apt install -y nginx
# 安装 MySQL
echo "Installing MySQL..."
sudo apt install -y mysql-server
# 启动并设置 Nginx 和 MySQL 开机自启
echo "Starting Nginx and MySQL..."
sudo systemctl start nginx
sudo systemctl start mysql
sudo systemctl enable nginx
sudo systemctl enable mysql
# 检查服务状态
echo "Checking Nginx status..."
sudo systemctl status nginx
echo "Checking MySQL status..."
sudo systemctl status mysql
echo "Nginx and MySQL installation completed."
步骤:
- 复制上面的代码并保存为一个
.sh
文件,比如install_nginx_mysql.sh
。 赋予脚本执行权限:
chmod +x install_nginx_mysql.sh
运行脚本:
./install_nginx_mysql.sh
该脚本会自动执行以下操作:
- 更新 Ubuntu 系统的包管理器。
- 安装 Nginx 和 MySQL。
- 启动并设置这两个服务为开机自启。
- 输出服务的状态,确保它们正确启动。
这样,你就可以在 Ubuntu 上自动安装并配置 Nginx 和 MySQL 了。
编写 bash 脚本常见问题总结
编写 Shell 脚本时,可能会遇到一些常见问题。了解这些问题可以帮助你更高效地调试和编写脚本。以下是一些常见的问题及其解决方法:
1. 权限问题
- 问题:无法执行脚本,提示权限不足。
- 原因:脚本文件没有执行权限。
解决方法:为脚本添加执行权限:
chmod +x myscript.sh
2. 路径问题
- 问题:找不到命令或文件。
- 原因:脚本中的命令或文件路径没有指定绝对路径,或者
PATH
环境变量未包含必要的路径。 解决方法:
- 使用绝对路径。例如:
/usr/bin/nginx
,而不是nginx
。 - 如果是脚本中调用的文件,确保文件存在于正确的路径下。
- 可以在脚本中使用
echo $PATH
检查路径设置。
- 使用绝对路径。例如:
3. 缺少 shebang 行
- 问题:执行脚本时出错,尤其是在非交互模式下运行脚本时。
- 原因:没有指定解释器,操作系统无法确定该用什么解释器来执行脚本。
解决方法:确保脚本的第一行包含正确的 shebang,例如:
#!/bin/bash
4. 脚本中的变量问题
- 问题:变量值没有正确传递或使用。
原因:
- 变量引用时缺少
$
符号。 - 使用了未定义的变量。
- 变量值中有空格时没有加引号。
- 变量引用时缺少
解决方法:
- 确保在引用变量时使用
$
,如:$my_variable
。 - 使用引号包裹带空格的变量值:
"$my_variable"
。
- 确保在引用变量时使用
5. 使用了错误的条件语句
- 问题:条件判断语句未按预期工作,导致脚本执行不正确。
原因:
- 在
if
语句中,[
和]
需要空格,且条件表达式内的比较符号(如=
)两侧需要有空格。 - 比较数值时使用
-eq
等,而不是=
。
- 在
解决方法:
字符串比较:
if [ "$var1" = "$var2" ]; then echo "Strings are equal" fi
数值比较:
if [ "$var1" -eq "$var2" ]; then echo "Numbers are equal" fi
6. 忘记加 exit
或返回值
- 问题:脚本运行结束时没有返回值,可能会影响后续脚本或自动化任务。
- 原因:没有显式返回退出状态码。
解决方法:可以在脚本最后添加
exit
来返回退出状态。例如:exit 0 # 正常退出 exit 1 # 异常退出
7. 错误的文件/目录操作
- 问题:删除或修改错误的文件或目录。
原因:
- 没有检查文件是否存在。
- 没有确认文件路径。
- 误用了
rm -rf
等危险命令。
解决方法:
在删除文件之前加上确认步骤:
if [ -f "$file" ]; then rm "$file" else echo "File does not exist." fi
8. 脚本中的错误处理不足
- 问题:脚本执行过程中如果某个命令出错,后续命令仍然继续执行,可能导致不可预见的错误。
- 原因:没有正确处理错误。
解决方法:
- 使用
set -e
来使脚本在遇到任何错误时退出。 使用
||
来捕捉并处理命令失败时的错误。例如:command || { echo "Command failed"; exit 1; }
- 使用
9. 循环和条件嵌套不当
- 问题:嵌套的循环或条件语句过多,导致脚本难以理解或出错。
- 原因:嵌套过深或缺乏适当的退出条件。
解决方法:
- 保持代码简洁,尽量避免深度嵌套。
- 可以使用函数来分隔不同的逻辑,使脚本结构更加清晰。
10. 输出重定向和管道问题
- 问题:命令的输出没有按预期重定向,或者管道未能正确传递数据。
原因:
- 没有正确使用重定向符号
>
和>>
。 - 管道中传递的数据格式不正确。
- 没有正确使用重定向符号
解决方法:
- 使用
>
将输出重定向到文件,>>
会将输出追加到文件。 使用管道传递命令结果:
command1 | command2
- 使用
11. 环境变量问题
- 问题:脚本无法正确访问某些环境变量。
- 原因:脚本中没有正确引用环境变量或没有在脚本中设置环境变量。
解决方法:
使用
export
设置环境变量,使其在脚本中可用:export MY_VAR="value"
12. 空格和缩进问题
- 问题:脚本执行时不按预期工作,代码难以阅读。
- 原因:缺少空格、错误的缩进或语法错误。
解决方法:
- 保持一致的缩进(通常使用 2 或 4 个空格)。
- 在操作符、条件、命令之间确保有空格。
简介下这个 .net 开发的小系统
https://kf.shengxunwei.com/
升讯威在线客服与营销系统是一款客服软件,但更重要的是一款营销利器。
- 可以追踪正在访问网站或使用 APP 的所有访客,收集他们的浏览情况,使客服能够主动出击,施展话术,促进成单。
- 可嵌入网站、手机 APP、公众号、或者通过 URL 地址直接联系客服。
- 支持访客信息互通,可传输访客标识、名称和其它任意信息到客服系统,与您的业务系统对接。
- 可全天候 7 × 24 小时挂机运行,网络中断,拔掉网线,手机飞行模式,不掉线不丢消息,欢迎实测。
希望能够打造: 开放、开源、共享。努力打造 .net 社区的一款优秀开源产品。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。