子プロセスの出力をキャプチャする方法は?

子プロセスの出力をキャプチャする方法は?

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

私がこれをキャプチャする必要があるのは、SFTP接続をテストするためにPerlスクリプトを書いているからです。私のワークショップにPerlのExpectモジュールをインストールすることを許可した場合は、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まですべてをグループ化します。

関連情報