Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- # vi: set filetype=sh
- ############################################################ CONFIGURATION
- #
- # File to send
- #
- FILE="5GB"
- #
- # Size of test file to create
- # NB: Comment-out to disable (e.g., if $FILE is a real file you want to send)
- #
- TESTSIZE_IN_MB=$(( 5 * 1024 ))
- #
- # scp(1) destination
- # NB: Can contain destination name for $FILE
- # NB: Keyword `CURRENT_HOST' replaced with destination hostname
- #
- DEST="localhost:$FILE.CURRENT_HOST"
- #
- # List of hosts to send the file to
- #
- HOSTS="sa saro cc bob"
- #
- # Maximum number of copies to perform in parallel
- #
- MAX_PARALLEL=2
- ############################################################ GLOBALS
- #
- # Process ID for backgrounded xargs(1) process
- #
- XARGS_PID=
- ############################################################ FUNCTIONS
- cleanup()
- {
- local retval=$? host log pid
- echo
- kill "$XARGS_PID" > /dev/null 2>&1
- for host in $HOSTS; do
- log="file_$host"
- pid=$( head -1 "$log" 2> /dev/null )
- kill "$pid" > /dev/null 2>&1
- rm -f "$log"
- done
- exit $retval
- }
- ############################################################ MAIN
- trap cleanup INT
- #
- # Generate the test payload if necessary/possible
- #
- if [ "$TESTSIZE_IN_MB" -a ! -e "$FILE" ]; then
- echo "Creating $FILE... (this may take a while)"
- dd if=/dev/urandom of="$FILE" bs=1m count="$TESTSIZE_IN_MB" || exit
- elif [ ! -e "$FILE" ]; then
- echo "$FILE: No such file or directory" >&2
- exit 1
- elif [ -d "$FILE" ]; then
- echo "$FILE: Is a directory" >&2
- exit 1
- fi
- #
- # Cleanup any logfiles left from previous runs
- #
- for host in $HOSTS; do
- rm -f "file_$host"
- done
- #
- # Send the payload to multiple hosts in parallel whilst logging progress
- #
- echo $HOSTS | xargs -rn1 -ICURRENT_HOST -P$MAX_PARALLEL \
- script -aqt0 file_CURRENT_HOST sh -c '
- file="$1"
- dest="$2"
- log="$3"
- cleanup()
- {
- echo RET:$? >> "$log"
- }
- echo $$ > "$log"
- trap cleanup EXIT
- scp "$file" "$dest"
- ' /bin/sh "$FILE" "$DEST" file_CURRENT_HOST > /dev/null 2>&1 &
- XARGS_PID=$!
- #
- # To display progress from multiple copies
- #
- while :; do
- status=
- all_done=1
- for host in $HOSTS; do
- log="file_$host"
- state=pend
- running=
- if [ -e "$log" ]; then
- pct=
- state=fail
- pid=$( head -1 "$log" 2> /dev/null )
- kill -0 "$pid" > /dev/null 2>&1 && running=1
- else
- all_done=
- fi
- if [ "$running" ]; then
- _pct=$( awk 'END {
- sub(/\r+$/, "")
- sub(/.*\r/, "")
- if (match($0, /[[:digit:]]+%/))
- print substr($0, RSTART, RLENGTH-1)
- }' "$log" 2> /dev/null )
- pct=${_pct:-$pct}
- state="${pct:-0}%"
- all_done=
- elif _ret=$( awk 'END {
- if (sub(/^RET:/, "")) {
- print
- exit 0
- }
- exit 1
- }' "$log" 2> /dev/null ); then
- pct=
- state=done
- [ $_ret -ne 0 ] && state=fail
- fi
- status="$status $( printf "%s [%4s]" $host $state )"
- done
- printf "\r%s\t\t%s" "$( date )" "$status"
- [ "$all_done" ] && break
- sleep 1
- done
- echo
- ################################################################################
- # END
- ################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement