我想使用 bash 脚本中的 sftp(仅)将文件从本地系统“放置”到 FTP 服务器。
我想抑制除错误之外的所有消息:
sftp $user@$server 2>&1 1>/dev/null <<EOF
put $local_file_path $remote_file_path
EOF
成功时命令的输出:
Connecting to <server>...
为什么我仍然得到它?
答案1
可能是因为Connecting to <server>...
发送到文件描述符 2 (stderr)。请记住,文件描述符 1 (stdout) 和 2 (stderr) 之间的唯一区别是前者是传统上用于普通消息,而后者是传统上用于调试或错误输出。但是,程序决定什么内容进入一个通道或另一个通道,您可以重定向一个输出或另一个输出,但您无法决定在哪里打印内容。例如,您不能强制只将错误发送到 stderr。
答案2
我确实有同样的问题,所以我想出了这个解决方案。它不是 100% 的正常输出stderr
,但它有助于确定导致错误的原因。
sftp $user@$server > /dev/null 2>&1 <<EOF
put $local_file_path $remote_file_path
EOF
sftp_status=$?
case $sftp_status in
0) sftp_error="";;
1) sftp_error="Error 1: Generic error - Undetermined error in file copy";;
2) sftp_error="Error 2: Remote host connection failure";;
3) sftp_error="Error 3: Destination is not directory, but it should be";;
4) sftp_error="Error 4: Connecting to host failed";;
5) sftp_error="Error 5: Connection lost for some reason";;
6) sftp_error="Error 6: File does not exist";;
7) sftp_error="Error 7: No permission to access file";;
8) sftp_error="Error 8: Undetermined error from sshfilexfer";;
9) sftp_error="Error 9: File transfer protocol mismatch";;
65) sftp_error="Error 65: Host not allowed to connect";;
66) sftp_error="Error 66: Protocol error";;
67) sftp_error="Error 67: Key exchange failed";;
68) sftp_error="Error 68: Host authentication failed";;
69) sftp_error="Error 69: MAC error";;
70) sftp_error="Error 70: Compression error (not used in SSH2)";;
71) sftp_error="Error 71: Service not available";;
72) sftp_error="Error 72: Protocol version not supported";;
73) sftp_error="Error 73: Host key not verifiable";;
74) sftp_error="Error 74: Connection lost";;
75) sftp_error="Error 75: Disconnected by application";;
76) sftp_error="Error 76: Too many connections";;
77) sftp_error="Error 77: Cancelled by user";;
78) sftp_error="Error 78: No more auth methods available";;
79) sftp_error="Error 79: Illegal user name";;
255) sftp_error="Error 255: Error occurred in SSH";;
*) sftp_error="Unknown sftp Error";;
esac
echo $sftp_error
状态代码基于此列表:https://support2.microfocus.com/techdocs/2487.html
您收到的状态代码取决于您的 sftp 客户端
所以有些客户端只使用状态码0,1&255
答案3
遗憾的是没有人正确回答这个问题。
尝试:
sftp_command 2>&1 >/dev/null | grep -v 'Connecting to'
将 stderr 重定向到 stdout 并然后将 stdout 重定向到 /dev/null 让您可以显示除连接到之外的所有内容。
答案4
为什么我仍然得到它?
因为sftp
将此消息打印到stderr
,并且您使用 重定向stderr
到stdout
,即您的终端2>&1
。
您会看到,文件描述符之类的文件描述符&1
不是链接(或指针,如果您熟悉这个概念),而是值。所以当你输入 时2>&1
,真正发生的是:
- 您的 shell 会找出文件描述符 1 (
stdout
) 当前指向的位置。就您而言,您正在交互式 shell 中运行它,因此stdout
指向您的终端。 - 文件描述符 2 (
stderr
) 也设置到您的终端。
因此,当您稍后更改第一个文件描述符时(使用1>/dev/null
),它对重定向没有影响stderr
,因为stderr
不会依靠以stdout
任何方式。
要将所有内容重定向到/dev/null
,您应该考虑文件描述符的值如何相互复制;这将导致您重新安排重定向,如下所示:
sftp $user@$server 1>/dev/null 2>&1
现在您的stdout
值设置为/dev/null
,然后stderr
设置为 的当前值stdout
,即/dev/null
。耶!