Linux挂载FTP、WEBDAV、SMB为本地目录交互式脚本
1.代码保存为multi_mount_manager.sh
2.切换成root用户执行sudo -i
#!/bin/bash
# multi_mount_manager.sh - 多协议挂载管理工具(支持远端目录)
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 配置文件
CONFIG_DIR="$HOME/.mount_manager"
FTP_CONFIG="$CONFIG_DIR/ftp_config"
WEBDAV_CONFIG="$CONFIG_DIR/webdav_config"
SMB_CONFIG="$CONFIG_DIR/smb_config"
MOUNT_HISTORY="$CONFIG_DIR/mount_history"
# 默认挂载点
DEFAULT_MOUNT_BASE="$HOME/mnt"
# 加载配置
load_config() {
mkdir -p "$CONFIG_DIR"
# 加载FTP配置
if [ -f "$FTP_CONFIG" ]; then
source "$FTP_CONFIG"
else
FTP_HOST=""
FTP_USER=""
FTP_PASS=""
FTP_PORT="21"
FTP_REMOTE_PATH="/"
FTP_MOUNT_POINT="$DEFAULT_MOUNT_BASE/ftp"
fi
# 加载WebDAV配置
if [ -f "$WEBDAV_CONFIG" ]; then
source "$WEBDAV_CONFIG"
else
WEBDAV_URL=""
WEBDAV_USER=""
WEBDAV_PASS=""
WEBDAV_REMOTE_PATH="/"
WEBDAV_MOUNT_POINT="$DEFAULT_MOUNT_BASE/webdav"
fi
# 加载SMB配置
if [ -f "$SMB_CONFIG" ]; then
source "$SMB_CONFIG"
else
SMB_SERVER=""
SMB_SHARE=""
SMB_USER=""
SMB_PASS=""
SMB_DOMAIN="WORKGROUP"
SMB_REMOTE_PATH="/"
SMB_MOUNT_POINT="$DEFAULT_MOUNT_BASE/smb"
fi
}
# 保存配置
save_config() {
# 保存FTP配置
cat > "$FTP_CONFIG" << EOF FTP_HOST="$FTP_HOST" FTP_USER="$FTP_USER" FTP_PASS="$FTP_PASS" FTP_PORT="$FTP_PORT" FTP_REMOTE_PATH="$FTP_REMOTE_PATH" FTP_MOUNT_POINT="$FTP_MOUNT_POINT" EOF # 保存WebDAV配置 cat > "$WEBDAV_CONFIG" << EOF WEBDAV_URL="$WEBDAV_URL" WEBDAV_USER="$WEBDAV_USER" WEBDAV_PASS="$WEBDAV_PASS" WEBDAV_REMOTE_PATH="$WEBDAV_REMOTE_PATH" WEBDAV_MOUNT_POINT="$WEBDAV_MOUNT_POINT" EOF # 保存SMB配置 cat > "$SMB_CONFIG" << EOF SMB_SERVER="$SMB_SERVER" SMB_SHARE="$SMB_SHARE" SMB_USER="$SMB_USER" SMB_PASS="$SMB_PASS" SMB_DOMAIN="$SMB_DOMAIN" SMB_REMOTE_PATH="$SMB_REMOTE_PATH" SMB_MOUNT_POINT="$SMB_MOUNT_POINT" EOF chmod 600 "$CONFIG_DIR"/* echo -e "${GREEN}配置已保存${NC}" } # 解析URL为各个组件 parse_url() { local url="$1" local protocol="$2" case $protocol in ftp) # ftp://user:pass@host:port/path FTP_HOST=$(echo "$url" | sed 's|^ftp://||' | cut -d/ -f1 | cut -d@ -f2) FTP_USER=$(echo "$url" | sed 's|^ftp://||' | cut -d/ -f1 | cut -d@ -f1 | cut -d: -f1) FTP_PASS=$(echo "$url" | sed 's|^ftp://||' | cut -d/ -f1 | cut -d@ -f1 | cut -d: -f2) FTP_REMOTE_PATH=$(echo "$url" | sed 's|^ftp://[^/]*||') [ -z "$FTP_REMOTE_PATH" ] && FTP_REMOTE_PATH="/" ;; webdav) # http://user:pass@host/path WEBDAV_URL=$(echo "$url" | cut -d' ' -f1) WEBDAV_REMOTE_PATH=$(echo "$url" | cut -d' ' -f2) [ -z "$WEBDAV_REMOTE_PATH" ] && WEBDAV_REMOTE_PATH="/" ;; smb) # //server/share/path SMB_SERVER=$(echo "$url" | sed 's|^//||' | cut -d/ -f1) SMB_SHARE=$(echo "$url" | sed 's|^//[^/]*/||' | cut -d/ -f1) SMB_REMOTE_PATH=$(echo "$url" | sed "s|^//$SMB_SERVER/$SMB_SHARE||") [ -z "$SMB_REMOTE_PATH" ] && SMB_REMOTE_PATH="/" ;; esac } # 显示远端目录选择器 remote_path_selector() { local protocol="$1" local current_path="$2" echo -e "${CYAN}=== 远端目录浏览器 ($protocol) ===${NC}" echo -e "当前路径: ${YELLOW}$current_path${NC}" echo case $protocol in ftp) list_ftp_directory "$current_path" ;; webdav) list_webdav_directory "$current_path" ;; smb) list_smb_directory "$current_path" ;; esac echo echo -e "${GREEN}[操作选项]${NC}" echo "1. 进入子目录" echo "2. 返回上级目录" echo "3. 使用当前目录" echo "4. 手动输入路径" echo "0. 取消" echo read -p "请选择: " choice case $choice in 1) read -p "输入子目录名: " subdir new_path="${current_path%/}/$subdir" remote_path_selector "$protocol" "$new_path" ;; 2) parent_path=$(dirname "$current_path") [ "$parent_path" = "." ] && parent_path="/" remote_path_selector "$protocol" "$parent_path" ;; 3) echo "$current_path" ;; 4) read -p "输入完整路径: " manual_path echo "$manual_path" ;; 0) echo "$current_path" ;; *) echo "$current_path" ;; esac } # 列出FTP目录内容 list_ftp_directory() { local path="$1" echo -e "${BLUE}目录内容:${NC}" if [ -z "$FTP_PASS" ]; then # 匿名访问 curl -s --list-only "ftp://$FTP_HOST:$FTP_PORT$path" 2>/dev/null | head -20
else
# 认证访问
curl -s --list-only --user "$FTP_USER:$FTP_PASS" "ftp://$FTP_HOST:$FTP_PORT$path" 2>/dev/null | head -20
fi
}
# 列出WebDAV目录内容
list_webdav_directory() {
local path="$1"
local full_url="$WEBDAV_URL$path"
echo -e "${BLUE}目录内容:${NC}"
if [ -z "$WEBDAV_PASS" ]; then
# 匿名访问
curl -s -X PROPFIND "$full_url" -H "Depth: 1" 2>/dev/null | \
grep -o '[^<]*' | \
sed 's###g; s###g' | \
head -20
else
# 认证访问
curl -s -X PROPFIND "$full_url" -H "Depth: 1" --user "$WEBDAV_USER:$WEBDAV_PASS" 2>/dev/null | \
grep -o '[^<]*' | \
sed 's###g; s###g' | \
head -20
fi
}
# 列出SMB目录内容
list_smb_directory() {
local path="$1"
local share_url="//$SMB_SERVER/$SMB_SHARE$path"
echo -e "${BLUE}目录内容:${NC}"
if command -v smbclient &> /dev/null; then
if [ -z "$SMB_PASS" ]; then
# 访客访问
smbclient "//$SMB_SERVER/$SMB_SHARE" -N -c "cd \"$path\"; dir" 2>/dev/null | \
grep '^ ' | awk '{print $1}' | head -20
else
# 认证访问
smbclient "//$SMB_SERVER/$SMB_SHARE" -U "$SMB_USER%$SMB_PASS" -W "$SMB_DOMAIN" -c "cd \"$path\"; dir" 2>/dev/null | \
grep '^ ' | awk '{print $1}' | head -20
fi
else
echo -e "${YELLOW}需要安装smbclient来浏览目录${NC}"
fi
}
# 记录挂载历史
record_mount() {
local protocol="$1"
local server="$2"
local remote_path="$3"
local mount_point="$4"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "$timestamp|$protocol|$server|$remote_path|$mount_point" >> "$MOUNT_HISTORY"
}
# 检查依赖
check_dependencies() {
local missing_pkgs=""
# 检查FTP依赖
if ! command -v curlftpfs &> /dev/null; then
missing_pkgs+=" curlftpfs"
fi
# 检查WebDAV依赖
if ! command -v mount.davfs &> /dev/null; then
missing_pkgs+=" davfs2"
fi
# 检查SMB依赖
if ! command -v mount.cifs &> /dev/null; then
missing_pkgs+=" cifs-utils"
fi
# 检查curl(用于目录浏览)
if ! command -v curl &> /dev/null; then
missing_pkgs+=" curl"
fi
if [ -n "$missing_pkgs" ]; then
echo -e "${YELLOW}缺少必要软件包:$missing_pkgs${NC}"
echo -e "${BLUE}是否安装?(y/N): ${NC}"
read -n 1 install_choice
echo
if [[ "$install_choice" =~ ^[Yy]$ ]]; then
install_dependencies "$missing_pkgs"
else
echo -e "${RED}部分功能可能无法使用${NC}"
fi
fi
}
# 安装依赖
install_dependencies() {
local pkgs="$1"
echo -e "${BLUE}正在安装依赖包...${NC}"
if [ -f /etc/debian_version ]; then
sudo apt update
sudo apt install -y $pkgs
elif [ -f /etc/redhat-release ]; then
sudo yum install -y $pkgs
elif [ -f /etc/arch-release ]; then
sudo pacman -S --noconfirm $pkgs
elif [ -f /etc/fedora-release ]; then
sudo dnf install -y $pkgs
else
echo -e "${RED}无法识别发行版,请手动安装: $pkgs${NC}"
return 1
fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}依赖安装完成${NC}"
else
echo -e "${RED}依赖安装失败${NC}"
fi
}
# 显示协议选择菜单
show_protocol_menu() {
clear
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
echo -e "${BLUE} 多协议挂载管理工具 v2.1 (支持远端目录)${NC}"
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
echo
echo -e "${CYAN}[选择协议]${NC}"
echo -e " 1. ${GREEN}FTP${NC} - 文件传输协议"
echo -e " 2. ${YELLOW}WebDAV${NC} - Web分布式创作和版本控制"
echo -e " 3. ${PURPLE}SMB/CIFS${NC} - Windows文件共享"
echo -e " 4. ${BLUE}查看所有挂载${NC}"
echo -e " 5. ${CYAN}批量卸载所有${NC}"
echo -e " 6. ${RED}清理挂载点${NC}"
echo -e " 7. ${GREEN}快速URL导入${NC}"
echo -e " 0. 返回主菜单"
echo
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
}
# 显示主菜单
show_main_menu() {
clear
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
echo -e "${BLUE} 多协议挂载管理工具 v2.1 (支持远端目录)${NC}"
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
echo
# 显示当前挂载状态
echo -e "${YELLOW}[当前挂载状态]${NC}"
show_mount_status brief
echo
echo -e "${GREEN}[主菜单选项]${NC}"
echo -e " 1. 选择协议进行挂载"
echo -e " 2. 配置连接信息"
echo -e " 3. 测试连接"
echo -e " 4. 查看挂载历史"
echo -e " 5. 设置开机自动挂载"
echo -e " 6. 创建快捷命令"
echo -e " 7. 浏览远程目录"
echo -e " 0. 退出"
echo
echo -e "${BLUE}══════════════════════════════════════════════════${NC}"
}
# 显示挂载状态
show_mount_status() {
local mode="$1"
if [ "$mode" = "brief" ]; then
# 简要显示
local mounted_count=0
# 检查FTP
if mount | grep -q "$FTP_MOUNT_POINT"; then
echo -e " ${GREEN}✓${NC} FTP: $FTP_HOST$FTP_REMOTE_PATH → $FTP_MOUNT_POINT"
mounted_count=$((mounted_count + 1))
fi
# 检查WebDAV
if mount | grep -q "$WEBDAV_MOUNT_POINT"; then
echo -e " ${GREEN}✓${NC} WebDAV: $WEBDAV_REMOTE_PATH → $WEBDAV_MOUNT_POINT"
mounted_count=$((mounted_count + 1))
fi
# 检查SMB
if mount | grep -q "$SMB_MOUNT_POINT"; then
echo -e " ${GREEN}✓${NC} SMB: //$SMB_SERVER/$SMB_SHARE$SMB_REMOTE_PATH → $SMB_MOUNT_POINT"
mounted_count=$((mounted_count + 1))
fi
if [ $mounted_count -eq 0 ]; then
echo -e " ${YELLOW}没有挂载的远程文件系统${NC}"
fi
else
# 详细显示
echo -e "${CYAN}[详细挂载信息]${NC}"
echo
# FTP状态
echo -e "${GREEN}FTP状态:${NC}"
if mount | grep -q "$FTP_MOUNT_POINT"; then
mount | grep "$FTP_MOUNT_POINT"
echo -e " 远端路径: $FTP_REMOTE_PATH"
echo -e " 目录内容:"
ls -la "$FTP_MOUNT_POINT/" 2>/dev/null | head -5
else
echo -e " ${YELLOW}未挂载${NC}"
echo -e " 配置: $FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH"
fi
echo
# WebDAV状态
echo -e "${YELLOW}WebDAV状态:${NC}"
if mount | grep -q "$WEBDAV_MOUNT_POINT"; then
mount | grep "$WEBDAV_MOUNT_POINT"
echo -e " 远端路径: $WEBDAV_REMOTE_PATH"
echo -e " 目录内容:"
ls -la "$WEBDAV_MOUNT_POINT/" 2>/dev/null | head -5
else
echo -e " ${YELLOW}未挂载${NC}"
echo -e " 配置: $WEBDAV_URL$WEBDAV_REMOTE_PATH"
fi
echo
# SMB状态
echo -e "${PURPLE}SMB状态:${NC}"
if mount | grep -q "$SMB_MOUNT_POINT"; then
mount | grep "$SMB_MOUNT_POINT"
echo -e " 远端路径: $SMB_REMOTE_PATH"
echo -e " 目录内容:"
ls -la "$SMB_MOUNT_POINT/" 2>/dev/null | head -5
else
echo -e " ${YELLOW}未挂载${NC}"
echo -e " 配置: //$SMB_SERVER/$SMB_SHARE$SMB_REMOTE_PATH"
fi
fi
}
# FTP相关功能
configure_ftp() {
echo -e "${GREEN}=== 配置FTP连接 ===${NC}"
read -p "FTP服务器地址 [当前: $FTP_HOST]: " input
[ -n "$input" ] && FTP_HOST="$input"
read -p "端口 [当前: $FTP_PORT]: " input
[ -n "$input" ] && FTP_PORT="$input"
read -p "用户名 [当前: $FTP_USER]: " input
[ -n "$input" ] && FTP_USER="$input"
read -s -p "密码 [输入新密码或回车保持]: " input
echo
[ -n "$input" ] && FTP_PASS="$input"
echo -e "${YELLOW}当前远端路径: $FTP_REMOTE_PATH${NC}"
read -p "远端路径 [输入路径或回车保持,输入'browse'浏览]: " input
if [ "$input" = "browse" ]; then
if [ -n "$FTP_HOST" ]; then
FTP_REMOTE_PATH=$(remote_path_selector "ftp" "$FTP_REMOTE_PATH")
else
echo -e "${RED}请先设置服务器地址${NC}"
fi
elif [ -n "$input" ]; then
FTP_REMOTE_PATH="$input"
fi
read -p "本地挂载点目录 [当前: $FTP_MOUNT_POINT]: " input
[ -n "$input" ] && FTP_MOUNT_POINT="$input"
# 创建挂载点目录
mkdir -p "$FTP_MOUNT_POINT"
save_config
}
mount_ftp() {
echo -e "${GREEN}[挂载FTP]${NC}"
if [ -z "$FTP_HOST" ]; then
echo -e "${YELLOW}请先配置FTP连接信息${NC}"
configure_ftp
fi
# 检查是否已挂载
if mount | grep -q "$FTP_MOUNT_POINT"; then
echo -e "${YELLOW}FTP已经挂载到 $FTP_MOUNT_POINT${NC}"
read -p "是否重新挂载?(y/N): " choice
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
return
fi
umount_ftp
fi
# 创建挂载点
mkdir -p "$FTP_MOUNT_POINT"
echo -e "${BLUE}正在挂载FTP...${NC}"
echo -e "服务器: ${FTP_HOST}:${FTP_PORT}"
echo -e "远端路径: $FTP_REMOTE_PATH"
echo -e "挂载点: $FTP_MOUNT_POINT"
local mount_cmd
local full_url
if [ -z "$FTP_PASS" ]; then
# 匿名访问
full_url="ftp://$FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH"
mount_cmd="curlftpfs -o allow_other,uid=$(id -u),gid=$(id -g) \"$full_url\" \"$FTP_MOUNT_POINT\""
else
# 认证访问
full_url="ftp://$FTP_USER:$FTP_PASS@$FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH"
mount_cmd="curlftpfs -o allow_other,uid=$(id -u),gid=$(id -g) \"$full_url\" \"$FTP_MOUNT_POINT\""
fi
echo -e "${YELLOW}执行命令: $mount_cmd${NC}"
if eval "$mount_cmd"; then
echo -e "${GREEN}✓ FTP挂载成功${NC}"
record_mount "FTP" "$FTP_HOST:$FTP_PORT" "$FTP_REMOTE_PATH" "$FTP_MOUNT_POINT"
else
echo -e "${RED}✗ FTP挂载失败${NC}"
echo -e "${YELLOW}提示: 尝试不使用远端路径挂载根目录${NC}"
read -p "是否尝试挂载根目录?(y/N): " retry
if [[ "$retry" =~ ^[Yy]$ ]]; then
FTP_REMOTE_PATH="/"
save_config
mount_ftp
fi
fi
}
umount_ftp() {
if mount | grep -q "$FTP_MOUNT_POINT"; then
echo -e "${BLUE}正在卸载FTP...${NC}"
fusermount -u "$FTP_MOUNT_POINT" 2>/dev/null || sudo fusermount -u "$FTP_MOUNT_POINT"
echo -e "${GREEN}✓ FTP卸载完成${NC}"
fi
}
test_ftp() {
if [ -z "$FTP_HOST" ]; then
echo -e "${RED}请先配置FTP连接信息${NC}"
return
fi
echo -e "${BLUE}测试FTP连接...${NC}"
echo -e "测试路径: $FTP_REMOTE_PATH"
if [ -z "$FTP_PASS" ]; then
timeout 10 curl -s --list-only "ftp://$FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH" > /dev/null 2>&1
else
timeout 10 curl -s --list-only --user "$FTP_USER:$FTP_PASS" "ftp://$FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH" > /dev/null 2>&1
fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ FTP连接测试成功${NC}"
else
echo -e "${RED}✗ FTP连接测试失败${NC}"
echo -e "${YELLOW}尝试测试根目录...${NC}"
if [ -z "$FTP_PASS" ]; then
timeout 10 curl -s --list-only "ftp://$FTP_HOST:$FTP_PORT/" > /dev/null 2>&1
else
timeout 10 curl -s --list-only --user "$FTP_USER:$FTP_PASS" "ftp://$FTP_HOST:$FTP_PORT/" > /dev/null 2>&1
fi
if [ $? -eq 0 ]; then
echo -e "${YELLOW}根目录可访问,但指定路径不可用${NC}"
fi
fi
}
# WebDAV相关功能
configure_webdav() {
echo -e "${YELLOW}=== 配置WebDAV连接 ===${NC}"
read -p "WebDAV基础URL (如: http://example.com) [当前: $WEBDAV_URL]: " input
[ -n "$input" ] && WEBDAV_URL="$input"
read -p "用户名 [当前: $WEBDAV_USER]: " input
[ -n "$input" ] && WEBDAV_USER="$input"
read -s -p "密码 [输入新密码或回车保持]: " input
echo
[ -n "$input" ] && WEBDAV_PASS="$input"
echo -e "${YELLOW}当前远端路径: $WEBDAV_REMOTE_PATH${NC}"
read -p "远端路径 [输入路径或回车保持,输入'browse'浏览]: " input
if [ "$input" = "browse" ]; then
if [ -n "$WEBDAV_URL" ]; then
WEBDAV_REMOTE_PATH=$(remote_path_selector "webdav" "$WEBDAV_REMOTE_PATH")
else
echo -e "${RED}请先设置基础URL${NC}"
fi
elif [ -n "$input" ]; then
WEBDAV_REMOTE_PATH="$input"
fi
read -p "本地挂载点目录 [当前: $WEBDAV_MOUNT_POINT]: " input
[ -n "$input" ] && WEBDAV_MOUNT_POINT="$input"
# 创建挂载点目录
mkdir -p "$WEBDAV_MOUNT_POINT"
save_config
}
mount_webdav() {
echo -e "${YELLOW}[挂载WebDAV]${NC}"
if [ -z "$WEBDAV_URL" ]; then
echo -e "${YELLOW}请先配置WebDAV连接信息${NC}"
configure_webdav
fi
# 检查是否已挂载
if mount | grep -q "$WEBDAV_MOUNT_POINT"; then
echo -e "${YELLOW}WebDAV已经挂载到 $WEBDAV_MOUNT_POINT${NC}"
read -p "是否重新挂载?(y/N): " choice
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
return
fi
umount_webdav
fi
# 创建挂载点
mkdir -p "$WEBDAV_MOUNT_POINT"
local full_url="${WEBDAV_URL%/}${WEBDAV_REMOTE_PATH}"
echo -e "${BLUE}正在挂载WebDAV...${NC}"
echo -e "URL: $full_url"
echo -e "挂载点: $WEBDAV_MOUNT_POINT"
local mount_cmd
if [ -z "$WEBDAV_PASS" ]; then
# 匿名访问
mount_cmd="sudo mount -t davfs \"$full_url\" \"$WEBDAV_MOUNT_POINT\" -o uid=$(id -u),gid=$(id -g),noexec"
else
# 认证访问
mount_cmd="sudo mount -t davfs \"$full_url\" \"$WEBDAV_MOUNT_POINT\" -o uid=$(id -u),gid=$(id -g),noexec,username=$WEBDAV_USER,password=$WEBDAV_PASS"
fi
echo -e "${YELLOW}执行命令: $mount_cmd${NC}"
if eval "$mount_cmd"; then
echo -e "${GREEN}✓ WebDAV挂载成功${NC}"
record_mount "WebDAV" "$WEBDAV_URL" "$WEBDAV_REMOTE_PATH" "$WEBDAV_MOUNT_POINT"
else
echo -e "${RED}✗ WebDAV挂载失败${NC}"
echo -e "${YELLOW}提示: 可能需要将用户加入davfs2组: sudo usermod -aG davfs2 $USER${NC}"
fi
}
umount_webdav() {
if mount | grep -q "$WEBDAV_MOUNT_POINT"; then
echo -e "${BLUE}正在卸载WebDAV...${NC}"
sudo umount "$WEBDAV_MOUNT_POINT"
echo -e "${GREEN}✓ WebDAV卸载完成${NC}"
fi
}
test_webdav() {
if [ -z "$WEBDAV_URL" ]; then
echo -e "${RED}请先配置WebDAV连接信息${NC}"
return
fi
local full_url="${WEBDAV_URL%/}${WEBDAV_REMOTE_PATH}"
echo -e "${BLUE}测试WebDAV连接...${NC}"
echo -e "测试URL: $full_url"
if [ -z "$WEBDAV_PASS" ]; then
timeout 10 curl -s -I "$full_url" | head -1 | grep -q "200"
else
timeout 10 curl -s -I --user "$WEBDAV_USER:$WEBDAV_PASS" "$full_url" | head -1 | grep -q "200"
fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ WebDAV连接测试成功${NC}"
else
echo -e "${RED}✗ WebDAV连接测试失败${NC}"
fi
}
# SMB相关功能
configure_smb() {
echo -e "${PURPLE}=== 配置SMB/CIFS连接 ===${NC}"
read -p "SMB服务器地址 [当前: $SMB_SERVER]: " input
[ -n "$input" ] && SMB_SERVER="$input"
read -p "共享名称 [当前: $SMB_SHARE]: " input
[ -n "$input" ] && SMB_SHARE="$input"
read -p "域名 [当前: $SMB_DOMAIN]: " input
[ -n "$input" ] && SMB_DOMAIN="$input"
read -p "用户名 [当前: $SMB_USER]: " input
[ -n "$input" ] && SMB_USER="$input"
read -s -p "密码 [输入新密码或回车保持]: " input
echo
[ -n "$input" ] && SMB_PASS="$input"
echo -e "${YELLOW}当前远端路径: $SMB_REMOTE_PATH${NC}"
read -p "远端路径 [输入路径或回车保持,输入'browse'浏览]: " input
if [ "$input" = "browse" ]; then
if [ -n "$SMB_SERVER" ] && [ -n "$SMB_SHARE" ]; then
SMB_REMOTE_PATH=$(remote_path_selector "smb" "$SMB_REMOTE_PATH")
else
echo -e "${RED}请先设置服务器地址和共享名称${NC}"
fi
elif [ -n "$input" ]; then
SMB_REMOTE_PATH="$input"
fi
read -p "本地挂载点目录 [当前: $SMB_MOUNT_POINT]: " input
[ -n "$input" ] && SMB_MOUNT_POINT="$input"
# 创建挂载点目录
mkdir -p "$SMB_MOUNT_POINT"
save_config
}
mount_smb() {
echo -e "${PURPLE}[挂载SMB/CIFS]${NC}"
if [ -z "$SMB_SERVER" ] || [ -z "$SMB_SHARE" ]; then
echo -e "${YELLOW}请先配置SMB连接信息${NC}"
configure_smb
fi
# 检查是否已挂载
if mount | grep -q "$SMB_MOUNT_POINT"; then
echo -e "${YELLOW}SMB已经挂载到 $SMB_MOUNT_POINT${NC}"
read -p "是否重新挂载?(y/N): " choice
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
return
fi
umount_smb
fi
# 创建挂载点
mkdir -p "$SMB_MOUNT_POINT"
local full_path="//$SMB_SERVER/$SMB_SHARE$SMB_REMOTE_PATH"
echo -e "${BLUE}正在挂载SMB...${NC}"
echo -e "共享: $full_path"
echo -e "挂载点: $SMB_MOUNT_POINT"
local mount_cmd
if [ -z "$SMB_PASS" ]; then
# 访客访问
mount_cmd="sudo mount -t cifs \"$full_path\" \"$SMB_MOUNT_POINT\" -o guest,uid=$(id -u),gid=$(id -g),iocharset=utf8,file_mode=0777,dir_mode=0777"
else
# 认证访问
mount_cmd="sudo mount -t cifs \"$full_path\" \"$SMB_MOUNT_POINT\" -o username=$SMB_USER,password=$SMB_PASS,domain=$SMB_DOMAIN,uid=$(id -u),gid=$(id -g),iocharset=utf8,file_mode=0777,dir_mode=0777"
fi
echo -e "${YELLOW}执行命令: $mount_cmd${NC}"
if eval "$mount_cmd"; then
echo -e "${GREEN}✓ SMB挂载成功${NC}"
record_mount "SMB" "//$SMB_SERVER/$SMB_SHARE" "$SMB_REMOTE_PATH" "$SMB_MOUNT_POINT"
else
echo -e "${RED}✗ SMB挂载失败${NC}"
echo -e "${YELLOW}提示:${NC}"
echo -e " 1. 检查cifs-utils是否安装: sudo apt install cifs-utils"
echo -e " 2. 检查共享地址是否正确"
echo -e " 3. 尝试使用IP地址代替主机名"
fi
}
umount_smb() {
if mount | grep -q "$SMB_MOUNT_POINT"; then
echo -e "${BLUE}正在卸载SMB...${NC}"
sudo umount "$SMB_MOUNT_POINT"
echo -e "${GREEN}✓ SMB卸载完成${NC}"
fi
}
test_smb() {
if [ -z "$SMB_SERVER" ] || [ -z "$SMB_SHARE" ]; then
echo -e "${RED}请先配置SMB连接信息${NC}"
return
fi
echo -e "${BLUE}测试SMB连接...${NC}"
echo -e "测试共享: //$SMB_SERVER/$SMB_SHARE"
# 使用smbclient测试
if command -v smbclient &> /dev/null; then
if [ -z "$SMB_PASS" ]; then
timeout 10 smbclient -L "$SMB_SERVER" -N > /dev/null 2>&1
else
timeout 10 smbclient -L "$SMB_SERVER" -U "$SMB_USER%$SMB_PASS" -W "$SMB_DOMAIN" > /dev/null 2>&1
fi
else
# 使用ping测试
ping -c 1 -W 2 "$SMB_SERVER" > /dev/null 2>&1
fi
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ SMB服务器连接成功${NC}"
# 测试具体共享
if [ -n "$SMB_REMOTE_PATH" ] && [ "$SMB_REMOTE_PATH" != "/" ]; then
echo -e "${YELLOW}注意: SMB远程路径测试需要挂载后才能验证${NC}"
fi
else
echo -e "${RED}✗ SMB连接测试失败${NC}"
fi
}
# 快速URL导入
quick_import() {
echo -e "${CYAN}=== 快速URL导入 ===${NC}"
echo
echo "支持的格式:"
echo " FTP: ftp://[user:pass@]host:port[/path]"
echo " WebDAV: http[s]://[user:pass@]host[/path]"
echo " SMB: //server/share[/path]"
echo
read -p "输入URL: " url
if [[ "$url" =~ ^ftp:// ]]; then
echo -e "${GREEN}检测到FTP URL${NC}"
parse_url "$url" "ftp"
echo -e "服务器: $FTP_HOST"
echo -e "用户名: $FTP_USER"
echo -e "远端路径: $FTP_REMOTE_PATH"
read -p "本地挂载点 [默认: $DEFAULT_MOUNT_BASE/ftp]: " mount_point
FTP_MOUNT_POINT="${mount_point:-$DEFAULT_MOUNT_BASE/ftp}"
save_config
echo -e "${GREEN}FTP配置已导入${NC}"
read -p "是否立即挂载?(y/N): " mount_now
if [[ "$mount_now" =~ ^[Yy]$ ]]; then
mount_ftp
fi
elif [[ "$url" =~ ^https?:// ]]; then
echo -e "${YELLOW}检测到WebDAV URL${NC}"
parse_url "$url" "webdav"
echo -e "URL: $WEBDAV_URL"
echo -e "远端路径: $WEBDAV_REMOTE_PATH"
read -p "本地挂载点 [默认: $DEFAULT_MOUNT_BASE/webdav]: " mount_point
WEBDAV_MOUNT_POINT="${mount_point:-$DEFAULT_MOUNT_BASE/webdav}"
save_config
echo -e "${GREEN}WebDAV配置已导入${NC}"
read -p "是否立即挂载?(y/N): " mount_now
if [[ "$mount_now" =~ ^[Yy]$ ]]; then
mount_webdav
fi
elif [[ "$url" =~ ^// ]]; then
echo -e "${PURPLE}检测到SMB URL${NC}"
parse_url "$url" "smb"
echo -e "服务器: $SMB_SERVER"
echo -e "共享: $SMB_SHARE"
echo -e "远端路径: $SMB_REMOTE_PATH"
read -p "本地挂载点 [默认: $DEFAULT_MOUNT_BASE/smb]: " mount_point
SMB_MOUNT_POINT="${mount_point:-$DEFAULT_MOUNT_BASE/smb}"
save_config
echo -e "${GREEN}SMB配置已导入${NC}"
read -p "是否立即挂载?(y/N): " mount_now
if [[ "$mount_now" =~ ^[Yy]$ ]]; then
mount_smb
fi
else
echo -e "${RED}无法识别的URL格式${NC}"
fi
}
# 浏览远程目录(独立功能)
browse_remote() {
echo -e "${CYAN}=== 浏览远程目录 ===${NC}"
echo
echo "选择协议:"
echo "1. FTP"
echo "2. WebDAV"
echo "3. SMB"
echo "0. 返回"
echo
read -p "请选择: " choice
case $choice in
1)
if [ -z "$FTP_HOST" ]; then
echo -e "${RED}请先配置FTP连接信息${NC}"
configure_ftp
else
selected_path=$(remote_path_selector "ftp" "$FTP_REMOTE_PATH")
echo -e "${GREEN}选择的路径: $selected_path${NC}"
read -p "是否使用此路径?(y/N): " use_path
if [[ "$use_path" =~ ^[Yy]$ ]]; then
FTP_REMOTE_PATH="$selected_path"
save_config
echo -e "${GREEN}FTP远端路径已更新${NC}"
fi
fi
;;
2)
if [ -z "$WEBDAV_URL" ]; then
echo -e "${RED}请先配置WebDAV连接信息${NC}"
configure_webdav
else
selected_path=$(remote_path_selector "webdav" "$WEBDAV_REMOTE_PATH")
echo -e "${GREEN}选择的路径: $selected_path${NC}"
read -p "是否使用此路径?(y/N): " use_path
if [[ "$use_path" =~ ^[Yy]$ ]]; then
WEBDAV_REMOTE_PATH="$selected_path"
save_config
echo -e "${GREEN}WebDAV远端路径已更新${NC}"
fi
fi
;;
3)
if [ -z "$SMB_SERVER" ] || [ -z "$SMB_SHARE" ]; then
echo -e "${RED}请先配置SMB连接信息${NC}"
configure_smb
else
selected_path=$(remote_path_selector "smb" "$SMB_REMOTE_PATH")
echo -e "${GREEN}选择的路径: $selected_path${NC}"
read -p "是否使用此路径?(y/N): " use_path
if [[ "$use_path" =~ ^[Yy]$ ]]; then
SMB_REMOTE_PATH="$selected_path"
save_config
echo -e "${GREEN}SMB远端路径已更新${NC}"
fi
fi
;;
0)
return
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
}
# 配置管理
configure_connections() {
echo -e "${CYAN}=== 配置连接信息 ===${NC}"
echo
echo "1. 配置FTP连接"
echo "2. 配置WebDAV连接"
echo "3. 配置SMB/CIFS连接"
echo "4. 查看所有配置"
echo "0. 返回"
echo
read -p "请选择: " choice
case $choice in
1)
configure_ftp
;;
2)
configure_webdav
;;
3)
configure_smb
;;
4)
show_configurations
;;
0)
return
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
}
# 显示所有配置
show_configurations() {
echo -e "${CYAN}[FTP配置]${NC}"
echo " 服务器: $FTP_HOST:$FTP_PORT"
echo " 用户名: $FTP_USER"
echo " 密码: [已保存]"
echo " 远端路径: $FTP_REMOTE_PATH"
echo " 挂载点: $FTP_MOUNT_POINT"
echo
echo -e "${YELLOW}[WebDAV配置]${NC}"
echo " URL: $WEBDAV_URL"
echo " 用户名: $WEBDAV_USER"
echo " 密码: [已保存]"
echo " 远端路径: $WEBDAV_REMOTE_PATH"
echo " 挂载点: $WEBDAV_MOUNT_POINT"
echo
echo -e "${PURPLE}[SMB配置]${NC}"
echo " 服务器: $SMB_SERVER"
echo " 共享: $SMB_SHARE"
echo " 域名: $SMB_DOMAIN"
echo " 用户名: $SMB_USER"
echo " 密码: [已保存]"
echo " 远端路径: $SMB_REMOTE_PATH"
echo " 挂载点: $SMB_MOUNT_POINT"
}
# 测试连接
test_connections() {
echo -e "${CYAN}=== 测试连接 ===${NC}"
echo
echo "1. 测试FTP连接"
echo "2. 测试WebDAV连接"
echo "3. 测试SMB连接"
echo "4. 测试所有连接"
echo "0. 返回"
echo
read -p "请选择: " choice
case $choice in
1)
test_ftp
;;
2)
test_webdav
;;
3)
test_smb
;;
4)
echo -e "${BLUE}测试所有连接...${NC}"
test_ftp
test_webdav
test_smb
;;
0)
return
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
}
# 查看挂载历史
show_mount_history() {
echo -e "${CYAN}=== 挂载历史 ===${NC}"
if [ -f "$MOUNT_HISTORY" ]; then
echo -e "${YELLOW}时间戳 协议 服务器 远端路径 挂载点${NC}"
echo "-----------------------------------------------------------------------------------------------"
tail -20 "$MOUNT_HISTORY" | while IFS='|' read -r timestamp protocol server remote_path mount_point; do
printf "%-23s %-8s %-25s %-20s %s\n" "$timestamp" "$protocol" "$server" "$remote_path" "$mount_point"
done
else
echo -e "${YELLOW}暂无挂载历史${NC}"
fi
}
# 批量卸载所有
unmount_all() {
echo -e "${RED}=== 卸载所有挂载 ===${NC}"
local mounted=0
# 卸载FTP
if mount | grep -q "$FTP_MOUNT_POINT"; then
echo -n "卸载FTP... "
fusermount -u "$FTP_MOUNT_POINT" 2>/dev/null && echo "✓" || echo "✗"
mounted=1
fi
# 卸载WebDAV
if mount | grep -q "$WEBDAV_MOUNT_POINT"; then
echo -n "卸载WebDAV... "
sudo umount "$WEBDAV_MOUNT_POINT" 2>/dev/null && echo "✓" || echo "✗"
mounted=1
fi
# 卸载SMB
if mount | grep -q "$SMB_MOUNT_POINT"; then
echo -n "卸载SMB... "
sudo umount "$SMB_MOUNT_POINT" 2>/dev/null && echo "✓" || echo "✗"
mounted=1
fi
if [ $mounted -eq 0 ]; then
echo -e "${YELLOW}没有需要卸载的挂载${NC}"
else
echo -e "${GREEN}所有挂载已卸载${NC}"
fi
}
# 清理挂载点
clean_mount_points() {
echo -e "${RED}=== 清理挂载点 ===${NC}"
echo "以下目录将被清空:"
echo " 1. $FTP_MOUNT_POINT"
echo " 2. $WEBDAV_MOUNT_POINT"
echo " 3. $SMB_MOUNT_POINT"
echo " 4. 所有以上目录"
echo " 0. 取消"
echo
read -p "请选择: " choice
case $choice in
1)
if [ -d "$FTP_MOUNT_POINT" ]; then
rm -rf "${FTP_MOUNT_POINT:?}/"*
echo -e "${GREEN}FTP挂载点已清理${NC}"
fi
;;
2)
if [ -d "$WEBDAV_MOUNT_POINT" ]; then
rm -rf "${WEBDAV_MOUNT_POINT:?}/"*
echo -e "${GREEN}WebDAV挂载点已清理${NC}"
fi
;;
3)
if [ -d "$SMB_MOUNT_POINT" ]; then
rm -rf "${SMB_MOUNT_POINT:?}/"*
echo -e "${GREEN}SMB挂载点已清理${NC}"
fi
;;
4)
for dir in "$FTP_MOUNT_POINT" "$WEBDAV_MOUNT_POINT" "$SMB_MOUNT_POINT"; do
if [ -d "$dir" ]; then
rm -rf "${dir:?}/"*
echo -e "${GREEN}$dir 已清理${NC}"
fi
done
;;
0)
return
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
}
# 创建快捷命令
create_shortcuts() {
echo -e "${CYAN}=== 创建快捷命令 ===${NC}"
local script_path="$(realpath "$0")"
local bin_dir="$HOME/bin"
mkdir -p "$bin_dir"
# 创建协议特定的快捷方式
cat > "$bin_dir/mount-ftp" << EOF #!/bin/bash "$script_path" --mount ftp EOF cat > "$bin_dir/mount-webdav" << EOF #!/bin/bash "$script_path" --mount webdav EOF cat > "$bin_dir/mount-smb" << EOF #!/bin/bash "$script_path" --mount smb EOF # 创建卸载快捷方式 cat > "$bin_dir/umount-all" << EOF #!/bin/bash "$script_path" --unmount-all EOF # 创建带路径的快捷方式 cat > "$bin_dir/mount-ftp-path" << EOF
#!/bin/bash
echo "当前远端路径: \$FTP_REMOTE_PATH"
read -p "输入新的远端路径 (或回车使用当前): " new_path
if [ -n "\$new_path" ]; then
FTP_REMOTE_PATH="\$new_path"
"$script_path" --save-config
fi
"$script_path" --mount ftp
EOF
# 设置执行权限
chmod +x "$bin_dir"/*
# 添加到PATH
if ! echo "$PATH" | grep -q "$bin_dir"; then
echo -e "${YELLOW}请将以下行添加到 ~/.bashrc 或 ~/.bash_profile:${NC}"
echo "export PATH=\"\$PATH:$bin_dir\""
echo
echo -e "${BLUE}或执行以下命令立即生效:${NC}"
echo "export PATH=\"\$PATH:$bin_dir\""
fi
echo -e "${GREEN}快捷命令已创建到 $bin_dir${NC}"
echo -e "${YELLOW}可用命令:${NC}"
echo " mount-ftp # 挂载FTP"
echo " mount-webdav # 挂载WebDAV"
echo " mount-smb # 挂载SMB"
echo " mount-ftp-path # 设置路径后挂载FTP"
echo " umount-all # 卸载所有"
}
# 命令行参数处理
handle_cli_args() {
case "$1" in
--mount)
case "$2" in
ftp)
mount_ftp
;;
webdav)
mount_webdav
;;
smb)
mount_smb
;;
*)
echo "用法: $0 --mount {ftp|webdav|smb}"
exit 1
;;
esac
exit 0
;;
--unmount-all)
unmount_all
exit 0
;;
--status)
show_mount_status full
exit 0
;;
--browse)
browse_remote
exit 0
;;
--import-url)
quick_import
exit 0
;;
--save-config)
save_config
exit 0
;;
--help)
echo "多协议挂载管理工具 (支持远端目录)"
echo "用法:"
echo " $0 # 交互式模式"
echo " $0 --mount ftp # 挂载FTP"
echo " $0 --mount webdav # 挂载WebDAV"
echo " $0 --mount smb # 挂载SMB"
echo " $0 --unmount-all # 卸载所有"
echo " $0 --status # 显示状态"
echo " $0 --browse # 浏览远程目录"
echo " $0 --import-url # 快速URL导入"
echo " $0 --save-config # 保存配置"
exit 0
;;
esac
}
# 设置开机自动挂载
setup_autostart() {
echo -e "${CYAN}=== 设置开机自动挂载 ===${NC}"
echo
echo "注意:此功能需要root权限"
echo
echo "1. 创建FTP自动挂载服务"
echo "2. 创建WebDAV自动挂载服务"
echo "3. 创建SMB自动挂载服务"
echo "4. 查看/etc/fstab示例(包含远端路径)"
echo "0. 返回"
echo
read -p "请选择: " choice
case $choice in
1)
create_ftp_service
;;
2)
create_webdav_service
;;
3)
create_smb_service
;;
4)
show_fstab_examples
;;
0)
return
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
}
# 显示fstab示例(包含远端路径)
show_fstab_examples() {
echo -e "${YELLOW}/etc/fstab 配置示例 (包含远端路径):${NC}"
echo
echo "# FTP (需要先安装curlftpfs)"
echo "# 格式: curlftpfs#ftp://user:pass@host:port/path /mnt/ftp fuse allow_other,_netdev,uid=1000,gid=1000 0 0"
echo "curlftpfs#ftp://$FTP_USER:$FTP_PASS@$FTP_HOST:$FTP_PORT$FTP_REMOTE_PATH $FTP_MOUNT_POINT fuse allow_other,_netdev,uid=$(id -u),gid=$(id -g) 0 0"
echo
echo "# WebDAV"
echo "# 格式: http://host/path /mnt/webdav davfs _netdev,noauto,user,uid=1000,gid=1000 0 0"
echo "${WEBDAV_URL%/}$WEBDAV_REMOTE_PATH $WEBDAV_MOUNT_POINT davfs _netdev,noauto,user,uid=$(id -u),gid=$(id -g) 0 0"
echo
echo "# SMB/CIFS"
echo "# 格式: //server/share/path /mnt/smb cifs username=user,password=pass,uid=1000,gid=1000,_netdev 0 0"
echo "//$SMB_SERVER/$SMB_SHARE$SMB_REMOTE_PATH $SMB_MOUNT_POINT cifs username=$SMB_USER,password=$SMB_PASS,uid=$(id -u),gid=$(id -g),_netdev 0 0"
echo
echo -e "${RED}警告:密码会以明文形式存储在fstab中,请谨慎使用!${NC}"
}
# 主程序
main() {
# 处理命令行参数
if [ $# -gt 0 ]; then
handle_cli_args "$@"
fi
# 检查依赖
check_dependencies
# 加载配置
load_config
while true; do
show_main_menu
read -p "请选择操作 [0-7]: " choice
case $choice in
1)
# 协议选择
while true; do
show_protocol_menu
read -p "选择协议 [0-7]: " protocol_choice
case $protocol_choice in
1)
echo -e "\n${GREEN}[FTP操作]${NC}"
echo "1. 挂载FTP"
echo "2. 卸载FTP"
echo "3. 配置FTP"
echo "4. 浏览FTP目录"
echo "0. 返回"
read -p "请选择: " ftp_op
case $ftp_op in
1) mount_ftp ;;
2) umount_ftp ;;
3) configure_ftp ;;
4) browse_remote ;;
0) continue ;;
*) echo -e "${RED}无效选择${NC}" ;;
esac
;;
2)
echo -e "\n${YELLOW}[WebDAV操作]${NC}"
echo "1. 挂载WebDAV"
echo "2. 卸载WebDAV"
echo "3. 配置WebDAV"
echo "4. 浏览WebDAV目录"
echo "0. 返回"
read -p "请选择: " webdav_op
case $webdav_op in
1) mount_webdav ;;
2) umount_webdav ;;
3) configure_webdav ;;
4) browse_remote ;;
0) continue ;;
*) echo -e "${RED}无效选择${NC}" ;;
esac
;;
3)
echo -e "\n${PURPLE}[SMB操作]${NC}"
echo "1. 挂载SMB"
echo "2. 卸载SMB"
echo "3. 配置SMB"
echo "4. 浏览SMB目录"
echo "0. 返回"
read -p "请选择: " smb_op
case $smb_op in
1) mount_smb ;;
2) umount_smb ;;
3) configure_smb ;;
4) browse_remote ;;
0) continue ;;
*) echo -e "${RED}无效选择${NC}" ;;
esac
;;
4)
show_mount_status full
;;
5)
unmount_all
;;
6)
clean_mount_points
;;
7)
quick_import
;;
0)
break
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
echo
read -p "按回车键继续..."
done
;;
2)
configure_connections
;;
3)
test_connections
;;
4)
show_mount_history
;;
5)
setup_autostart
;;
6)
create_shortcuts
;;
7)
browse_remote
;;
0)
echo -e "${GREEN}感谢使用,再见!${NC}"
exit 0
;;
*)
echo -e "${RED}无效选择,请重新输入${NC}"
;;
esac
echo
read -p "按回车键继续..."
done
}
# 运行主程序
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi