smbclient 是一个功能强大的SMB/CIFS客户端工具,允许Linux系统访问和操作Windows共享、Samba服务器和其他支持SMB/CIFS协议的网络共享。它提供了一个类似FTP的交互式界面,支持文件传输、共享浏览和基本管理操作。
在基于Debian/Ubuntu的系统上安装:
sudo apt-get update
sudo apt-get install samba-client samba-common
在基于RHEL/CentOS的系统上安装:
sudo yum install samba-client
# 或者
sudo dnf install samba-client
在基于Arch Linux的系统上安装:
sudo pacman -S samba
在基于macOS的系统上安装(通过Homebrew):
brew install samba
smbclient [选项] 服务位置 [密码] [子命令]
或者交互式模式:
smbclient //服务器/共享名 [选项]
| 选项 | 说明 |
|---|---|
-L, --list=主机 |
列出指定主机的可用共享 |
-U, --user=用户名[%密码] |
指定用户名和密码 |
-W, --workgroup=工作组 |
指定工作组/域 |
-I, --ip-address=IP |
指定服务器的IP地址 |
-N, --no-pass |
不使用密码,匿名访问 |
-A, --authentication-file=文件 |
从文件读取用户名和密码 |
-c, --command=命令 |
执行命令后退出(非交互模式) |
-t, --timeout=秒 |
设置操作超时时间 |
-p, --port=端口 |
指定SMB端口(默认445) |
-d, --debuglevel=级别 |
设置调试级别(0-10) |
-s, --configfile=文件 |
指定配置文件 |
-m, --max-protocol=协议 |
指定最大协议版本 |
-e, --encrypt |
使用加密传输 |
-M, --message=主机 |
发送WinPopup消息 |
--help |
显示帮助信息 |
--version |
显示版本信息 |
列出指定Windows主机或Samba服务器的可用共享:
# 匿名列出共享
smbclient -L //192.168.1.100 -N
# 使用用户名列出共享
smbclient -L //192.168.1.100 -U username
# 指定用户名和密码
smbclient -L //192.168.1.100 -U username%password
# 指定工作组
smbclient -L //WINSERVER -W WORKGROUP -U username%password
输出示例:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk 远程管理
C$ Disk 默认共享
IPC$ IPC 远程 IPC
Public Disk 公共共享
Users Disk 用户目录
Reconnecting with SMB1 for workgroup listing.
Server Comment
--------- -------
WINSERVER
Workgroup Master
--------- -------
WORKGROUP WINSERVER
# 连接共享目录
smbclient //192.168.1.100/Public -U username%password
# 连接后进入smb: \>提示符
# 可以执行各种命令,如ls、get、put等
# 执行单个命令后退出
smbclient //192.168.1.100/Public -U username%password -c "ls"
# 执行多个命令
smbclient //192.168.1.100/Public -U username%password -c "ls; get file.txt; exit"
# 尝试匿名访问
smbclient //192.168.1.100/Public -N
# 匿名列出共享
smbclient -L //192.168.1.100 -N
连接共享后进入交互式模式,可用命令:
| 命令 | 说明 |
|---|---|
help [命令] |
显示帮助信息 |
? |
同help |
ls [目录] |
列出目录内容 |
dir [目录] |
同ls |
cd [目录] |
切换目录 |
lcd [目录] |
切换本地目录 |
pwd |
显示当前远程目录 |
lpwd |
显示当前本地目录 |
get 远程文件 [本地文件] |
下载文件 |
put 本地文件 [远程文件] |
上传文件 |
mget 模式 |
批量下载匹配文件 |
mput 模式 |
批量上传匹配文件 |
mkdir 目录 |
创建目录 |
rmdir 目录 |
删除目录 |
rm 文件 |
删除文件 |
del 文件 |
同rm |
rename 旧文件 新文件 |
重命名文件 |
more 文件 |
查看文件内容 |
mask 模式 |
设置文件掩码(通配符) |
recurse |
切换递归模式(目录操作) |
prompt |
切换交互提示(批量操作时) |
queue |
显示操作队列 |
quit |
退出smbclient |
exit |
同quit |
tar c|x [IXbgNa] |
tar备份/恢复 |
blocksize 大小 |
设置块大小 |
tarmode 模式 |
设置tar模式 |
setmode 文件 模式 |
设置文件属性 |
# 连接共享
smbclient //192.168.1.100/Public -U username%password
# 连接成功后的交互操作示例:
smb: \> help # 显示帮助
smb: \> ls # 列出文件
smb: \> cd Documents # 进入Documents目录
smb: \> pwd # 显示当前目录
smb: \> lcd ~/downloads # 切换本地目录
smb: \> lpwd # 显示本地目录
smb: \> get report.pdf # 下载文件
smb: \> put local.txt # 上传文件
smb: \> mkdir newdir # 创建目录
smb: \> rename old new # 重命名文件
smb: \> rm temp.txt # 删除文件
smb: \> mget *.txt # 下载所有txt文件
smb: \> mput *.pdf # 上传所有pdf文件
smb: \> recurse on # 开启递归模式
smb: \> prompt off # 关闭提示(批量操作)
smb: \> quit # 退出
# 非交互式批量下载
smbclient //192.168.1.100/Public -U username%password -c "prompt; mget *.pdf; exit"
# 或交互式操作
smb: \> prompt
smb: \> mget *.pdf
smb: \> quit
# 递归下载整个目录
smb: \> tar c Documents
# 这会创建一个名为Documents.tar的tar备份
# 恢复tar备份
smb: \> tar x backup.tar
smbclient可以使用以下配置文件:
| 配置文件 | 位置 | 说明 |
|---|---|---|
| 全局配置 | /etc/samba/smb.conf |
Samba主配置文件 |
| 用户配置 | ~/.smb/smb.conf |
用户级配置文件 |
| 凭据文件 | ~/.smbcredentials |
存储用户名和密码 |
| 主机缓存 | ~/.smbhosts |
主机名缓存 |
# 创建凭据文件
nano ~/.smbcredentials
# 内容:
username=myusername
password=mypassword
domain=WORKGROUP
# 设置权限
chmod 600 ~/.smbcredentials
# 使用凭据文件
smbclient //server/share -A ~/.smbcredentials
[global]
workgroup = WORKGROUP
client min protocol = NT1
client max protocol = SMB3
client lanman auth = yes
client ntlmv2 auth = yes
[homes]
comment = Home Directories
browseable = no
read only = no
create mask = 0700
directory mask = 0700
#!/bin/bash
# backup_windows_share.sh - 自动备份Windows共享
SERVER="192.168.1.100"
SHARE="Backup"
USERNAME="backupuser"
PASSWORD="password123"
LOCAL_DIR="/backup/windows"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="windows_backup_$DATE.tar.gz"
echo "开始备份Windows共享..."
echo "服务器: $SERVER"
echo "共享: $SHARE"
echo "时间: $DATE"
# 创建本地目录
mkdir -p "$LOCAL_DIR"
# 使用smbclient创建tar备份
smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "tar c *" | \
gzip > "$LOCAL_DIR/$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "备份成功: $BACKUP_FILE"
echo "大小: $(du -h "$LOCAL_DIR/$BACKUP_FILE" | cut -f1)"
else
echo "备份失败"
exit 1
fi
# 清理旧备份(保留最近7天)
find "$LOCAL_DIR" -name "windows_backup_*.tar.gz" -mtime +7 -delete
echo "已清理7天前的旧备份"
#!/bin/bash
# sync_windows_share.sh - 同步Windows共享
SERVER="192.168.1.100"
SHARE="Documents"
USERNAME="syncuser"
PASSWORD="syncpass123"
LOCAL_DIR="/data/sync/$SHARE"
REMOTE_DIR="/"
LOG_FILE="/var/log/sync_windows.log"
echo "$(date) 开始同步 $SHARE" >> "$LOG_FILE"
# 创建本地目录
mkdir -p "$LOCAL_DIR"
# 同步文件
smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "
prompt
recurse
mask *.pdf,*.doc,*.docx,*.xls,*.xlsx,*.ppt,*.pptx
lcd $LOCAL_DIR
mget *
" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "$(date) 同步成功" >> "$LOG_FILE"
echo "同步的文件数: $(find "$LOCAL_DIR" -type f | wc -l)" >> "$LOG_FILE"
else
echo "$(date) 同步失败" >> "$LOG_FILE"
fi
# 发送消息到Windows计算机
smbclient -M WINDOWS_PC << EOF
From: Linux Server
Subject: 服务器通知
正文:服务器将于今晚10点进行维护,请保存工作。
EOF
# 或使用单行命令
echo -e "From: Admin\n\n系统维护通知" | smbclient -M COMPUTER_NAME
session setup failed: NT_STATUS_LOGON_FAILURE
解决方案:
# 1. 检查用户名和密码
smbclient //server/share -U username%password
# 2. 检查工作组/域
smbclient //server/share -U username%password -W DOMAIN
# 3. 使用IP地址代替主机名
smbclient //192.168.1.100/share -U username%password
# 4. 检查防火墙设置
# Windows: 确保文件和打印机共享被允许
# Linux: sudo ufw allow samba
# 5. 检查SMB协议版本
smbclient //server/share -U username%password -m SMB2
smbclient //server/share -U username%password -m NT1
tree connect failed: NT_STATUS_BAD_NETWORK_NAME
解决方案:
# 1. 检查共享名是否正确
smbclient -L //server -U username%password
# 2. 共享可能需要完整路径
smbclient //server/C$/Windows -U username%password
# 3. 尝试使用管理员共享
smbclient //server/ADMIN$ -U administrator%password
# 4. 检查共享权限
Connection to SERVER failed (Error NT_STATUS_CONNECTION_REFUSED)
解决方案:
# 1. 检查网络连通性
ping 192.168.1.100
# 2. 检查SMB端口
telnet 192.168.1.100 445
telnet 192.168.1.100 139
# 3. 增加超时时间
smbclient //server/share -U username%password -t 60
# 4. 使用WINS服务器
smbclient //server/share -U username%password -W WORKGROUP
NT_STATUS_ACCESS_DENIED listing \*
解决方案:
# 1. 检查用户权限
# 确保用户有访问共享的权限
# 2. 使用不同用户
smbclient //server/share -U administrator%password
# 3. 检查共享权限设置
# Windows: 右键共享 -> 属性 -> 共享权限/安全权限
# 启用详细调试
smbclient //server/share -U username%password -d 3
# 调试级别说明:
# 0: 无调试
# 1: 基本调试
# 2: 详细调试
# 3: 非常详细
# 4: 调试所有
# 保存调试日志到文件
smbclient //server/share -U username%password -d 3 2>&1 | tee debug.log
# 查看Samba日志
sudo tail -f /var/log/samba/log.smbd
sudo tail -f /var/log/samba/log.nmbd
# 查看客户端日志
sudo tail -f /var/log/samba/client.log
| 命令 | 说明 |
|---|---|
smbstatus |
显示当前Samba连接状态 |
testparm |
测试Samba配置文件语法 |
nmblookup |
NetBIOS名称查询工具 |
mount.cifs |
挂载CIFS/SMB文件系统 |
net |
Samba网络管理工具 |
rpcclient |
MS-RPC客户端工具 |
smbtree |
以树形结构显示可用共享 |
smbtar |
备份/恢复SMB共享 |
除了使用smbclient,还可以直接挂载SMB共享到本地文件系统:
# 安装cifs-utils
sudo apt-get install cifs-utils
# 创建挂载点
sudo mkdir -p /mnt/windows_share
# 挂载共享
sudo mount -t cifs //192.168.1.100/Public /mnt/windows_share -o username=user,password=pass
# 使用凭据文件挂载
echo "username=user" > ~/.smbcreds
echo "password=pass" >> ~/.smbcreds
chmod 600 ~/.smbcreds
sudo mount -t cifs //server/share /mnt/windows_share -o credentials=~/.smbcreds
# 卸载共享
sudo umount /mnt/windows_share
| 协议 | 版本 | 说明 |
|---|---|---|
| CIFS | SMB1 | 传统协议,Windows NT/2000/XP |
| SMB2 | 2.0 | Windows Vista/Server 2008 |
| SMB2.1 | 2.1 | Windows 7/Server 2008 R2 |
| SMB3 | 3.0 | Windows 8/Server 2012 |
| SMB3.1.1 | 3.1.1 | Windows 10/Server 2016+ |
指定SMB协议版本:
# 使用特定协议版本
smbclient //server/share -U user%pass -m SMB2
smbclient //server/share -U user%pass -m SMB3
smbclient //server/share -U user%pass -m NT1 # SMB1
# 配置默认协议版本(在smb.conf中)
# client min protocol = SMB2
# client max protocol = SMB3
#!/bin/bash
# monitor_share.sh - 监控共享中的新文件
SERVER="192.168.1.100"
SHARE="Incoming"
USERNAME="monitor"
PASSWORD="monitor123"
LOCAL_DIR="/data/incoming"
STATE_FILE="/tmp/smbclient_last_check"
LOG_FILE="/var/log/monitor_share.log"
echo "$(date) 开始检查新文件" >> "$LOG_FILE"
# 获取远程文件列表
REMOTE_FILES=$(smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "ls" 2>/dev/null | \
grep -E '^ [A-Za-z0-9]' | awk '{print $1}')
# 检查是否有新文件
if [ -f "$STATE_FILE" ]; then
LAST_FILES=$(cat "$STATE_FILE")
NEW_FILES=$(echo "$REMOTE_FILES" | grep -v -F "$LAST_FILES")
else
NEW_FILES="$REMOTE_FILES"
fi
# 下载新文件
if [ -n "$NEW_FILES" ]; then
echo "$(date) 发现新文件: $NEW_FILES" >> "$LOG_FILE"
for FILE in $NEW_FILES; do
smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "get $FILE" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "$(date) 下载成功: $FILE" >> "$LOG_FILE"
else
echo "$(date) 下载失败: $FILE" >> "$LOG_FILE"
fi
done
else
echo "$(date) 没有新文件" >> "$LOG_FILE"
fi
# 保存当前文件列表
echo "$REMOTE_FILES" > "$STATE_FILE"
#!/bin/bash
# smb_health_check.sh - SMB共享健康检查
CONFIG_FILE="/etc/samba/smb_servers.conf"
LOG_FILE="/var/log/smb_health.log"
TIMEOUT=30
echo "=== SMB共享健康检查 $(date) ===" | tee -a "$LOG_FILE"
# 读取服务器列表
while IFS=, read -r SERVER SHARE USERNAME PASSWORD || [ -n "$SERVER" ]; do
# 跳过注释和空行
[[ "$SERVER" =~ ^# ]] && continue
[[ -z "$SERVER" ]] && continue
echo "检查: //$SERVER/$SHARE" | tee -a "$LOG_FILE"
# 测试连接
timeout $TIMEOUT smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "ls" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "状态: 正常" | tee -a "$LOG_FILE"
# 获取共享信息
INFO=$(timeout $TIMEOUT smbclient "//$SERVER/$SHARE" -U "$USERNAME%$PASSWORD" -c "du" 2>/dev/null | head -1)
echo "信息: $INFO" | tee -a "$LOG_FILE"
else
echo "状态: 失败" | tee -a "$LOG_FILE"
echo "错误: 无法连接" | tee -a "$LOG_FILE"
fi
echo "---" | tee -a "$LOG_FILE"
done < "$CONFIG_FILE"
echo "检查完成" | tee -a "$LOG_FILE"
-c选项执行脚本,结合bash实现自动化recurse命令启用目录递归操作mget/mput配合mask和prompttar命令进行完整的共享备份/恢复-e选项启用SMB加密-m指定协议版本,解决兼容性问题-d 3进行详细调试,分析连接问题| 用途 | 命令示例 |
|---|---|
| 列出共享 | smbclient -L //server -U user%pass |
| 连接共享 | smbclient //server/share -U user%pass |
| 匿名连接 | smbclient //server/share -N |
| 执行单命令 | smbclient //server/share -U user%pass -c "ls" |
| 下载文件 | smbclient //server/share -U user%pass -c "get file.txt" |
| 上传文件 | smbclient //server/share -U user%pass -c "put local.txt" |
| 批量下载 | smbclient //server/share -U user%pass -c "mget *.pdf" |
| 创建目录 | smbclient //server/share -U user%pass -c "mkdir newdir" |
| 删除文件 | smbclient //server/share -U user%pass -c "rm file.txt" |
| 发送消息 | smbclient -M computername |
| 使用凭据文件 | smbclient //server/share -A ~/.smbcredentials |
| 调试模式 | smbclient //server/share -U user%pass -d 3 |