···9898 }
9999100100 # follow <unit>: stream its log until it finishes, fail if it did.
101101+ # tail can lag far behind the log when the reader (nom) is slow, so
102102+ # it must not be killed on a timer: --pid makes it read the log to
103103+ # the end once the waiter (unit finished) is gone, then exit, so
104104+ # no line is cut off.
101105 follow() {
102106 ssh "''${ssh_opts[@]}" "$target" bash -s -- "$1" "$state" <<'EOF'
103107 unit=$1 log=$2/$1.log
104104- tail -n +1 -F "$log" 2>/dev/null &
105105- tailpid=$!
106108 while case $(systemctl show -p ActiveState -p SubState "$unit") in
107109 *ActiveState=activating* | *SubState=running*) true ;;
108110 *) false ;;
109111 esac; do
110112 sleep 1
111111- done
112112- sleep 1
113113- kill "$tailpid"
113113+ done &
114114+ tail -n +1 -F --pid=$! "$log" 2>/dev/null
114115 [ "$(systemctl show -p Result --value "$unit")" = success ] && exit 0
115116 echo "deploy: $unit failed (exit status $(systemctl show -p ExecMainStatus --value "$unit")), log: $log" >&2
116117 exit 1