同じコマンドを複数のサーバで実行
Assurerにシェルモードが追加されたので、もういいかなという感じですが、自分の使っているスクリプトをさらしてみる。
sshで1つのコマンドを複数のサーバに順番に実行させていけます。
「password:」のプロンプトに対して、expectを使って自動で入力する機能もあるので、sudoなどにも対応
mssh -f list.txt -u user -p -- id
-f ファイル名: ホスト名が書いてあるファイル名。1行1ホスト
-u ユーザ名: ログインするユーザ名
-p: パスワードを使うフラグ
--: これ以降にコマンド
以下ソース
#!/usr/bin/perl package MSH; use strict; use warnings; use Expect; sub new { my $class = shift; bless {@_}, $class; } sub log { my $self = shift; $self->{_log} && print @_; } sub execute { my $self = shift; my @cmd = @_; my $user = $self->{user} || die; my $host = $self->{host} || die; my $pass = $self->{pass}; my $cmd = join " ", @cmd; $cmd or die; $self->{_log} = 1; $self->log(<<EOF); [$user\@$host] CMD: $cmd EOF my @t = qw(ssh); push @t, "-l", $user, $host, @cmd; my $ssh = Expect->spawn(@t) || die "Warning: ssh failed on $host\n"; $ssh->log_stdout(0); $ssh->log_file( sub { $self->log(shift) } ); $ssh->expect( 180, [ qr/assword:\s*$/ => sub { $self->log("\n"); $self->{_log} = 0; $ssh->send("$pass\n"); exp_continue; } ], [ qr/.+/ => sub { $self->{_log} = 1; exp_continue; } ], [ timeout => sub { die "timeout.\n" } ], ); $ssh->hard_close(); print "\n"; } 1; package main; use strict; use warnings; use IO::Prompt; use Getopt::Long; GetOptions( 'f=s' => \my $list, 'u|user=s' => \my $user, 'p' => \my $with_passwd, ); my @args = @ARGV; @ARGV=(); my $passwd; if ( $with_passwd ) { $passwd = prompt("$user password: ", -echo=>"*"); $passwd or die; } open(my $fh, $list); my @hosts = <$fh>; foreach my $host ( @hosts ) { chomp $host;chomp $host; my $msh = MSH->new( host => $host, user => $user, pass => $passwd ); $msh->execute(@args); }