Explorar o código

Now optionally has an output directory.

Thomas Flucke %!s(int64=6) %!d(string=hai) anos
pai
achega
a1e37083c0
Modificáronse 1 ficheiros con 47 adicións e 17 borrados
  1. 47 17
      src/distributer/distribute.sh

+ 47 - 17
src/distributer/distribute.sh

@@ -1,49 +1,79 @@
 #!/bin/sh
 
+readonly DEFAULT_OUT_FMT="%s.out"
+readonly CMD_FEED="$(mktemp -u distributer-XXX.fifo)"
 readonly CONF_LIST="$1"
 readonly SERVER_LIST="$2"
+readonly OUT_FMT="${3:-$DEFAULT_OUT_FMT}"
+
+readonly MK_DIR_CMD="if [ ! -d \"$(dirname "$OUT_FMT")\" ]; then
+                        mkdir -p \"$(dirname "$OUT_FMT")\" > /dev/null
+                     fi"
+
+readonly S_SPACE="s/[[:space:].\/]/_/g"
+readonly R_DASH="s/-//g"
+readonly S_QUOTE="s/'/\\\\'/g"
 
 help() {
-    printf "Usage: $(basename $0) cmd_list server_list\n" >&2
+    printf "Usage: $(basename $0) cmd_list server_list [out_file_fmt]\n" >&2
     printf "    cmd_list: A text file containing a list of commands to run.\n" >&2
     printf "    server_list: A text file containing a list of servers to\n" >&2
-    printf "    connect to and run commands on.\n\n" >&2
+    printf "    connect to and run commands on.\n" >&2
+    printf "    out_file_fmt: File name format to write the output of each\n" >&2
+    printf "    command to (default: $DEFAULT_OUT_FMT).\n\n" >&2
     printf "All commands will be allocated to the first available server.\n" >&2
     printf "Each command must be valid on every server.\n" >&2
     printf "The output will be saved to a text file on the remote systems.\n" >&2
     exit 1
 }
 
+clean_server() {
+    cmd_feed="$1"
+    rm "$cmd_feed"
+    exit 2
+}
+
 run_server() {
     server="$1"
-    loop="/tmp/$(basename $PIPE_NAME .fifo)-$server.fifo"
+    loop="/tmp/$(basename $CMD_FEED .fifo)-$server.fifo"
     mkfifo "$loop"
+    trap "clean_server $loop" 2 15
     while read cmd; do
-        out_file="$(echo "$cmd" | sed 's/[[:space:].\/]/_/g;s/-//g').out"
-        printf "$cmd > $out_file\necho\n"
+        cmd_sanitized="$(echo "$cmd" | sed "$S_SPACE;$R_DASH;$S_QUOTE")"
+        out_file="$(printf "$OUT_FMT" "$cmd_sanitized")"
         printf "$server: $cmd\n" >&2
+        printf "$cmd > $out_file\necho\n"
         read line < "$loop" > /dev/null # Block until command completes
     done | ssh -oBatchMode=yes -oStrictHostKeyChecking=no "$server" "sh" > "$loop"
-    rm "$loop"
+    clean_server "$loop"
     echo "Server '$server' finished!" >&2
 }
 
+clean_up() {
+    for pid in $(pgrep -P $$); do
+        pkill -P $pid
+    done
+    rm "$CMD_FEED"
+    exit 2
+}
+
 main() {
-    PIPE_NAME="$(mktemp /tmp/distributer-XXX.fifo)"
-    rm "$PIPE_NAME"
-    mkfifo "$PIPE_NAME"
-    sed '/^[[:space:]]*$/d' "$CONF_LIST" > "$PIPE_NAME" &
-    cat "$SERVER_LIST" | while read server; do
-        run_server "$server" < "$PIPE_NAME" > /dev/null &
-        echo $!
-    done | while read pid; do
-        wait $pid
+    mkfifo "$CMD_FEED"
+    trap clean_up 2 15
+    sed '/^[[:space:]]*$/d' "$CONF_LIST" > "$CMD_FEED" &
+    pids=""
+    for server in $(cat $SERVER_LIST); do
+        run_server "$server" < "$CMD_FEED" > /dev/null &
+        pids="$pids $!"
+    done
+    for pid in $pids; do
+        wait $pids
     done
-    rm "$PIPE_NAME"
+    clean_up
     echo "All jobs finished!"
 }
 
-if [ "$#" -eq 2 ]; then
+if [ "$#" -eq 2 -o "$#" -eq 3 ]; then
     main
 else
     help