On 6/2/24 21:35, DdB wrote:
Am 02.06.2024 um 02:41 schrieb DdB:
Will share my findings, once i made more progress...

Here is what i've got before utilizing it:


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$


"test" is both a program and a shell builtin. I suggest that you pick another, non-keyword, name for your script.


I suggest adding the Bash option "-u' (nounset).


Your file descriptor duplication, redirection, etc., seems overly complex. Would not it be easier to use the coproc handles directly?

2024-06-03 08:49:41 dpchrist@laalaa ~/sandbox/bash
$ nl coproc-demo
     1  #!/usr/bin/env bash
     2  # $Id: coproc-demo,v 1.3 2024/06/03 15:49:36 dpchrist Exp $
     3  set -e
     4  set -u
     5  coproc COPROC { bash ; }
     6  echo 'echo "hello, world!"' >&"${COPROC[1]}"
     7  read -r reply <&"${COPROC[0]}"
     8  echo $reply
     9  echo "exit" >&"${COPROC[1]}"
    10  wait $COPROC_PID

2024-06-03 08:49:44 dpchrist@laalaa ~/sandbox/bash
$ bash -x coproc-demo
+ set -e
+ set -u
+ echo 'echo "hello, world!"'
+ bash
+ read -r reply
+ echo hello, 'world!'
hello, world!
+ echo exit
+ wait 4229


David

Reply via email to