Respondendo minha própria pergunta aqui.
Agora temos uma função como esta:
function remote::run() {
# usage: remote::run "host" "includes" "commands"
# where "includes" is a list of functions to export to
# the remote host
[[ -n "$2" ]] && includes="$(declare -f $2);"
ssh -T $1 "$includes $3"
}
Isso nos permite fazer coisas como (exemplo inventado):
function status::report() {
date
host $(hostname)
}
remote::run $REMOTE_HOSTNAME status::report 'echo status report:; status::report' > out
Está longe de ser perfeito, mas é menos feio do que o que tínhamos:)
Resposta anterior:
Foi difícil acompanhar o fluxo de controle nos scripts acima, acho que estou resolvendo algo assim:
#!/bin/bash
# Generate the foo report
# source the shared code/vars if we're running locally
[[ -f shared.sh ]] && source shared.sh
if [[ "$report_host" != "$(hostname)" ]]; then
# ssh-agent will provide passwordless logon
runner="ssh -T -o SendEnv=report_host $report_host"
else
# run report locally
runner="bash"
fi
report="$($runner << EOF
$(declare -f run_report)
run_report
EOF
)"
echo "$report" | mail -s "daily foo report" root
Não estou entusiasmado com o código remoto estar em um heredoc. Desde que permaneça como algumas declarações seguidas por uma simples chamada de função, acho que está tudo bem.