distribute.sh 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #!/bin/sh
  2. readonly CONF_LIST="$1"
  3. readonly SERVER_LIST="$2"
  4. help() {
  5. printf "Usage: $(basename $0) cmd_list server_list\n" >&2
  6. printf " cmd_list: A text file containing a list of commands to run.\n" >&2
  7. printf " server_list: A text file containing a list of servers to\n" >&2
  8. printf " connect to and run commands on.\n\n" >&2
  9. printf "All commands will be allocated to the first available server.\n" >&2
  10. printf "Each command must be valid on every server.\n" >&2
  11. printf "The output will be saved to a text file on the remote systems.\n" >&2
  12. exit 1
  13. }
  14. run_server() {
  15. server="$1"
  16. loop="/tmp/$(basename $PIPE_NAME .fifo)-$server.fifo"
  17. mkfifo "$loop"
  18. while read cmd; do
  19. out_file="$(echo "$cmd" | sed 's/[[:space:].\/]/_/g;s/-//g').out"
  20. printf "$cmd > $out_file\necho\n"
  21. printf "$server: $cmd\n" >&2
  22. read line < "$loop" > /dev/null # Block until command completes
  23. done | ssh -oBatchMode=yes -oStrictHostKeyChecking=no "$server" "sh" > "$loop"
  24. rm "$loop"
  25. echo "Server '$server' finished!" >&2
  26. }
  27. main() {
  28. PIPE_NAME="$(mktemp /tmp/distributer-XXX.fifo)"
  29. rm "$PIPE_NAME"
  30. mkfifo "$PIPE_NAME"
  31. sed '/^[[:space:]]*$/d' "$CONF_LIST" > "$PIPE_NAME" &
  32. cat "$SERVER_LIST" | while read server; do
  33. run_server "$server" < "$PIPE_NAME" > /dev/null &
  34. echo $!
  35. done | while read pid; do
  36. wait $pid
  37. done
  38. rm "$PIPE_NAME"
  39. echo "All jobs finished!"
  40. }
  41. if [ "$#" -eq 2 ]; then
  42. main
  43. else
  44. help
  45. fi