`
standalone
  • 浏览: 611104 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Turn to Python from Perl: example of SSH in multi-threads

阅读更多

I need to execute commands on several remote servers at the same time via ssh. Writing shell script to send commands to servers with code below is quite simple but has trouble to know when all the tasks are finished on all servers.

            ssh $ip “nohup sh go.sh > log 2>&1 &”

Then I turn to perl, write following perl code:

#!/usr/bin/perl


use threads;
use Net::SSH::Perl;
use strict;

my @thread_array;
system( "touch $result_file" );
open( ResultHandle, "> $result_file" ) || die "Open result file error...\n";

sub Test
{
        my $host = shift;
        chomp( $host );
        $current_host = $host;
        print "\nDebug:Try to connect $host for sequence write test...\n"; 


        eval
        {
                alarm $time_out;
                my $ssh = Net::SSH::Perl->new( $host );
                $ssh->login($user, $pass);
                my($out,$err,$exit ) = $ssh->cmd($myCmd);


                alarm 0;
               print ResultHandle " Test\n $host \n $out\n \n $err";
                print "$host\n$out\n$err\n$exit\n";
        };
}


my @clients = ("10.0.0.4","10.0.0.6"); 


for(my $i = 0; $i <= $#clients; $i++){
        print "thread $i\n";
        $thread_array[$i] = threads->new(\&Test, $clients[$i]);
}


foreach my $thread( @thread_array )
{
        $thread -> join( );
}

 

However, when I run this script, it says “Segment fault” when running more than threads, I do not know why and it stops me moving ahead. Quite disappointed!!!
Then I turn to python…first try the library pyssh:
With following code:

import os
import re
import time
import sys
import pyssh
from threading import Thread 


class SSHController(Thread): 


    """Connect to remote host with SSH and issue commands.
    This is a facade/wrapper that uses PySSH to spawn and control an SSH client.
    You must have OpenSSH installed. 


    @ivar host_name: Host name or IP address
    @ivar user_name: User name
    @ivar password: Password
    @ivar prompt: Command prompt (or partial string matching the end of the prompt)
    @ivar ssh: Instance of a pyssh.Ssh object
    """
    def __init__(self, host_name, user_name, password, cmd):
        """
        @param host_name: Host name or IP address
        @param user_name: User name
        @param password: Password
        @param prompt: Command prompt (or partial string matching the end of the prompt)
        """
        Thread.__init__(self)
        self.host_name = host_name
        self.user_name = user_name
        self.password = password
        self.port = '22'  #default SSH port
        self.ssh = None
        self.cmd = cmd 


    def login(self):

        """Connect to a remote host and login.
        """
        self.ssh = pyssh.Ssh(self.user_name, self.host_name, self.port)
        self.ssh.login(self.password)


    def run_command(self, command):
        """Run a command on the remote host.
        @param command: Unix command
        @return: Command output
        @rtype: String
        """
        response = self.ssh.sendcmd(command)
        return self.__strip_output(command, response) 


    def logout(self):
        """Close the connection to the remote host.
        """
        self.ssh.logout()


    def run_atomic_command(self, command):
        """Connect to a remote host, login, run a command, and close the connection.
        @param command: Unix command
        @return: Command output
        @rtype: String
        """
        self.login()
        command_output = self.run_command(command)
        self.logout()
        return command_output


    def __strip_output(self, command, response):
        """Strip everything from the response except the actual command output.
        @param command: Unix command
        @param response: Command output
        @return: Stripped output
        @rtype: String
        """
        lines = response.splitlines()
        # if our command was echoed back, remove it from the output
        if command in lines[0]:
            lines.pop(0)
        # remove the last element, which is the prompt being displayed again
        lines.pop()
        # append a newline to each line of output
        lines = [item + '\n' for item in lines]
        # join the list back into a string and return it
        return ''.join(lines)


    def run(self):        
        self.run_atomic_command(self.cmd)


print time.ctime()
pinglist = []
for host in range(1,2):
   ip = "10.0.0."+str(host)
   print ip
   current = SSHController(ip,"tao","123456","ls")
   pinglist.append(current)
   current.start()


for pingle in pinglist:
   pingle.join() 


print time.ctime()

 

But again, this script failed.  It says:  ValueError: signal only works in main threadI do not know if it’s pyssh library’s problem.
Then I turn to a library named paramiko, and finally I succeed!
First you should install this library; possibly you may need another library pycrypto-2.0.1.
With all things ready, and the following script:

#!/usr/bin/env python
import os, sys, socket
import paramiko
from threading import Thread 


class myThread(Thread): 


    def __init__ (self, ip, usr, pwd, command):
        Thread.__init__(self)
        self.ip = ip
        self.usr= usr
        self.pwd= pwd
        self.command = command


    def run (self):
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(self.ip, username=self.usr, password=self.pwd)
        stdin, stdout, stderr = client.exec_command(self.command)
        if self.command.startswith("sudo")
                  stdin.write(“123456\n”)
                  stdin.flush()
        for line in stdout.read().splitlines():
                print 'host: %s: %s' % (self.ip, line)
        for line in stderr.read().splitlines():
                print 'host: %s: %s' % (self.ip, line)


    def test (self):
        pass # some code to test this class

 mythreads = []
hosts = []
cmd = ""
if __name__ == "__main__":
    num = int(sys.argv[1])
    print "total %d nodes\n" % num
    for i in range(2,2+num):
        hosts.append("10.0.0." + str(sys.argv[i]))
    for i in range(2+num,len(sys.argv)):
        cmd += " " + sys.argv[i]
    print "cmd to execute: %s\n" % cmd


    for ip in hosts:
        t = myThread(ip, "tao","123456",cmd)
        mythreads.append(t);
        t.start()


    for thread in mythreads:
        thread.join()
        print "execution on %s completes!\n" % thread.ip
print "test done!"

 

 

This script accepts arguments like this: 2 1 4 du –h
    First argument 2 means I want to execute this command on two hosts, and followed with the last part of ip. ( ip of my machines all have the pattern of 10.0.0.*).
    Then the command follows the hosts. If you need to execute a sudo command, remember to modify /etc/sudoers to allow you send ssh commands without a real tty.
    You can add a line like this to walk around this problem.

Defaults:tao !requiretty

分享到:
评论

相关推荐

    centos7 perl rpm依赖包

    perl-threads-shared-1.43-6.el7.x86_64 perl-threads-1.87-4.el7.x86_64 perl-Filter-1.49-3.el7.x86_64 1:perl-Pod-Simple-3.28-4.el7.noarch perl-Getopt-Long-2.40-2.el7.noarch 4:perl-5.16.3-286.el7.x86...

    perl-threads-shared-1.43-6.el7.x86_64.rpm

    离线安装包,亲测可用

    perl-threads-shared-1.58-2.el8.ppc64le.rpm

    离线安装包,亲测可用

    jboss-threads-3.1.0.Final-API文档-中文版.zip

    赠送jar包:jboss-threads-3.1.0.Final.jar; 赠送原API文档:jboss-threads-3.1.0.Final-javadoc.jar; 赠送源代码:jboss-threads-3.1.0.Final-sources.jar; 赠送Maven依赖信息文件:jboss-threads-3.1.0.Final....

    Python库 | signalr-client-threads-0.0.12.tar.gz

    Python库`signalr-client-threads-0.0.12.tar.gz`是一个专门为Python开发者设计的 SignalR 客户端库,它允许你在Python应用程序中与使用SignalR服务的Web应用进行实时通信。SignalR是ASP.NET框架下的一项技术,用于...

    linux实用脚本show-busy-java-threads

    本文将深入探讨标题所提及的三个实用脚本:“show-busy-java-threads”、“show-duplicate-java-classes”以及“find-in-jars”。这些脚本都是针对Java开发者和系统管理员的利器,旨在提高效率和解决问题。 1. **...

    show-busy-java-threads.sh文件

    `show-busy-java-threads.sh`脚本就是为了帮助开发者快速定位和排查这类性能问题而设计的。这个脚本主要用于监控并展示Java应用程序中的繁忙线程,从而帮助我们理解程序的执行状态,找出可能导致高CPU负载的原因。 ...

    mingw64.zip

    PATH : /usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_...

    jboss-threads-3.1.0.Final-API文档-中英对照版.zip

    赠送jar包:jboss-threads-3.1.0.Final.jar; 赠送原API文档:jboss-threads-3.1.0.Final-javadoc.jar; 赠送源代码:jboss-threads-3.1.0.Final-sources.jar; 赠送Maven依赖信息文件:jboss-threads-3.1.0.Final....

    gcc4.8.5离线安装rpm包含依赖

    Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/...

    mingw-std-threads-master

    mingw-std-threads-master介绍 mingw-std-threads-master是一个为MinGW(Minimalist GNU for Windows)环境提供的标准线程库实现。MinGW是一个开源项目,它提供了在Windows平台上使用GNU工具集(如GCC)进行软件...

    Node.js-worker-threads-pool轻松管理Node.js工作线程池

    "worker-threads-pool" 是一个专门为Node.js设计的库,它的目的是简化工作线程池的管理和操作。工作线程池可以有效地将CPU密集型任务分配到不同的工作线程中,从而提高程序的执行效率。这个库的主要功能包括创建...

    EurekaLog_7.5.0.0_Enterprise

    21)..Added: Major improvements in removal of recursive areas from call stack 22)..Added: Statistics collection 23)..Added: Support for uploading multiple files in JIRA 24)..Added: EResLeaks ...

    x86_64-4.8.5-release-posix-sjlj-rt_v4-rev0.7z

    PATH : /usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_...

    Packt.Python.Journey.from.Novice.to.Expert.2016

    Develop a strong set of programming skills with Pyhton that you will be able to express in any situation, on every platform, thanks to Python's portability Stop writing scripts and start architecting ...

    mysql-community-server-5.7.28-x86.tar.gz

    适用于x86架构linux的mysql-community-server-5.7.28-x86,文件列表 ...perl-threads-shared-1.43-6.el7.x86_64.rpm perl-Time-HiRes-1.9725-3.el7.x86_64.rpm perl-Time-Local-1.2300-2.el7.noarch.rpm

    XSS漏洞检测工具

    * Multiple injections from URL, with automatic payloading, using tor proxy, injecting on payloads character encoding in "Hexadecimal", with verbose output and saving results to file &#40;XSSlist.dat&#...

    Python库 | hanging_threads-1.1.0-py2-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:hanging_threads-1.1.0-py2-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    rh-perl530-perl-threads-shared-1.60-452.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    rh-perl526-perl-threads-shared-1.57-5.el7.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

Global site tag (gtag.js) - Google Analytics