繰り返しbashの新機能です。 txt ファイルを読み取ってリストされた各サーバーからユーザーを削除するには、スクリプトが必要です。これはどのように見えますか?
for user in $(cat /tmp/server-list.txt); do userdel -f $USERID; done
実行されますが、サーバーでユーザーアカウントが見つかりません(「id」は存在しません)。私は何が間違っていましたか?
答え1
あなたが次のようであるとしましょう:
- サーバーのIPアドレスのリストを含むテキストファイルを繰り返してみてください。各アドレスは新しい行に表示されます。
- Ubuntuユーザーとして各サーバーにSSHでアクセスし(ユーザーを自由に変更可能)、各システムから特定のユーザーを1つ削除しようとしています(例: "john smith")
- 一行にすべて
USERID="john smith"; cat /tmp/server-list.txt | while read IP_ADDRESS; do ssh -q -n ubuntu@$IP_ADDRESS "userdel -f $USERID" ; done
複数のユーザーと複数のサーバーがある場合は、入れ子になったループまたは配列を使用する必要があります。
答え2
Bashという点を考慮すると、mapfile
ファイルの内容を含む配列を作成できます。
mapfile server </tmp/server-list.txt
その後、次のサーバーを繰り返すことができます。
for s in "${server[@]}"
do
#something
done
$s
これで、コードを書くときにプレースホルダー ""を配置した値を使用する必要があります("command"パラメータは次のようになる#something
ため、これは少し難しいかもしれません)。ssh
文字列に結合され、sh -c
サーバーに渡されます。):
ssh "root@$s" "userdel -f '${USERID//\'/\'\\\'\'}''"
($USERID
スクリプトの外側のどこかに設定されているとします。このトリッキーな代替は、'
リモートシェルを混乱させる文字を処理することです。)
一緒に入れてください:
read -p "Delete which user?" userid
mapfile server </tmp/server-list.txt
for s in "${server[@]}"
do
ssh "root@$s" "userdel -f '${userid//\'/\'\\\'\'}''"
done
答え3
for user in $(cat /tmp/server-list.txt); do userdel -f $USERID; done
これはuser
ループ変数の名前です。ループが繰り返されるたびに、/tmp/server-list.txt
ファイルの次の行に設定します。
この変数はループのどこにも使用されません。したがって、ループはファイル内の行数と同じ文を繰り返し実行します。
$USERID
USERID
このコードに設定されていない変数を読みます。したがって、その変数に何も割り当てないと仮定すると、実行される実際のコードは次のようになります。
userdel -f
"server-list.txt"ファイルの行を "user"変数として読み取ることは実際にはエラーではありませんが、それでも非常に混乱しています。これはスタイルエラーであり、ループが複数のコマンドで大きくなると面倒な原因になります。