My VBA codes below shows the template about how to control my host via plink
Set wsh = VBA.CreateObject("WScript.Shell")
for i = 1 to 1000
wsh.Run("cmd.exe /c plink -ssh 192.168.100.xx -l root -pw xxxx command", 0, True)
Sleep 1000
next i
If I have to get information from host via plink.exe every second, it is necessary to execute "wsh.Run("cmd.exe /c plink -ssh 192.168.100.xx -l root -pw xxxx command", 0, True)" every time, which wastes time in opening shell and executing plink.exe and then close it all each round. Is there a way to save the time, which means that to open shell and execute plink.exe once and keep plink.exe listening my command until loop ends?
You may want to take a look at Chip Pearsons solution, Shell and Wait.
http://www.cpearson.com/excel/ShellAndWait.aspx
The ShellAndWait function calls Shell and then waits for the Shell'd process to terminate. You can specify an interval after which the function times out and returns to the caller. The declaration of ShellAndWait is as follows:
Related
I have hard requirement of logging into a terminal via SSH from TCL console and relaunch a tcl script from that terminal. For this I use exec command and it does get executed. The only problem is it doesn't return back to parent code.
I have automated SSH login and it works fine from a bash/csh terminal
But from TCL console, the following happens
Simple example
exec ssh hostname pwd
puts "Done"
When I execute this code in TCL, "Done" never gets printed. I just get the output of pwd and that's it.
I have a need of looping SSH into multiple terminals and run TCL jobs on a hardware, but the loop gets stuck after executing the first SSH.
I search the internet for answers and I am not able to find any. Please help.
There could be a lot issues going on here. Running ssh with an explicit command (pwd) will usually default to not allocating a tty (ssh -T) and will run the remote shell in non-interactive mode. And the output of a command called from exec is not normally echoed to standard output, so I would not expect you to see the output if you call it from a script. You have to print the result of exec to see the output of the pwd command. Also, different shell startup scripts are run on the remote host depending on which shell the account is set up with and whether it is an interactive or non-interactive shell. It could be .bashrc, .bash_profile, .profile, .cshrc, etc., and if the script behaves differently when it has a tty vs. when it doesn't, that could explain differing behavior between a bash/csh shell and the TCL console.
Without having access to your system, it is hard for me to troubleshoot. I would start with a script like this:
set result [exec ssh -T hostname pwd]
puts "result = $result"
puts "Done."
Then I would try changing the -T to a -t and trying again. If the output of "pwd" is appearing before the "result =" line, then you can tell that the command is writing the result to a tty instead of standard output, and that's useful information for troubleshooting.
I am scripting some command line operations for collecting and parsing specific network metrics from a Palo Alto 5060 firewall. I am using Plink and Windows batch scripting.
#echo off
"C:\path\to\plink.exe" -ssh user#1.2.3.4 -pw password < "C:\path\to\commands.txt >> "C:\path\to\output.txt"
The content of the commands.txt is simple at the moment.
show interface ethernet1/1
I cannot get this to work. My output.txt has the following results:
Last login: Tue Nov 24 15:43:13 2015 from localhost
show interface ethernet1/1Welcome user.
user#pa5060> show
[Kuser#pa5060> show interface
[Kuser#pa5060> show interface ethernet1/1
This isn't the proper output and the entry of the commands confuses me. Has anyone seen something like this? There is a login banner on this device if that is relevant.
I'd guess you are missing a new-line at the end of the command.txt, so the command is not submitted.
As for the repeated prompt and the [K sequence:
This is simply because the remote side expects an interactive terminal on your end, and sends ANSI escape sequences to pretty-print an output.
Each line likely starts with the CR (carriage return) character that would cause the interactive terminal to overwrite the previous line. But this does not work, when you redirect the output to a file. Though if you print the file on a terminal (cmd.exe) using type output, you will probably get only the last line.
To make Plink not enable the interactive terminal, use the -T command-line switch:
"C:\path\to\plink.exe" -ssh user#1.2.3.4 -pw password -T < "C:\path\to\commands.txt >> "C:\path\to\output.txt"
Though even better is to specify the command on PLink command line
"C:\path\to\plink.exe" -ssh user#1.2.3.4 -pw password show interface ethernet1/1 >> "C:\path\to\output.txt"
or using -m switch:
"C:\path\to\plink.exe" -ssh user#1.2.3.4 -pw password -m "C:\path\to\commands.txt >> "C:\path\to\output.txt"
The difference is that the commands specified this way are automatically executed in a non-interactive terminal and mainly in an "exec" channel in a more controlled way, then in the "shell" channel you are using when redirecting the input. So you get rid of the "Last login:" message as well as the command prompt (user#pa5060>) and such.
I want to run a few shell commands every time I SSH to a server via PuTTY. I'm connecting to a production web server managed by someone else, and I don't want to store my own scripts there.
I see the option Connection > SSH > Remote Command, but if I put my initialization commands there, after starting the session, it closes immediately after the commands execute. How can I run the Remote Command, and then keep the session open so I can continue using it?
The SSH session closes (and PuTTY with it) as soon as the command finishes. By default the "command" is a shell. As you have overridden this default "command" and yet you want to run the shell nevertheless, you have to explicitly execute the shell yourself:
my-command ; /bin/bash
See also Executing a specific command on the server.
One option to go is set up your putty remote command like this:
ls > dir.ls & /bin/bash
In this example command you want to run is "ls > dir.ls" what creates file dir.ls with content of directory listing.
And as you want to leave shell open you can add aditional command "/bin/bash" or any other shell of your choice.
I am trying the following string in command prompt to execute some (test) remote commands on my server:
plink.exe -ssh -pw [PASSWD] [U/NAME]#[SERVER] -m cmds.bat -v
In my cmds.bat file I have some test commands:
sleep 3
#echo off
ls -la ~/
#echo on
sleep 1
I now want to beef this up to run a remote script while passing an argument. The argument will be handled and appended by my VBA code. This is the part I am stuck at. Please note the following VBA code is only a snippet; the part that calls Plink. The surrounding code, I am happy with:
If re.Test(Msg.Subject) Then
Set matchCol = re.Execute(Msg.Subject)
For Each match In matchCol
shellStr = "plink.exe -ssh [USERNAME]#[SERVER] -pw [P/WORD] -m cmds.bat " & match
Shell(shellStr, vbNormalFocus)
Next
End If
The offending line is:
shellStr = "plink.exe -ssh [USERNAME]#[SERVER] -pw [P/WORD] -m cmds.bat " & match
I do not know how to append the value held in variable match (captured by the Regexp) to the string to be executed in opening the shell.
The bat file will handle the command for actually running the script on the remote Unix server, where instead of ls -la ~/ in the above example I will use:
python ~/myscript.py [ARGUMENT FROM VBA VARIABLE "match"]
But how do I pass this match variable's value into this?
you cannot do this; plink just doesn't support this usage. your best bet is doing what you suggested in your comment: build the script on the fly. (and maybe don't call it .bat, that seems misleading a bit …)
How do I execute a command every time after ssh'ing from one machine to another?
e.g
ssh mymachine
stty erase ^H
I'd rather just have "stty erase ^H" execute every time after my ssh connection completes.
This command can't simply go into my .zshrc file. i.e. for local sessions, I can't run the command (it screws up my keybindings). But I need it run for my remote sessions.
Put the commands in ~/.ssh/rc
You can put something like this into your shell's startup file:
if [ -n "$SSH_CONNECTION" ]
then
stty erase ^H
end
The -n test will determine if SSH_CONNECTION is set which happens only when logged in via SSH.
If you're logging into a *nix box with a shell, why not put it in your shell startup?
.bashrc or .profile in most cases.
Assuming a linux target, put it in your .profile
Try adding the command below the end of your ~/.bashrc. It should be exited upon logoff. Do you want this command only executed when logging off a ssh session? What about local sessions, etc?
trap 'stty erase ^H; exit 0' 0
You probably could setup a .logout file from /etc/profile using this same pattern as well.
An answer for us, screen/byobu users:
The geocar's solution will not work as screen will complain that "Must be connected to a terminal.". (This is probably caused by the fact that .ssh/rc is processed before shell is started. See LOGIN PROCESS section from man 8 sshd).
Robert's solution is better here but since screen and byobu open it's own bash instance, we need to avoid infinite recursion. So here is adjusted byobu-friendly version:
## RUN BYOBU IF SSH'D ##
## '''''''''''''''''' ##
# (but only if this is a login shell)
if shopt -q login_shell
then
if [ -n "$SSH_CONNECTION" ]
then
byobu
exit
fi
fi
Note that I also added exit after byobu, since IMO if you use byobu in the first place, you normally don't want to do anything outside of it.