terry wang's answer helped me to get to mine, but i wanted to post this separately for anyone else looking to run more complex scripts:
EXIT_CODE_FILE="/tmp/exit_code_file"
TIMING_FILE="/tmp/timing_file"
LOG_FILE="/tmp/log_file"
ssh "${SSH_USER}@${HOST_ADDRESS}" "nohup bash -c '
# Source .bashrc because that doesn't happen automatically for ssh commands
source ~/.bashrc
echo "START: $(date +%s)" > ${TIMING_FILE}
# Run your command / script and capture its stdout/stderr streams
my_command.sh --with args > ${LOG_FILE} 2>&1
# Save the exit code
echo \$? > ${EXIT_CODE_FILE}
echo "END: $(date +%s)" >> ${TIMING_FILE}
' > /dev/null 2>&1 &"
The nohup ensures that the entire wrapped command provided to bash runs to completion even when we disconnect, while its standard output streams are redirected to /dev/null and the & runs everything as a background process. In this way, only the command we're interested in prints its output to the given log file.
At this point it's easy enough to implement resumable polling behavior by polling the EXIT_CODE_FILE until we have a result.
echo "Waiting for remote operation to complete..."
while true; do
# Check if the exit code file exists and has a value
EXIT_CODE=$(ssh "${SSH_USER}@${HOST_ADDRESS}" "cat ${EXIT_CODE_FILE} 2>/dev/null || echo 'pending'")
if [ "$EXIT_CODE" != "pending" ]; then
break
fi
echo -n "."
sleep 5
done
Operation completed
if [ "$EXIT_CODE" -eq 0 ]; then
echo "Remote operation completed successfully"
else
echo "Remote operation failed with exit code: $EXIT_CODE"
fi
echo ""
echo "Timing file:"
ssh "${SSH_USER}@${HOST_ADDRESS}" "cat ${TIMING_FILE}"
echo "Remote log output:"
ssh "${SSH_USER}@${HOST_ADDRESS}" "cat ${LOG_FILE}"
if [ "$EXIT_CODE" -ne 0 ]; then
exit $EXIT_CODE
fi