VanDyke Software Forums

VanDyke Software Forums (https://forums.vandyke.com/index.php)
-   SecureCRT on the Mac (https://forums.vandyke.com/forumdisplay.php?f=24)
-   -   script to SSH to host (https://forums.vandyke.com/showthread.php?t=13248)

rleon 09-12-2018 10:36 AM

script to SSH to host
 
:cool:
Code:

def main():
        crt.Screen.Synchronous = False
with open('/Users/rleon16/hosts') as hosts_:
        for host in hosts_:
                crt.Screen.WaitForString("working # ")
                crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@" + host + ps -ef | grep gofer + '\r')
                crt.Screen.WaitForString("word: ")
                crt.Screen.Send("mypass!" + chr(13))

main()

/Users/rleon16/hosts is a list of hostnames.

I am trying to string a ssh command but getting an error.

I just want it to run the command and loop through.

Any ideas?

jdev 09-12-2018 11:11 AM

Quote:

Originally Posted by rleon (Post 50199)
I am trying to string a ssh command but getting an error.

Usually the most important aspect of knowing how to address an error is knowing details about the error itself.

What is the exact text of the error you're seeing?

I can share things I see wrong with your code, but without any details about the error you're seeing, it's possible that none of them will have anything to do with the error you're seeing.
Here are my in-the-dark-because-you-haven't-said-what-the-error-is observations:
  1. The indentation of your code seems to be off, which python is particularly sensitive about:
    Incorrect indentation:
    Code:

    def main():
            crt.Screen.Synchronous = False
    with open('/Users/rleon16/hosts') as hosts_:
            for host in hosts_:
                    crt.Screen.WaitForString("working # ")
                    crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@" + host + ps -ef | grep gofer + '\r')
                    crt.Screen.WaitForString("word: ")
                    crt.Screen.Send("mypass!" + chr(13))

    main()

    Correct Indentation:
    Code:

    def main():
        crt.Screen.Synchronous = False
        with open('/Users/rleon16/hosts') as hosts_:
            for host in hosts_:
                crt.Screen.WaitForString("working # ")
                crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@" + host + ps -ef | grep gofer + '\r')
                crt.Screen.WaitForString("word: ")
                crt.Screen.Send("mypass!" + chr(13))

    main()

  2. Also, you're trying to concatenate a string so that your ssh command tells the remote ssh host to run a command there on that secondary host (the 'ps -eaf | grep gofer' portion). However, you failed to enclose that portion in ""s, so the python interpreter is choking on that portion of your statement.

    This would be one way of correcting the mistake:
    Code:


    crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@" + host + " \"ps -ef | grep gofer\"\r")

    Here's another way to correctly concatenate strings, using the format function and substitution params {0} and {1}:
    Code:


    crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@{0} \"{1}\"\r".format(host, "ps -ef | grep gofer"))

    Here's yet another example, which breaks things up into smaller chunks and builds the command using those chunks:
    Code:


    strSSHcmd = "ssh -oStrictHostKeyChecking=no root@" + host
    strRexec = "ps -ef | grep gofer"
    strFullCmd = "{0} \"{1}\"\r".format(strSSHcmd, strRexec)
    crt.Screen.Send(strFullCmd)

  3. If you want the 'grep' performed on the remote server (the 'host' as read in from your file), then you need to enclose the entire command in embedded ""s. Otherwise, the grep will be done on the jump host instead of on the remote host. This problem has been fixed for you in the above examples as well. If you wanted the grep to be conducted in the shell of your jump host server, just remove the \" components from the above examples.


rleon 04-17-2019 01:13 PM

Sorry to dig up an old thread but something is wrong with the code.

Code:

# $language = "python"
# $interface = "1.0"

def main():
        crt.Screen.Synchronous = False
        with open('/Users/rleon/hosts') as hosts_:
                for host in hosts_:
                        crt.Screen.WaitForString("nfs # ")
                        crt.Screen.Send("ssh -oStrictHostKeyChecking=no root@{0} \"{1}\"\r".format(host, "ps -ef | grep gofer"))
                        crt.Screen.WaitForString("word: ")
                        crt.Screen.Send("mypass" + chr(13))

main()


when it runs

Code:

# ssh -oStrictHostKeyChecking=no root@myhost
 "ps -ef | grep gofer"

the command i want ran on the remote host is on the next line.

it should be all one line

# ssh -oStrictHostKeyChecking=no root@myhost "ps -ef | grep gofer"

jdev 04-17-2019 02:02 PM

Quote:

Originally Posted by rleon (Post 51352)
Sorry to dig up an old thread but something is wrong with the code.

the command i want ran on the remote host is on the next line.

it should be all one line

# ssh -oStrictHostKeyChecking=no root@myhost "ps -ef | grep gofer"

When you use Python's open() to read in lines from a file, the data returned for each line read includes the EOL terminator -- which may be a carriage return (CR or \r) or a line feed (LF or \n) or potentially both (CRLF or \r\n) for all I know.

If using this host variable to compose your command (which doesn't have any literal \r or \n in the string between the hostname and the rexec portion of the command) results in output as you describe with the rexec portion appearing on a separate line, then it must mean that your host variable has some embedded \r and/or \n character(s) that cause the entire command to be sent to the remote as two separate lines.

Consider using the Python-provided strip() method on your host variable to remove any unwanted \r or \n characters, as demonstrated in this example demonstrating a before and after.

Then use the same pattern to fix your code.
Code:

# $language = "python"
# $interface = "1.0"

import os

def main():
    crt.Screen.Synchronous = False
    with open(os.path.expanduser('~') + '/hosts') as hosts_:
        for host in hosts_:
            hostbefore = host
           
            # get rid of \r and \n characters
            host = host.strip('\r\n')

            # The following messagebox will show the
            # value of the hostbefore and host variables
            # but surrounded by <>s. If there are any
            # embedded \r or \n chars, both <>s won't be
            # on the same line in the msgbox.
            crt.Dialog.MessageBox("host(before): <{0}>\r\n\r\nhost(after): <{1}>".format(hostbefore, host))


main()

There's also an arguably slicker way Python allows for doing the strip() inside of the for iterator so that the variable is already cleansed of any \r and \n chars. However, this syntax is a wee bit harder to grok if you're not used to the construct:
Code:

# $language = "python"
# $interface = "1.0"

import os

def main():
    crt.Screen.Synchronous = False
    with open(os.path.expanduser('~') + '/hosts') as hosts_:
        for host in (x.strip('\r\n') for x in hosts_):
            hostbefore = host

            # The following messagebox will show the
            # value of the hostbefore and host variables
            # but surrounded by <>s. If there are any
            # embedded \r or \n chars, both <>s won't be
            # on the same line in the msgbox.
            crt.Dialog.MessageBox("host(before): <{0}>\r\n\r\nhost(after): <{1}>".format(hostbefore, host))


main()



All times are GMT -6. The time now is 01:05 AM.