Bash脚本中FTP命令凭证错误仍返回true问题排查
问题:FTP脚本无论凭证正确与否均判定执行成功
以下是我的Bash脚本:
#!/bin/bash # FTP Vars FTP_IP=IPv4 FTP_USERNAME=USERNAME FTP_PASSWORD=PASSWORD FTP_PATH=/SOME_PATH # FTP Connection, Upload and Delete function upload() { ftp -n -v $FTP_IP << EOF ascii user $FTP_USERNAME $FTP_PASSWORD prompt cd $FTP_PATH ls bye EOF } if upload then echo 'done' else echo 'not done' fi
问题在于,无论输入的密码正确与否,输出中都会显示done,这意味着upload函数被判定执行成功。
正确凭证的输出:
Connected to IPv4. 220---------- Welcome to Pure-FTPd [privsep] [TLS] ---------- 220-You are user number 1 of 50 allowed. 220-Local time is now 23:32. Server port: 21. 220-This is a private system - No anonymous login 220-IPv6 connections are also welcome on this server. 220 You will be disconnected after 15 minutes of inactivity. 200 TYPE is now ASCII 331 User group OK. Password required 230-This server supports FXP transfers 230 OK. Current restricted directory is / Remote system type is UNIX. Using binary mode to transfer files. Interactive mode off. 250 OK. Current directory is /SOME_PATH 229 Extended Passive mode OK (|||35332|) 150 Accepted data connection drwxr-xr-x 7 1047 group 92 May 1 12:49 . drwx--x--- 8 1047 1003 181 May 1 21:29 .. drwxr-xr-x 3 1047 group 24 May 1 12:49 dir1 drwxr-xr-x 3 1047 group 24 May 1 12:49 dir2 226-Options: -a -l 226 7 matches total 221-Goodbye. You uploaded 0 and downloaded 0 kbytes. 221 Logout. done
错误凭证的输出:
Connected to IPv4. 220---------- Welcome to Pure-FTPd [privsep] [TLS] ---------- 220-You are user number 1 of 50 allowed. 220-Local time is now 23:36. Server port: 21. 220-This is a private system - No anonymous login 220-IPv6 connections are also welcome on this server. 220 You will be disconnected after 15 minutes of inactivity. 200 TYPE is now ASCII 331 User group OK. Password required 530 Login authentication failed Login failed. Interactive mode off. 530 You aren't logged in 530 You aren't logged in 530 You aren't logged in 530 You aren't logged in 221-Goodbye. You uploaded 0 and downloaded 0 kbytes. 221 Logout. done
解决方法
问题根源是:默认情况下,ftp命令即便登录失败,最终也会返回退出码0,所以脚本里的if upload只会判断ftp命令本身是否执行完毕,而不会校验登录或后续操作是否成功。
要实现正确的结果判断,需要捕获ftp的输出内容,检查其中是否包含错误标识(比如530 Login authentication failed或Login failed.),再根据检查结果设置函数的退出码。修改后的脚本如下:
#!/bin/bash # FTP Vars FTP_IP=IPv4 FTP_USERNAME=USERNAME FTP_PASSWORD=PASSWORD FTP_PATH=/SOME_PATH # FTP Connection, Upload and Delete function upload() { # 捕获ftp命令的所有输出(包括stderr),同时打印到终端 local ftp_output ftp_output=$(ftp -n -v "$FTP_IP" 2>&1 << EOF ascii user $FTP_USERNAME $FTP_PASSWORD prompt cd $FTP_PATH ls bye EOF ) echo "$ftp_output" # 检查输出中是否存在登录失败的关键词 if echo "$ftp_output" | grep -qE "530 Login authentication failed|Login failed\."; then return 1 # 返回非0值表示执行失败 else return 0 # 返回0表示执行成功 fi } if upload then echo 'done' else echo 'not done' fi
修改说明:
- 将
ftp命令的所有输出(包括标准错误流)捕获到变量中,确保不会遗漏错误信息 - 用
grep检查输出内容,匹配登录失败的特征字符串 - 根据检查结果返回不同的退出码,让
if语句能正确判断执行结果
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

