
私は常に仕事の効率化を模索しているので、複数のLinuxマシンにログインして、それぞれで同じコマンドを実行するのは避けたいものです。同じコマンドを複数のマシンで同時に実行できる方がずっと良いのです。
参照: 知っておくべきオープンソースと Linux の用語 40 選 (TechRepublic Premium)
もちろん、そのためのアプリはあります。でも、Linuxですから、自分なりのソリューションを組み立てた方が合理的ではないでしょうか?もちろん、その通りです。結局のところ、Linuxは選択肢、パワー、そして柔軟性の宝庫ですから。
例えば、複数のUbuntuサーバーがあり、それらすべてに対してsudo apt-get updateとsudo apt-get upgradeを一度に実行したいとします。これらのコマンドを実行するために、それぞれのマシンにログインする必要はありません。そのタスクを自動的に処理するスクリプトがあるからです。
そういったスクリプトを見つけたので、これを修正して、特定のホスト(UbuntuやRHELベースのサーバーなど)向けに複数のスクリプトを作成できるようにしました。このスクリプトを見て、どのように動作するかを確認してみましょう。
必要なもの
このスクリプトを使用するには、コマンドを実行するLinuxマシンと、コマンドを送信するLinuxサーバーが必要です。リモートサーバーで実行するコマンドによっては、sudo権限を持つユーザーが必要になります。
それだ。魔法をかけてみよう。
SSHの設定方法
まず最初に、リモートホストを定義するSSH設定ファイルを作成します。ただし、この設定にはちょっとしたコツがあります。それぞれのオペレーティングシステムに応じて、ubuntu-またはrhel-で始まるホスト名を定義します。
スクリプトを実行するシステムで、次のコマンドを使用して SSH 構成ファイルを作成します。
nano ~/.ssh/config
次のような状況があるとします。
IPアドレス192.168.1.11と192.168.1.13のUbuntuベースシステムと、IPアドレス192.168.1.14のRHELベースマシン。設定ファイルは以下のようになります。
Host rhel-db1
Hostname 192.168.1.14
Host ubuntu-invoice
Hostname 192.168.1.11
Host ubuntu-portainer
Hostname 192.168.1.13
ファイルを保存して閉じます。
スクリプトの作成方法
ここで、Ubuntuサーバー用とRHELサーバー用の2つのスクリプトを作成します。以下のコマンドでUbuntuサーバー用のスクリプトを作成します。
nano ~/ubuntu-cmd
そのファイルに次の内容を貼り付けます。
!/bin/bash
# Get the user's input as command
[[ -z ${@} ]] && exit || CMD_EXEC="${@}"
# Get the hosts from ~/.ssh/config whose names are prefixed by `lan-`
HOSTS=$(grep -Po 'Host\s\Kubuntu-.*' “$HOME/.ssh/config”)
# Test weather the input command uses sudo
if [[ $CMD_EXEC =~ ^sudo ]]
then
# Ask for password
read -sp '[sudo] password for remote_admin: '
password; echo
# Rewrite the command
CMD_EXEC=$(sed "s/^sudo/echo '$password' | sudo -S/"
"$CMD_EXEC")
fi
# loop over the hosts and execute the SSH command, remove `-a` to override the>
while IFS= read -r host
do
echo -e '\n\033[1;33m'"HOST: ${host}"'\033[0m'
ssh -n "$host" "$CMD_EXEC 2>&1" | tee -a "/tmp/$(basename "${0}").${host}.>
done <<< "$HOSTS"
ファイルを保存して閉じます。次に、次のコマンドでRHELスクリプトを作成します。
nano ~/rhel-cmd
そのファイルに次の内容を貼り付けます。
#!/bin/bash
# Get the user's input as command
[[ -z ${@} ]] && exit || CMD_EXEC="${@}"
# Get the hosts from ~/.ssh/config whose names are prefixed by `lan-`
HOSTS=$(grep -Po 'Host\s\Krhel-.*' "$HOME/.ssh/config")
# Test weather the input command uses sudo
if [[ $CMD_EXEC =~ ^sudo ]]
then
# Ask for password
read -sp '[sudo] password for remote_admin: ' password; echo
# Rewrite the command
CMD_EXEC=$(sed "s/^sudo/echo '$password' | sudo -S/" <<<
"$CMD_EXEC")
fi
# loop over the hosts and execute the SSH command, remove `-a` to override the>
while IFS= read -r host
do
echo -e '\n\033[1;33m'"HOST: ${host}"'\033[0m'
ssh -n "$host" "$CMD_EXEC 2>&1" | tee -a "/tmp/$(basename
"${0}").${host}.>
done <<< "$HOSTS"
ファイルを保存して閉じます。以下のコマンドを使って、これらのファイルをパス内のディレクトリに移動します。
sudo cp ubuntu-cmd rhel-cmd /usr/local/bin
これらのスクリプトの所有権を次のように変更します。
sudo chown $USER /usr/local/bin/ubuntu-cmd
sudo chown $USER /usr/local/bin/rhel-cmd
これで、SSH設定ファイルにUbuntuとRHELのホストが定義され、スクリプトはグローバルに実行できるようになりました。まずはUbuntuスクリプトを実行し、sudo apt-get updateコマンドをUbuntuサーバーに送信してみましょう。コマンドは以下のようになります。
ubuntu-cmd sudo apt-get update
このスクリプトは、SSH設定ファイルでubuntuで始まるホストを確認し、各ホストのsudoパスワードとリモートユーザーパスワードの両方の入力を求めます。SSH設定ファイルに記載されているUbuntuサーバーであれば、apt-get updateコマンドが正常に実行されるはずです。
次に、次のコマンドを使用して、RHEL ホストで sudo dnf update を実行します。
rhel-cmd sudo dnf update
同じことが起こりますが、SSH 構成ファイルで定義されている RHEL ベースのホストでは dnf update コマンドのみが実行されます。
SSH設定ファイルで定義された複数のホストでコマンドを実行するスクリプトの作成方法はこれだけです。この設定を使って、Linuxの強みである、他にどんな賢い使い方ができるか試してみてください。
Jack Wallen によるビジネス プロフェッショナル向けの最新のテクノロジー アドバイスをすべて知るには、YouTube で TechRepublic の How To Make Tech Work を購読してください。