Linuxコンピュータのリストからpingアクセスを確認するために、次のbashスクリプトを作成しました。
for M in $list
do
ping -q -c 1 "$M" >/dev/null
if [[ $? -eq 0 ]]
then
echo "($C) $MACHINE CONNECTION OK"
else
echo "($C) $MACHINE CONNECTION FAIL"
fi
let C=$C+1
done
これは以下を印刷します:
(1) linux643 CONNECTION OK
(2) linux72 CONNECTION OK
(3) linux862 CONNECTION OK
(4) linux12 CONNECTION OK
(5) linux88 CONNECTION OK
(6) Unix_machinetru64 CONNECTION OK
printf
bashスクリプトで(または他のコマンド)を使用して次の形式を印刷するにはどうすればよいですか?
(1) linux643 ............ CONNECTION OK
(2) linux72 ............. CONNECTION OK
(3) linux862 ............ CONNECTION OK
(4) linux12 ............. CONNECTION OK
(5) linux88 ............. CONNECTION FAIL
(6) Unix_machinetru64 ... CONNECTION OK
答え1
パラメータ拡張を使用して、ドットによる%-s
スペースを置き換えます。
#!/bin/bash
list=(localhost google.com nowhere)
C=1
for M in "${list[@]}"
do
machine_indented=$(printf '%-20s' "$M")
machine_indented=${machine_indented// /.}
if ping -q -c 1 "$M" &>/dev/null ; then
printf "(%2d) %s CONNECTION OK\n" "$C" "$machine_indented"
else
printf "(%2d) %s CONNECTION FAIL\n" "$C" "$machine_indented"
fi
((C=C+1))
done
答え2
for m in $list
文法ですzsh
。まさにbash
そこにfor i in "${list[@]}"
。
bash
パディング演算子はありません。パディングにはスペースを使用できますが、printf
任意の文字ではなくスペースのみを使用できます。zsh
パディング演算子があります。
#! /bin/zsh -
list=(
linux643
linux72
linux862
linux12
linux88
Unix_machinetru64
)
c=0
for machine in $list; do
if ping -q -c 1 $machine >& /dev/null; then
state=OK
else
state=FAIL
fi
printf '%4s %s\n' "($((++c)))" "${(r:25::.:):-$machine } CONNECTION $state"
done
これ充填材オペレーター${(r:25:)parameter}
正しい- スペースがあるパッドの長さ25${(r:25::string:)parameter}
または正しい- スペースの代わりに任意の文字列で埋めます。
私達はまたprintf '%4s'
使用します左- 空白で埋めます(x)
。私たちはそれを代わりに使用することもできました${(l:4:):-"($((++c)))"}
。ただし、1つの重要な違いは、文字列が4文字を超えると切り捨てられ、${(l)}
オーバーフローが発生することですprintf
。
答え3
書式%s
指定子は精度(%.20s
例:)を取ることができます。浮動小数点値を特定の精度(例えば)に出力したい場合、%.4f
出力は与えられた文字列引数の最大文字数です。
したがって、マシン名とポイントの両方を使用するのに十分なポイントを含む文字列を作成します。
cnt=0
for hname in vboxhost ntp.stupi.se example.com nonexistant; do
if ping -q -c 1 "$hname" >/dev/null 2>&1; then
status="OK"
else
status="FAIL"
fi
printf "(%d) %.20s CONNECTION %s\n" \
"$(( ++cnt ))" "$hname ...................." "$status"
done
出力:
(1) vboxhost ........... CONNECTION OK
(2) ntp.stupi.se ....... CONNECTION OK
(3) example.com ........ CONNECTION OK
(4) nonexistant ........ CONNECTION FAIL
答え4
fping
私はandにしますawk
。残念ながら、awk
'printf
はドットで埋められず、空白またはゼロで埋めることができるので、次の関数を書く必要がありました。
list=(kali surya indra ganesh durga hanuman nonexistent)
fping "${list[@]}" 2>&1 |
sort -k3 |
awk -F'[: ]' 'BEGIN { fmt="(%02d) %s CONNECTION %s\n"};
function dotpad(s,maxlen, l,c,pads) {
l = maxlen - length(s);
pads = "";
for (c=0;c<l;c++) {pads=pads"."};
return s " " pads
};
/alive$/ { printf fmt, ++i, dotpad($1,19), "OK" };
/unreachable$/ { printf fmt, ++i, dotpad($1,19), "FAIL" }
/not known$/ { printf fmt, ++i, dotpad($1,19), "IMPOSSIBLE" } '
(01) durga .............. CONNECTION OK
(02) ganesh ............. CONNECTION OK
(03) indra .............. CONNECTION OK
(04) kali ............... CONNECTION OK
(05) nonexistent ........ CONNECTION IMPOSSIBLE
(06) hanuman ............ CONNECTION FAIL
(07) surya .............. CONNECTION FAIL
10〜99のホストがあっても型がめちゃくちゃにならないように、括弧内にゼロで埋められた2桁の数字を使用します$list
(100+はまだ台無しです)。別のアプローチは、END {}
ブロックが発生するまで印刷を遅らせ、/regexp-matches/は3つの配列のうちの1つにのみホスト名を挿入することです(例えばok
、、、fail
)unknown
。または、単に連想配列(たとえばhosts[hostname]="OK"
)です。その後、行数を計算し、それを使用して行カウンタフィールドの幅を決定できます。
また、出力で未知のホスト(CONNECTION IMPOSSIBLE
)と接続できないホスト(CONNECTION FAIL
)を区別することにしました。
オプションで、sort -k3
結果fping
(「ホスト名がアクティブです」、「ホスト名に接続できません」、または「ホスト名:名前またはサービスが不明」)に基づいて出力をグループ化するだけです。そうでない場合、sort
未知のホストは常に出力の最初に表示されます。ホスト名別にソートはsort
ありません-k3
。