我教你OpenEulerShell编程22:vscode借力AI完成工程任务
本文介绍了一种基于AI辅助的Linux自动化运维方案。通过将常用Linux任务封装为函数库(包括系统管理、文件操作、网络工具等模块),构建了标准化的Shell脚本框架。该方案采用模块化设计,包含config、lib、modules等目录结构,支持通过配置文件驱动任务执行。文中以PXE自动部署openEuler系统和FTP服务部署为例,展示了如何利用AI生成完整的部署脚本,包括服务安装、配置生成、权
兰生幽谷,不为莫服而不芳;
君子行义,不为莫知而止休。
生产场景:在AI接口引入的情况下,完成Linux下各种服务任务的架设。
顶层设计:让AI将Linux常用的任务封装成函数,将这些函数导入函数库,然后用shell脚本来调用这些库文件,完成特定的服务。由于Linux系统非常复杂,我将库函数大致分为系统管理、文件管理、网络管理、安全管理、通用库等。vscode登录远程Linux服务器,到自己要完成的目录下。
下面是系统架构示例:
目录结构
|
shell_deploy/ ├── config │ └── config.ini ├── deploy_example.sh ├── deployTask │ └── deploy_ftp_dnf.sh ├── deploy_with_config.sh ├── lib │ ├── common_functions.sh │ ├── config_parser.sh │ ├── file_operations.sh │ ├── network_utils.sh │ └── package_manager.sh ├── logs └── modules ├── mount_shared_folder.sh ├── setup_ftp_source.sh ├── setup_http_source.sh └── system_init.sh |
1.直接将这个结构丢给AI接口,让AI生成init_project.sh,并运行生成系统目录结构:
|
#!/bin/bash # ================================================================ # Script Name: init_project.sh # Description: init_project.sh 功能描述:按用户要求生成目录结构 # # # Author: root # Created: 2026-05-16 # Last Modified: 2026-05-16 # Version: v1.0 # License: wzz@CQIE # Syntax: 用法 # ================================================================ # 定义项目根目录名称 PROJECT_NAME="auto_ops_project" # 定义需要创建的目录列表(使用 Bash 数组) # 利用 mkdir -p 的特性,即使父目录不存在也能一并创建 DIRS=( "${PROJECT_NAME}/config" "${PROJECT_NAME}/deployTask" "${PROJECT_NAME}/lib" "${PROJECT_NAME}/logs" "${PROJECT_NAME}/modules" ) # 定义需要创建的空文件列表 FILES=( "${PROJECT_NAME}/config/config.ini" "${PROJECT_NAME}/deploy_example.sh" "${PROJECT_NAME}/deployTask/deploy_ftp_dnf.sh" "${PROJECT_NAME}/deploy_with_config.sh" "${PROJECT_NAME}/lib/common_functions.sh" "${PROJECT_NAME}/lib/config_parser.sh" "${PROJECT_NAME}/lib/file_operations.sh" "${PROJECT_NAME}/lib/network_utils.sh" "${PROJECT_NAME}/lib/package_manager.sh" "${PROJECT_NAME}/modules/mount_shared_folder.sh" "${PROJECT_NAME}/modules/setup_ftp_source.sh" "${PROJECT_NAME}/modules/setup_http_source.sh" "${PROJECT_NAME}/modules/system_init.sh" ) # 【函数封装】打印带颜色的日志信息 log_info() { echo -e "\033[32m[INFO]\033[0m $1" } log_error() { echo -e "\033[31m[ERROR]\033[0m $1" } # 【主逻辑函数】执行目录和文件的创建 create_structure() { log_info "开始创建项目目录结构..."
# 1. 循环创建所有目录 for dir in "${DIRS[@]}"; do # -p 参数确保如果目录已存在不会报错,且能递归创建多级目录 if ! mkdir -p "$dir"; then log_error "创建目录失败: $dir" exit 1 fi done log_info "目录结构创建完成。" log_info "开始创建项目基础文件..."
# 2. 循环创建所有空文件 for file in "${FILES[@]}"; do # 使用 touch 命令创建空文件,如果文件已存在则只更新访问时间 if ! touch "$file"; then log_error "创建文件失败: $file" exit 1 fi done log_info "基础文件创建完成。"
log_info "✅ 项目 '$PROJECT_NAME' 初始化成功!" } # 执行主函数 create_structure |
赋权运行,验证:
|
11:29:23 [root@fire vscodeshell]# sh init_project.sh [INFO] 开始创建项目目录结构... [INFO] 目录结构创建完成。 [INFO] 开始创建项目基础文件... [INFO] 基础文件创建完成。 [INFO] ✅ 项目 'auto_ops_project' 初始化成功! |
验证一下:
|
11:29:36 [root@fire vscodeshell]# tree . ├── auto_ops_project │ ├── config │ │ └── config.ini │ ├── deploy_example.sh │ ├── deployTask │ │ └── deploy_ftp_dnf.sh │ ├── deploy_with_config.sh │ ├── lib │ │ ├── common_functions.sh │ │ ├── config_parser.sh │ │ ├── file_operations.sh │ │ ├── network_utils.sh │ │ └── package_manager.sh │ ├── logs │ └── modules │ ├── mount_shared_folder.sh │ ├── setup_ftp_source.sh │ ├── setup_http_source.sh │ └── system_init.sh └── init_project.sh |
确实生成了文件结构,不过这些文件都是空的。还需要你慢慢完成。
不过,右边不是有AI接口吗?好好描述,叫它去完成。然后照单收货就行了。下面是我点验的各种脚本(均由AI生成):
|
#!/bin/bash # 公共函数库lib/common_functions.sh LOG_DIR="../logs" LOG_FILE="$LOG_DIR/deploy_$(date +%Y%m%d).log" # 初始化日志目录 init_log() { mkdir -p "$LOG_DIR" } # 写日志 log() { local level=$1 shift local msg="$@" echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg" | tee -a "$LOG_FILE" } info() { log "INFO" "$@"; } warn() { log "WARN" "$@"; } error() { log "ERROR" "$@"; exit 1; } # 颜色输出 red() { echo -e "\033[31m$@\033[0m"; } green() { echo -e "\033[32m$@\033[0m"; } yellow() { echo -e "\033[33m$@\033[0m"; } # 检查是否为 root 用户 check_root() { if [[ $EUID -ne 0 ]]; then red "请使用 root 权限执行本脚本" exit 1 fi } |
|
#!/bin/bash # 配置文件解析器lib/config_parser.sh # 用法: get_config <section> <key> <config_file> get_config() { local section=$1 local key=$2 local file=$3 awk -F '=' -v sec="[$section]" -v k="$key" ' $0 ~ /^$/ { in_sec = ($0 == sec) } in_sec && $1 ~ /^[[:space:]]*'"$key"'[[:space:]]*$/ { gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2) print $2 exit } ' "$file" } |
|
#!/bin/bash # 文件操作函数库lib/file_operations.sh # 安全创建目录 create_dir() { local dir=$1 if [[ ! -d "$dir" ]]; then mkdir -p "$dir" info "创建目录: $dir" else info "目录已存在: $dir" fi } # 备份文件(若存在) backup_file() { local src=$1 if [[ -f "$src" ]]; then cp "$src" "${src}.bak.$(date +%Y%m%d%H%M%S)" info "已备份: $src" fi } # 设置目录所有者及权限 set_owner_perm() { local path=$1 local owner=$2 local perm=$3 chown -R "$owner" "$path" chmod "$perm" "$path" info "设置 $path 所有者=$owner 权限=$perm" } |
|
#!/bin/bash # 网络工具函数库lib/network_utils.sh # 获取本机第一个非 lo 的 IPv4 地址 get_local_ip() { ip -4 addr show | grep -v '127.0.0.1' | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1 } # 测试 TCP 端口连通性 test_port() { local host=$1 local port=$2 timeout 2 bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null && return 0 || return 1 } |
|
# 软件包管理函数库lib/package_manager.sh # 检查包是否已安装 is_installed() { rpm -q "$1" &>/dev/null } # 安装指定软件包 install_pkg() { local pkg=$1 if is_installed "$pkg"; then info "$pkg 已安装,跳过" else info "正在安装 $pkg ..." dnf install -y "$pkg" || error "安装 $pkg 失败" fi } |
|
#!/bin/bash # 系统初始化模块modules/system_init.sh system_init() { info "开始系统初始化..." # 关闭 SELinux(临时 + 永久) setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config info "SELinux 已关闭" # 配置防火墙,开放 ftp 服务 firewall-cmd --add-service=ftp --permanent firewall-cmd --reload info "防火墙已开放 FTP 服务" # 设置本地时间(避免 FTP 时间差) sed -i 's/^#use_localtime=YES/use_localtime=YES/' /etc/vsftpd/vsftpd.conf 2>/dev/null || true } |
创建ftp网站所需配置config/config.ini
|
[ftp] public_dir=/srv/ftp/public dept_dirs_base=/srv/ftp/depts virtual_user_file=/etc/vsftpd/vusers.txt pam_service=vsftpd.virtual guest_username=ftpvirtual [departments] 行政部 admin_dept 设计部 design_dept 开发部 dev_dept [public_account] username=pubuser readonly=yes |
完成了上面库函数建设之后,可以给右边的AI提非分要求:

图403- 1
下面我们看看git给出的结果:
|
#!/bin/bash # PXE 自动部署 openEuler 24.03 最小化系统脚本 # 适用网段:192.168.100.0/24 # 依赖项目函数库:common_functions.sh config_parser.sh file_operations.sh network_utils.sh package_manager.sh set -euo pipefail SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) PROJECT_DIR=$(dirname "$SCRIPT_DIR") source "$PROJECT_DIR/lib/common_functions.sh" source "$PROJECT_DIR/lib/config_parser.sh" source "$PROJECT_DIR/lib/file_operations.sh" source "$PROJECT_DIR/lib/network_utils.sh" source "$PROJECT_DIR/lib/package_manager.sh" # 默认参数,可通过环境变量覆盖 ISO_PATH=${ISO_PATH:-/root/openEuler-24.03-x86_64-dvd.iso} SERVER_IP=${SERVER_IP:-$(get_local_ip)} TFTP_ROOT=${TFTP_ROOT:-/var/lib/tftpboot} HTTP_ROOT=${HTTP_ROOT:-/var/www/html/openeuler} ISO_MOUNT=${ISO_MOUNT:-/mnt/openeuler_iso} DHCP_CONF=${DHCP_CONF:-/etc/dhcp/dhcpd.conf} KS_FILE=${KS_FILE:-$HTTP_ROOT/ks.cfg} PXE_CFG=${PXE_CFG:-$TFTP_ROOT/pxelinux.cfg/default} DHCP_RANGE_START=${DHCP_RANGE_START:-192.168.100.100} DHCP_RANGE_END=${DHCP_RANGE_END:-192.168.100.200} GATEWAY=${GATEWAY:-192.168.100.1} DNS_SERVERS=${DNS_SERVERS:-114.114.114.114,8.8.8.8} HTTP_PACKAGE=${HTTP_PACKAGE:-httpd} usage() { cat <<EOF Usage: $0 [ISO_PATH] 示例: ISO_PATH=/root/openEuler-24.03-x86_64-dvd.iso $0 环境变量可覆盖默认值: SERVER_IP PXE 服务器 IP TFTP_ROOT TFTP 根目录 HTTP_ROOT HTTP 根目录 ISO_MOUNT ISO 挂载目录 DHCP_RANGE_START DHCP 起始地址 DHCP_RANGE_END DHCP 结束地址 GATEWAY 网关 DNS_SERVERS DNS 地址 EOF exit 1 } if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage fi if [[ $# -ge 1 ]]; then ISO_PATH=$1 fi init_log check_root if [[ ! -f "$ISO_PATH" ]]; then error "找不到 ISO 镜像:$ISO_PATH" fi if [[ -z "$SERVER_IP" ]]; then error "无法自动获取本机 IP,请通过 SERVER_IP 环境变量指定" fi info "PXE 服务器 IP: $SERVER_IP" info "使用 ISO: $ISO_PATH" # 安装基础服务 install_pkg dhcp-server install_pkg tftp-server install_pkg syslinux install_pkg "$HTTP_PACKAGE" # 创建目录 create_dir "$TFTP_ROOT" create_dir "$HTTP_ROOT" create_dir "$ISO_MOUNT" create_dir "$(dirname "$PXE_CFG")" # 挂载 ISO,并在 HTTP 根目录创建软链接或挂载 if mount | grep -q " $ISO_MOUNT "; then info "ISO 已挂载在 $ISO_MOUNT" else mount -o loop "$ISO_PATH" "$ISO_MOUNT" info "已挂载 ISO 到 $ISO_MOUNT" fi # 如果 HTTP_ROOT 目录为空,则直接挂载 ISO 到 HTTP_ROOT if [[ -z "$(ls -A "$HTTP_ROOT" 2>/dev/null)" ]]; then umount "$HTTP_ROOT" 2>/dev/null || true mount -o loop "$ISO_PATH" "$HTTP_ROOT" info "已挂载 ISO 到 HTTP 根目录 $HTTP_ROOT" fi # 复制 PXE 引导文件 PXELINUX_BIN=$(find /usr/share -name pxelinux.0 | head -n 1 || true) MENU_C32_BIN=$(find /usr/share -name menu.c32 | head -n 1 || true) if [[ -z "$PXELINUX_BIN" ]]; then error "未找到 pxelinux.0,请确认 syslinux 包已正确安装" fi cp -f "$PXELINUX_BIN" "$TFTP_ROOT/" info "已复制 pxelinux.0 到 $TFTP_ROOT" if [[ -n "$MENU_C32_BIN" ]]; then cp -f "$MENU_C32_BIN" "$TFTP_ROOT/" info "已复制 menu.c32 到 $TFTP_ROOT" else warn "未找到 menu.c32,PXE 菜单可能不可用" fi # 复制内核和 initrd if [[ ! -f "$ISO_MOUNT/images/pxeboot/vmlinuz" || ! -f "$ISO_MOUNT/images/pxeboot/initrd.img" ]]; then error "ISO 中未找到 images/pxeboot/vmlinuz 或 initrd.img,请检查镜像是否为 openEuler 24.03 安装镜像" fi cp -f "$ISO_MOUNT/images/pxeboot/vmlinuz" "$TFTP_ROOT/" cp -f "$ISO_MOUNT/images/pxeboot/initrd.img" "$TFTP_ROOT/" info "已复制内核和 initrd 到 $TFTP_ROOT" # 生成 PXE 配置 cat > "$PXE_CFG" <<EOF DEFAULT menu.c32 PROMPT 0 TIMEOUT 100 ONTIMEOUT openeuler LABEL openeuler MENU LABEL ^Install openEuler 24.03 Minimal KERNEL vmlinuz APPEND initrd=initrd.img inst.repo=http://$SERVER_IP/openeuler/ inst.ks=http://$SERVER_IP/ks.cfg ip=dhcp inst.text EOF info "已生成 PXE 配置 $PXE_CFG" # 生成 Kickstart 文件 cat > "$KS_FILE" <<EOF #version=DEVEL #install text url --url=http://$SERVER_IP/openeuler/ lang zh_CN.UTF-8 keyboard us network --bootproto=dhcp --device=link --activate --onboot=on rootpw --plaintext 1q2w3e4r firewall --enabled --service=ssh selinux --disabled timezone Asia/Shanghai --isUtc bootloader --location=mbr --boot-drive=sda clearpart --all --initlabel autopart --type=lvm firstboot --disable reboot %packages @core @base openssh-server chrony NetworkManager %end EOF info "已生成 Kickstart 文件 $KS_FILE" # 生成 DHCP 配置 cat > "$DHCP_CONF" <<EOF default-lease-time 600; max-lease-time 7200; option domain-name-servers $DNS_SERVERS; option routers $GATEWAY; option broadcast-address 192.168.100.255; option subnet-mask 255.255.255.0; subnet 192.168.100.0 netmask 255.255.255.0 { range $DHCP_RANGE_START $DHCP_RANGE_END; option routers $GATEWAY; option domain-name-servers $DNS_SERVERS; next-server $SERVER_IP; filename "pxelinux.0"; } EOF info "已生成 DHCP 配置 $DHCP_CONF" # 配置服务 if systemctl list-unit-files | grep -q '^dhcpd\.service'; then systemctl enable --now dhcpd.service else systemctl enable --now dhcpd fi if systemctl list-unit-files | grep -q '^tftp\.socket'; then systemctl enable --now tftp.socket else systemctl enable --now tftp fi systemctl enable --now "$HTTP_PACKAGE".service || systemctl enable --now httpd # 防火墙 if command -v firewall-cmd >/dev/null 2>&1; then firewall-cmd --permanent --add-service=dhcp firewall-cmd --permanent --add-service=tftp firewall-cmd --permanent --add-service=http firewall-cmd --reload info "已在防火墙中开放 DHCP/TFTP/HTTP 服务" fi green "PXE openEuler 24.03 最小化部署已就绪" info "请确认以下内容:" echo " - PXE 服务器 IP: $SERVER_IP" echo " - HTTP 安装源: http://$SERVER_IP/openeuler/" echo " - Kickstart 地址: http://$SERVER_IP/ks.cfg" echo " - DHCP 范围: $DHCP_RANGE_START ~ $DHCP_RANGE_END" echo " - PXE 配置文件: $PXE_CFG" echo info "请确保客户端从网段 192.168.100.0/24 的网卡通过 PXE 启动,即可自动安装最小化 openEuler 24.03。" |
也可以在这个基础上,叫AI完成下面的任务:
|
完成基本功能函数封装,然后部署一个ftp网站部署验证一下。某企业为了实现文件资源的共享,需要建设FTP文件服务。 基本需求: 行政部、设计部、开发部有独立账号 独立账号访问,默认目录为部门目录 所有账号能够仅能够访问本部门目录,且具有读写权限 提供公共账号,仅允许读取公共目录的资源 禁止匿名账号访问 |
下面是AI创建的脚本:
FTP 自动化部署脚本 deployTask/deploy_ftp_dnf.sh
该脚本调用上述函数库,完成 vsftpd 安装、虚拟用户创建、目录隔离、权限设置等全部工作。
|
#!/bin/bash # FTP 服务器自动化部署(虚拟用户模式) # 适用系统:openEuler 24.03 set -e # 引入函数库 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) PROJECT_DIR=$(dirname "$SCRIPT_DIR") source "$PROJECT_DIR/lib/common_functions.sh" source "$PROJECT_DIR/lib/config_parser.sh" source "$PROJECT_DIR/lib/file_operations.sh" source "$PROJECT_DIR/lib/network_utils.sh" source "$PROJECT_DIR/lib/package_manager.sh" source "$PROJECT_DIR/modules/system_init.sh" # 初始化日志 init_log check_root # 加载配置 CONFIG_FILE="$PROJECT_DIR/config/config.ini" PUBLIC_DIR=$(get_config ftp public_dir "$CONFIG_FILE") DEPT_BASE=$(get_config ftp dept_dirs_base "$CONFIG_FILE") VUSER_FILE=$(get_config ftp virtual_user_file "$CONFIG_FILE") PAM_SERVICE=$(get_config ftp pam_service "$CONFIG_FILE") GUEST_USER=$(get_config ftp guest_username "$CONFIG_FILE") PUB_USER=$(get_config public_account username "$CONFIG_FILE") # 解析部门列表(格式:部门名 账号名) declare -A DEPT_MAP while read -r dept_name dept_user; do DEPT_MAP["$dept_name"]="$dept_user" done < <(awk -F '=' '/^\[departments$/{flag=1; next} /^\[/{flag=0} flag && NF{print $2}' "$CONFIG_FILE" | while read line; do echo $line; done) info "========== 开始部署 FTP 服务 ==========" # 1. 系统初始化 system_init # 2. 安装必要软件包 install_pkg vsftpd install_pkg db4-utils # 用于生成虚拟用户数据库 install_pkg ftp # 客户端测试工具 # 3. 创建虚拟用户映射的系统用户 if ! id "$GUEST_USER" &>/dev/null; then useradd -d /nonexistent -s /sbin/nologin "$GUEST_USER" info "创建映射系统用户: $GUEST_USER" fi # 4. 创建目录结构 create_dir "$PUBLIC_DIR" create_dir "$DEPT_BASE" for dept in "${!DEPT_MAP[@]}"; do create_dir "$DEPT_BASE/$dept" done # 5. 设置目录权限 # 公共目录:root 所有,755,允许所有人读取 set_owner_perm "$PUBLIC_DIR" root:root 755 # 部门目录:由对应的虚拟用户拥有(通过 guest_username 映射,实际所有者设为 root,权限 700 或 750,但 vsftpd 以 guest 身份运行,需保证 guest 有读写权限) # 这里将部门目录所有者设为 root:root,权限 770,并将 guest 用户加入 root 组(或直接设为 guest 所有) # 简单方案:将部门目录所有者设为 $GUEST_USER,权限 700,这样只有 guest 能读写,而不同虚拟用户通过 chroot 隔离 for dept in "${!DEPT_MAP[@]}"; do set_owner_perm "$DEPT_BASE/$dept" "$GUEST_USER:$GUEST_USER" 700 done # 6. 生成虚拟用户密码文件(明文) info "生成虚拟用户列表..." > "$VUSER_FILE" # 部门用户 for dept in "${!DEPT_MAP[@]}"; do user="${DEPT_MAP[$dept]}" # 生成随机密码(12位) pass=$(openssl rand -base64 12) echo "$user" >> "$VUSER_FILE" echo "$pass" >> "$VUSER_FILE" info "虚拟用户 $user (部门:$dept) 密码: $pass" done # 公共只读用户 pub_pass=$(openssl rand -base64 12) echo "$PUB_USER" >> "$VUSER_FILE" echo "$pub_pass" >> "$VUSER_FILE" info "公共用户 $PUB_USER 密码: $pub_pass" # 生成 Berkeley DB 文件 db_load -T -t hash -f "$VUSER_FILE" /etc/vsftpd/vusers.db chmod 600 /etc/vsftpd/vusers.db info "虚拟用户数据库已生成" # 7. 配置 PAM 认证 info "配置 PAM 认证..." cat > /etc/pam.d/$PAM_SERVICE <<EOF auth required pam_userdb.so db=/etc/vsftpd/vusers account required pam_userdb.so db=/etc/vsftpd/vusers EOF # 8. 配置 vsftpd.conf info "配置 vsftpd..." backup_file /etc/vsftpd/vsftpd.conf cat > /etc/vsftpd/vsftpd.conf <<EOF # 基础设置 listen=YES listen_ipv6=NO anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES chroot_local_user=YES allow_writeable_chroot=YES hide_ids=YES userlist_enable=YES userlist_deny=NO userlist_file=/etc/vsftpd/user_list # 虚拟用户设置 guest_enable=YES guest_username=$GUEST_USER virtual_use_local_privs=YES user_config_dir=/etc/vsftpd/vusers_config pam_service_name=$PAM_SERVICE # 被动模式端口范围 pasv_enable=YES pasv_min_port=50000 pasv_max_port=51000 pasv_address=$(get_local_ip) EOF # 9. 创建虚拟用户独立配置目录 create_dir /etc/vsftpd/vusers_config # 部门用户配置:限制在家目录,允许读写 for dept in "${!DEPT_MAP[@]}"; do user="${DEPT_MAP[$dept]}" cat > "/etc/vsftpd/vusers_config/$user" <<EOF local_root=$DEPT_BASE/$dept write_enable=YES anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES EOF done # 公共用户配置:只读,锁定在公共目录 cat > "/etc/vsftpd/vusers_config/$PUB_USER" <<EOF local_root=$PUBLIC_DIR write_enable=NO anon_upload_enable=NO anon_mkdir_write_enable=NO anon_other_write_enable=NO download_enable=YES EOF # 10. 创建 user_list 白名单(允许登录的虚拟用户) > /etc/vsftpd/user_list for dept in "${!DEPT_MAP[@]}"; do echo "${DEPT_MAP[$dept]}" >> /etc/vsftpd/user_list done echo "$PUB_USER" >> /etc/vsftpd/user_list # 11. 启动服务并设置开机自启 systemctl enable vsftpd --now systemctl restart vsftpd info "vsftpd 服务已启动" # 12. 验证测试 LOCAL_IP=$(get_local_ip) info "FTP 服务器地址: ftp://$LOCAL_IP" info "========== 部署完成 ==========" green "请使用以下账号测试:" for dept in "${!DEPT_MAP[@]}"; do echo " 部门: $dept 账号: ${DEPT_MAP[$dept]}" done echo " 公共只读账号: $PUB_USER" |
稍稍修改一下,完全可以部署成功。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)