私はヒアドキュメントでこのようにSSH経由でコマンドを実行しようとしています:
ssh example.com <<END
Sudo /etc/init.d/Apache2 reload
END
これは、Sudoのパスワードなど、入力が必要なものを実行しようとしている場合を除いて、通常は機能します。その場合、次のメッセージが表示されます。
Sudo: no tty present and no askpass program specified
SSHで-t
フラグを使用して、次のような疑似ttyを割り当てることができます。
ssh -t example.com "Sudo /etc/init.d/Apache2 reload"
動作しますが、ヒアドキュメントで同じことをしようとすると、動作せず、ttyが存在しないという同じエラーが発生します。
ssh -t example.com <<END
Sudo /etc/init.d/Apache2 reload
END
どうすればこれを機能させることができますか?
また、なぜ同じ行に渡すのではなく、ヒアドキュメントを操作する必要があるのか疑問に思っている場合は、入力コマンド(いくつかある場合があります)がスクリプトによって読み取られた構成ファイルから取得されているためです引用符や二重引用符などのコマンドをエスケープする問題を回避できると聞きました。
visudo
を使用してsudoersファイルを編集し、以下の行を挿入します。
Defaults:<user> !requiretty
ssh -t "something" versus ssh -t <<STOP something STOP
を使用しても機能しない理由については回答していません。 Sudoを使用していないが、自分のユーザーに直接passwdを使用しているとしましょう。それでも、ヒアドキュメントを使用してTTYを取得できません。
Stdinが端末でない場合でも、ssh -t -t
を試して疑似tty割り当てを強制します。
ヒアドキュメントをssh -t
をコマンド引数として。
より一般的なメモでは、ssh -T
または、リモートホストの標準入力がヘレドキュメントからリダイレクトされる場合は、コマンド引数としてリモートシェルを指定します(ssh
がptyを割り当てようとしないようにするため)。
# store heredoc in a variable
heredoc="$(cat <<EOF
who
Sudo ls -ld /
logname
EOF
)"
ssh -t localhost "$heredoc"
# avoid: Pseudo-terminal will not be allocated because stdin is not a terminal.
- ssh example.com <<END
+ ssh -T example.com <<END
+ ssh example.com /bin/sh <<END