datakanja@PBuster-NFox:/mnt/tmp$ cat test
#!/bin/bash -e
# testing usefulness of coprocess to control host and backup machine from a single script.
# beware: do not use subprocesses or pipes, as that will confuse the pipes setup by coproc!
# At this point, this interface may not be very flexible
# but trying to follow best practices for using coproc in bash scripts
# todo (deferred): how to handle stderr inside coproc?
# todo (deferred): what, if coproc dies unexpectedly?
# setting up the coprocess:
stdout_to_ssh_stdin=5 # arbitrary choice outside the range of used file desciptors
stdin_from_ssh_stdout=6
coproc SSH { bash; } # for testing purposes, i refrain from really involving ssh just yet and replace it with bash:
# save filedescriptors by duplicating them:
eval "exec ${stdin_from_ssh_stdout}<&${SSH[0]} ${stdout_to_ssh_stdin}>&${SSH[1]}"
echo The PID of the coproc is: $SSH_PID # possibly useful for inspection
unique_eof_delimirer="<EOF>"
line=""
# collect the output available and print it locally (synchonous):
function print-immediate-output () {
while IFS= read -r -u "${stdin_from_ssh_stdout}" line
do
if [[ "${line:0-5:5}" == "$unique_eof_delimirer" ]] # currently, the length is fixed
then
line="${line%<EOF>}"
if [[ ! -z $line ]]
then
printf '%s\n' "$line"
fi
break
fi
printf '%s\n' "$line"
done
}
# send a single command via ssh and print output locally
function send-single-ssh-command () {
printf '%s\n' "$@" >&"${stdout_to_ssh_stdin}"
printf '%s\n' "echo '"$unique_eof_delimirer"'" >&"${stdout_to_ssh_stdin}"
print-immediate-output
}
send-single-ssh-command "find . -maxdepth 1 -name [a-z]\*" # more or less a standard command, that succeeds
send-single-ssh-command "ls nothin" # more or less a standard command, that fails
# tearing down the coprocess:
printf "%s\n" "exit" >&"${stdout_to_ssh_stdin}" # not interested in any more output (probably none)
wait
# Descriptors must be closed to prevent leaking.
eval "exec ${stdin_from_ssh_stdout}<&- ${stdout_to_ssh_stdin}>-"
echo "waited for the coproc to end gracefully, done"
datakanja@PBuster-NFox:/mnt/tmp$ ./test
The PID of the coproc is: 28154
./test
./out
ls: Zugriff auf 'nothin' nicht möglich: Datei oder Verzeichnis nicht gefunden
waited for the coproc to end gracefully, done
datakanja@PBuster-NFox:/mnt/tmp$