我试图捕捉 sftp 的密码提示,但不知何故它不是来自 STDIN 或 STDERR。它可能来自子流程。
以下是我的测试。我尝试将密码提示重定向到文件。我尝试了文件句柄号 1 到 4。但没有成功。
mypc:/home/myname$ sftp localhost >/tmp/junk
myname@localhost's password:
mypc:/home/myname$ sftp localhost 2>/tmp/junk
myname@localhost's password:
mypc:/home/myname$ sftp localhost 3>/tmp/junk
myname@localhost's password:
mypc:/home/myname$ sftp localhost 4>/tmp/junk
myname@localhost's password:
这是我的操作系统
mypc:/home/myname$ uname -a
Linux mypc 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
mypc:/home/myname$ which sftp
/usr/bin/sftp
我需要捕获它的原因是因为我正在编写一个 Perl 脚本来测试 sftp 连接。如果我被允许将 Perl 的 Expect 模块安装在我的工作场所中,我本可以使用它。
谢谢
答案1
1. 为什么简单的指令无法捕获密码提示?
- 该提示可能来自子进程。
- 这可能是一个特殊的设计,以便提示符不会与用户可能捕捉到的 stdout 和 stderr 混合在一起。
参考:当 stdout 和 stderr 都重定向时,ssh 如何/为什么输出到 tty?
2.如何捕捉?
我们可以使用 Perl 的 Expect 模块。测试如下图所示
myname@mypc:/mnt/c/users/myname$ perl -MExpect -e 'print ${Expect->spawn("sftp localhost")->expect(3, [qr/.+/])}[2], "\n";'
umyname@localhost's password:
myname@mypc:/mnt/c/users/myname$ perl -MExpect -e 'print ${Expect->spawn("sftp localhost")->expect(3, [qr/.+/])}[2], "\n";' >/tmp/junk
这基本上将从 tty 到 stdout 的所有内容分组。