スクリプトに入力したリストから、リモートホストにインストールされているホスト名、IP、および合計メモリを収集するスクリプトを作成しようとしています。このスクリプトは Redhat および Solaris コンピュータから情報を収集します。私のスクリプトは次のとおりです。
#!/bin/bash
echo > ip_info.output
echo -e "\n"
for host in `cat ip_adds`
do
echo "Hostname:" $host
sudo ssh -o BatchMode=yes -o ConnectTimeout=5 $host "echo IP Address:; ip route get 1 | awk '{print $NF;exit}'; free -m | grep Mem | awk '{print $1,$2}'"
echo -e "\n"
done
スクリプトを実行すると、次のエラーが発生します。
awk: {print ,}
awk: ^ syntax error
awk: {print ,}
awk: ^ syntax error
awk: cmd. line:1: {print ,}
awk: cmd. line:1: ^ unexpected newline or end of string
問題があるようですが、free -m | grep Mem | awk '{print $1,$2}
解決策がわかりません。シェルに直接入ってもfree -m | grep Mem | awk '{print $1,$2}
問題ありません。スクリプトの中にあります。
答え1
これは必要以上に複雑です。それになぜssh
走っているのでしょうかsudo
?リモートでrootとしてログインする必要がある場合は、これを行うことができます()。ただし、SSHキーがすべてルートに属していない限り、ssh root@$host
sshを実行する必要はほとんどありません。sudo
これはとても悪い考えです。
また、私のArchシステムでは、IPを取得するために使用するコマンドが私のユーザーのUIDを返すようです。
$ ip route get 1
1.0.0.0 via 192.168.1.1 dev enp0s31f6 src 192.168.1.111 uid 1000
cache
$ ip route get 1 | awk '{print $NF;exit}';
1000
テストしたUbuntuは期待どおりに機能します。
$ ip route get 1
1.0.0.0 via 123.456.7.8 dev eth0 src 123.456.7.9
$ ip route get 1 | awk '{print $NF;exit}';
123.456.7.9
したがって、後でフィールドを印刷する方が移植可能なバージョンになる可能性がありますsrc
。
$ ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p'
192.168.1.111
あなたが見るエラーは実際に引用によるものです。を実行しているため、ssh $host "command"
二重引用符で囲むと、command
シェルはコマンド内で見つかったすべての変数(awk$2
など)を拡張します。これを防ぎ、拡張されていないシンボルをawkに渡すにはエスケープする必要があります$
。
より簡単なスクリプトバージョン:
#!/bin/bash
sshOpts="BatchMode=yes -o ConnectTimeout=5"
echo > ip_info.output
echo ""
while read host; do
printf "Hostname:%s" $host
ssh -o $sshOpts $host "printf 'Hostname: %s\nIP: %s\nMem: %s\n' $host "$(ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p')" "$(free -m | awk '/Mem/{print $2}')""
done < ip_adds
答え2
私はこの質問に対する答えを見つけました。これはエスケープに関連しているので、次のように$ 1と$ 2の前に\を追加しました。
free -m | grep Mem | awk '{print \$1,\$2}
答え3
これが最終的なスクリプトの外観です。私はそれがあなたの一部に役立つことを知っています。
#!/bin/bash
for host in `cat ip_adds2`
do
echo "Hostname:" $host
sudo ssh -t -o BatchMode=yes -o ConnectTimeout=5 $host 'echo IP: `hostname -i`;read junk total used free shared buffers cached junk < <(free -g | grep ^Mem);echo Memory: $total GiB'
echo -e "\n"
done