capture.sh 1012 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #!/bin/bash
  2. # Copyright (c) Daniel Sheffield 2024 - 2025
  3. set -euo pipefail
  4. if [ "$#" == "0" ]
  5. then
  6. echo capture
  7. exit 0
  8. fi
  9. . "${BASH_SOURCE[0]%/*}"/helpers/common.sh
  10. PROG="$1"
  11. SUBPROG="$(get_subprog "$@")"
  12. TIMESTAMP=$(date +%Y%m%d_%H%M%S_%N)
  13. LOG_DIR="$LOG_ROOT"/"$PROG"/"$SUBPROG"/"$TIMESTAMP"
  14. mkdir -p "$LOG_DIR"
  15. PTYA="$LOG_DIR"/ptyA
  16. PTYB="$LOG_DIR"/ptyB
  17. OUT="$LOG_DIR"/stdout
  18. ERR="$LOG_DIR"/stderr
  19. DAT="$LOG_DIR"/dat
  20. INF="$LOG_DIR"/info
  21. CMD="$(shell_escape "$@")"
  22. info(){
  23. cat <<EOF > "$INF"
  24. $CMD
  25. status=$?
  26. EOF
  27. exec 1>&- 2>&-
  28. [ "${socat:-}" ] && kill "$socat"
  29. wait
  30. }
  31. trap 'info' EXIT
  32. exec 2> >(tee -a "$DAT" "$ERR")
  33. if [ -t 1 ] && ! [ "$PROG" = "sudo" ] && which socat 1>/dev/null 2>&1
  34. then
  35. socat PTY,rawer,link="$PTYA" PTY,rawer,link="$PTYB" &
  36. socat="$!"
  37. for pty in "$PTYA" "$PTYB"
  38. do
  39. while ! [ -e "$pty" ]; do sleep 0.01; done
  40. stty -F "$pty" rows "$LINES" cols "$COLUMNS"
  41. done
  42. tee -a "$DAT" "$OUT" 2>/dev/null < "$PTYB" &
  43. exec 1> "$PTYA"
  44. else
  45. exec 1> >(tee -a "$DAT" "$OUT")
  46. fi
  47. "$@"