【问题标题】:Run a remote bash command through ssh通过 ssh 运行远程 bash 命令
【发布时间】:2017-09-08 18:04:31
【问题描述】:

我计划使用以下脚本在远程服务器上执行 bash 命令。每次运行此脚本时,它都应检查远程 MySQL (PXC) 服务器是否正在进行 SST。

#!/usr/bin/perl

use strict;
use warnings;

my $time = localtime();

my $file = '/db-common-list/names.txt';
open my $info, $file or die "Could not open $file: $!";

while ( my $hostname = <$info> )  {

    my $wsrep_check = `ssh $hostname ps -ef |grep mysql | grep wsrep_sst_xtrabackup-v2`;

    if ( index($wsrep_check, 'State transfer in progress, setting sleep higher mysqld') != -1 ) {
        print "$time: Server $hostname";
        last if $. == 2;
    }
}

close $info;

/db-common-list/names.txt 内部是一个数据库列表,脚本应该逐行循环遍历这些数据库。所以它看起来像这样:

db-test-1
db-test-2
db-test-3
db-test-4
...

但是当我运行脚本时,命令行只是挂起并且从不显示任何内容,此时我必须手动强制脚本停止执行。所以几分钟后,除了脚本只是挂在终端上,我使用 Ctrl-D 停止脚本,我得到了这个:

thegeorgia@cron-db$ ./test.cron
Connection to db-test-1 closed.
Connection to db-test-2 closed.
thegeorgia@cron-db$ ./test.cron

我可以 ssh 和 ping 这些远程服务器,如下所示,所以这肯定不是问题:

thegeorgis@cron-db$ ping db-test-1
PING db-test-1 (10.1.4.205) 56(84) bytes of data.
64 bytes from db-test-1 (10.1.4.205): icmp_seq=1 ttl=64 time=0.263 ms
64 bytes from db-test-1 (10.1.4.205): icmp_seq=2 ttl=64 time=0.222 ms 

所有涉及的服务器都在运行 Ubuntu。

注意: 根据 Borodin 的建议,我添加了 chomp 如下:

    while( my $hostname = <$info>)  {
    my $server = chomp( $hostname );
    my $wsrep_check = `ssh $server ls`;
         if ( index($wsrep_check, 'State transfer in progress, setting sleep higher mysqld') != -1 ){
            print "$time: Server $server";
       }
last if $. == 2;
}

当我运行 perl 脚本时,我现在收到以下错误:

ssh: connect to host 1 port 22: Invalid argument
ssh: connect to host 1 port 22: Invalid argument

解决方案:

#!/usr/bin/perl -w

use strict;
use warnings;

my $time = localtime();
my $file = '/db-common-list/names.txt';
open my $info, $file or die "Could not open $file: $!";

while( my $hostname = <$info>)  {
    chomp( $hostname );
    my $wsrep_check = `ssh $hostname ps -ef |grep mysql | grep wsrep_sst_xtrabackup-v2`;
         if ( $wsrep_check ne "" ){
            print "$time: Server $hostname\n";
       }
}
close $info;

【问题讨论】:

  • 您是否仅在远程运行脚本时遇到此问题?当您在该服务器上本地运行 ps -ef 时会发生什么?
  • 1) 可以挂在这里的一件事是ssh。您可以从 Perl 脚本 ssh 到该服务器并取回任何东西吗?在运行ssh 之后,您是否尝试在while 循环之外打印任何内容?例如,$wsrep_check 变量? (2) 这是你的完整剧本吗? while 完成后还有更多挂起的吗?
  • 脚本在本地运行。问题似乎与 ssh 部分有关。
  • 您能否尝试在if 语句之前添加print "$wsrep_check\n"; 并告诉我们会发生什么?
  • 好的,谢谢——看来@Borodin 想通了。你肯定需要 chomp 那个(在我的快速测试中,ssh 确实在主机名后面挂了一个换行符)。

标签: bash perl ubuntu ssh


【解决方案1】:

你需要

chomp $hostname;

在您的 ssh 命令之前从读取中删除尾随换行符

我还怀疑您的 last if $. == 2 应该在 if 块之外

Perl 内置了对正则表达式的支持,因此很少需要调用 index

if ( index($wsrep_check, 'State transfer in progress, setting sleep higher mysqld') != -1 ) { ... }

通常会写成

if ( $wsrep_check =~ /State transfer in progress, setting sleep higher mysqld/ ) { ... }

但是你写的很好

【讨论】:

  • 根据您的建议,它不会挂起,但会引发错误:/home/thegeorgia/.bashrc: line 2: /usr/local/bin/virtualenvwrapper.sh: No such file or directory
  • @TheGeorgia:这是您的.bashrc 的问题。您需要找到virtualenvwrapper.sh 在相关主机上的位置并更正路径。
  • 请查看我的原始帖子以查看更改和当前输出
  • 你的意思是在本地服务器上添加,还是在远程服务器上添加?
  • chomp 成功了。感谢@Borodin 和所有提供反馈的人
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 2014-04-07
  • 2012-10-23
相关资源
最近更新 更多