#!/bin/bash CFG_FILE=$HOME/.config/ssh-check.list TIMEOUT=5 # seconds read -d '' SSH_OPTIONS </dev/null 2>&1 } match() { local search_text="$1" search_pattern invert= shift for search_pattern in "$@" do if [[ "$search_pattern" = '!'* ]] then invert=y fi if (set +e [[ $search_text = ${search_pattern#!} ]] [ $? ${invert:+ !}= 0 ]) then return fi done false } main() { local h declare -a hosts=() declare -i max_found_host_length=0 while read h cmd do if [ ${#h} -gt $max_found_host_length ] then max_found_host_length=${#h} fi hosts+=("$h $cmd") done < "$CFG_FILE" while true do { default_hostcmd=uptime for h in "${hosts[@]}" do host=${h%% *} hostcmd=${h#* } [ "$host" ] || continue [ $# = 0 ] || match "$host" "$@" || continue ( #.........."1234567890123456" successpat=" Success: %-${max_found_host_length}s %s\n" failurepat="*FAILURE: %-${max_found_host_length}s %s\n" command_stderr=$(mktemp) if command_stdout=$(ssh -n $SSH_OPTIONS -- \ "$host" \ "${hostcmd:-$default_hostcmd}" \ 2>"$command_stderr") then if [ "$hostcmd" ] then logtail=${command_stdout: -40 } else logtail=${command_stdout: 1 : 40 } fi printf "$successpat" "$host" "${logtail@Q}" else REPLY= while read do REPLY=${REPLY%$'\r'} printf "$failurepat" "$host" "${REPLY@Q}" done <"$command_stderr" >&2 logtail=${REPLY: -40 } printf "$failurepat" "$host" "${logtail@Q}" fi rm "$command_stderr" ) & done wait } | column -t -s'$' tty -s && break sleep 5 done } edit_config() { set -e f=$(mktemp) if [ -e "$CFG_FILE" ] then cp "$CFG_FILE" "$f" fi touch -r "$f" "$f".timestamp $EDITOR "$f" [ -e "$f" -a "$f" -nt "$f".timestamp ] mv "$f" "$CFG_FILE" set +e rm "$f".timestamp } usage() { cat <&2; exit 1 ;; *) break;; esac shift done if [ "$do_edit" ] then edit_config r=$? if ! [ "${run_anyway}" ] then exit $r fi elif [ ! -e "$CFG_FILE" -a -t 0 ] then edit_config fi main "$@"