Ssh using expect with threads? - multithreading

Have you found solution any on how to ssh using expect with threads?
sub thDoWork {
#variables
my $thread_number = $_[0];
my $PassStoreQueue = $_[1];
my $Thread_Die = '';
my $My_Print_Bucket = '';
while ($Thread_Die ne 'KILL_THREAD') {
my $temp_Store_Number_Working_On = $PassStoreQueue->dequeue();
my $name;
my $ip;
my $Device_Exist;
my $TempDeviceName;
my $DNS_Results;
# I need to ssh inside many threads, I can ssh from the main
# thread just fine but not a sub thread.
$ssh = Expect->spawn("ssh -l $username1 $temp_ssh_device " .
"-o UserKnownHostsFile=/dev/null " .
"-o StrictHostKeyChecking=no")
or return "Couldn't spawn ssh session";
# this is unable to login to device.
}
I have read a thread that expect is not working correctly in threads, is that still true?

Related

Start Shell Script in Java and destroy all processes on Exit

I need some special kind of setup to controll a LED Wall. Sadly i cant really change the programming language i use. My setup looks like this:
Processing (some crazy java fork...) Sketch starts after Boot Process. The Processing Sketch scans a folder for subfolder (other sketches which can be started and controll the LED Wall) and starts a Webserver. The Server renders a List with all the scanned Folders. On Click the "Webserver" launches the selected Sketch via ProcessBuilder. The Processing Sketch looks like this:
import http.*;
import java.util.*;
import java.lang.*;
SimpleHTTPServer server;
String prog = "";
int ExitValue = 1;
ProcessBuilder preparedsketch;
Process runningsketch;
void setup() {
SimpleHTTPServer.useIndexHtml = false;
server = new SimpleHTTPServer(this);
TemplateFileHandler templateHandler = new ResultFiles("index.ftl");
server.createContext("", templateHandler);
}
class ResultFiles extends TemplateFileHandler {
public ResultFiles(String templateFileName) {
super(templateFileName);
}
void createMap() {
Map<String, String> params = queryToMap();
if (params.containsKey("prog")) {
if (params.get("prog").equals(prog)) {
println("Has not changed");
} else {
println("PrevProcess: " + runningsketch);
if (runningsketch != null) {
println("Killing: " + runningsketch);
runningsketch.destroy();
}
prog = params.get("prog");
try {
runningsketch = new ProcessBuilder("/Users/kessleml/dev/pixelpusher/base/processing-quit.sh", "--sketch=/Users/kessleml/dev/pixelpusher/base/sketches/pixelpusher_colourcycle_halloween", "--run").start();
// runningsketch = new ProcessBuilder("/usr/local/bin/processing-java", "--force", "--sketch=" + sketchPath("sketches/" + prog + "/"), "--no-java", "--run").start();
} catch (IOException ex) {
println(ex);
}
println("ProjChagned: " + prog);
println("NewProcess: " + runningsketch);
}
}
File files = new File(sketchPath("sketches"));
String[] fileslist = files.list();
addVariable("files", fileslist);
addVariable("selectedprog", prog);
}
}
Everything works till now. But of course i want to close a running (and looping) Sketch if i change (click on a other Sketch on the Website). The Problem is:
When i launch a selected Sketch via runninngsketch = new ProcessBuilder("Path/To/ProcessingCLI", "--sketch=Path/To/Selected/Sketch", "--run").start(); more than one process launches. The reason for this, is the ProcessingCLI File:
#!/bin/sh
# Prevents processing-java from stealing focus, see:
# https://github.com/processing/processing/issues/3996.
OPTION_FOR_HEADLESS_RUN=""
for ARG in "$#"
do
if [ "$ARG" = "--build" ]; then
OPTION_FOR_HEADLESS_RUN="-Djava.awt.headless=true"
fi
done
cd "/Applications/Processing.app/Contents/Java" && /Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true $OPTION_FOR_HEADLESS_RUN -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$#"
So the ProcessBuilder starts three processes: One sh-process which launches two Java-Children-Processes. When i use runningsketch.destroy() it only kills the sh process. The two Java-processes continue running. (Not sure if this is also because of this bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4770092 since i am developing on MacOS Yosemite. The final Product should run on a Linux Machine.)
My solution was to write a new sh-script which kills all of its children via trap:
#!/bin/sh
OPTION_FOR_HEADLESS_RUN=""
function killAllChildren {
kill -9 -$(ps -o pgid= $$ | grep -o '[0-9]*')
}
trap killAllChildren SIGTERM SIGKILL
# trap "trap - SIGTERM && kill -- $$" SIGINT SIGTERM EXIT
cd "/Applications/Processing.app/Contents/Java"
/Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true $OPTION_FOR_HEADLESS_RUN -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$#"
But somehow, also this doesnt work. Even with starting the new sh-script and sending for example a SIGTERM to the started sh-process, doesnt destroy the two Java-Processes neither the sh-process.
I found the solution:
Java sends a SIGTERM signal, so i had to trap this signal. But the java/processing file wasnt the problem, the sh-script didn work as intended.
I had to add & wait to the and of my script. Otherwise SIGTERM cant be trapped (see this post: https://apple.stackexchange.com/questions/123631/why-does-a-shell-script-trapping-sigterm-work-when-run-manually-but-not-when-ru).
Also the killing process didn work out right. I have to kill all children, the sh-script itself BUT not the parent-processes of the sh-script (in this use case the webserver etc.). So i wrote a function to find all children processes and kill them. Things like kill -9 -$(ps -o pgid= $$ | grep -o '[0-9]*') didnt work since they killed the whole tree. In the end the sh-file looks like this:
#!/bin/sh
function killAllChildren {
getChild $$
pkill -TERM -P $$
}
function getChild() {
cpids=`pgrep -P $1|xargs`
for cpid in $cpids;
do
kill -15 $cpid
getChild $cpid
done
}
trap killAllChildren SIGUSR1 SIGTERM SIGKILL EXIT
cd "/Applications/Processing.app/Contents/Java"
/Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$#" & wait

How to call a function in Perl script after performing SSH?

I am creating a perl script in which I have to ssh multiple servers from same script and perform same commands on all these remote servers.
Right now I am using "If loop" and call all other servers from this script and perform command on them.
I want to create a function with these set of commands, that I need to perform on these different servers.
if($random_number==1){
use Net::SSH::perl
use lib qw("user/share/perl5/");
my $hostname = "10.*.*.*";
my $username = "root";
my $password = "root\#123";
my $cmd1 = "ls /home/ashish/"
my $cmd2 = "netstat -na | grep *.*.*.*;
$ssh->login("$username" , "$password");
my ($stdout,$stderr,$exit) = $ssh->cmd("$smd1" && "$cmd2");
print $stdout;
}
the above commands after if syntax needs to be repeated for different servers.
want to use a function call.
Start with general programming toutorials, then do it like:
use Net::SSH::perl;
use strict;
use warnings;
my #servers = (
{
hostname => 'somehost1',
username => 'someuser1',
password => 'somepass1',
commands => ['somecmd11','somecmd12'],
},
{
hostname => 'somehost2',
username => 'someuser2',
password => 'somepass2',
commands => ['somecmd21','somecmd22'],
},
# ...
);
do_something_on_remote_servers_one_by_one( #servers );
exit(0);
sub do_something_on_remote_servers_one_by_one {
my (#servers) = #_;
foreach my $server (#servers) {
my $ssh = Net::SSH::perl->new($server->{hostname});
$ssh->login($server->{username}, $server->{password});
my $cmd_string = join(' & ', #{ $server->{commands} } );
my ($stdout,$stderr,$exit) = $ssh->cmd($cmd_string);
print $stdout;
}
}
After that, you can think about executing commands in paralell.

segmentation fault while using Net::ssh::perl module with threads

After running this program
Segmentation fault (core dumped)
Code below:
use threads;
use Net::SSH::Perl;
my $host = 'hostname';
my $user = 'root';
my $password = 'root123';
my $thread = threads->new (\&ThreadEntry,"ls");
my $thread1 = threads->new (\&ThreadEntry,"ls -al ");
sub ThreadEntry()
{
my $ssh = Net::SSH::Perl->new($host, 35903);
print "in ssh function \n";
my($stdout, $stderr, $exit) =$ssh->cmd(#_);
print "$stdout $stderr $exit\n";
}
$thread->join();
$thread1->join();
This is a known bug, see link below:
https://rt.cpan.org/Public/Bug/Display.html?id=62053

Using Net::Telnet to ssh into linux

I am trying to use below perl code to ssh into linux machine and pull output of ls -l but it doesnt seem to be working.
What am i doing wrong?
#!/usr/bin/perl
use warnings;
use strict;
use Net::Telnet;
use IO::Pty;
use POSIX 'setsid';
use Getopt::Long;
use constant PROMPT => '/[a-z#>]/';
my $host = "192.168.1.121";
my $user = "root";
my $ssh = do_cmd( 'ssh', "-l$user", $host );
my $shell = Net::Telnet->new( Fhopen => $ssh );
$shell->binmode(1);
$shell->cmd( String => 'test', Prompt => '/[a-z]/' );
$shell->waitfor(PROMPT);
my #lines = $shell->cmd( String => 'ls -l', Prompt => '/[a-z]/' );
print #lines;
print "\n";
sub do_cmd {
my ( $cmd, #args ) = #_;
my $pty = IO::Pty->new;
defined( my $child = fork );
return $pty if $child;
setsid();
my $tty = $pty->slave;
close $pty;
STDIN->fdopen( $tty, "<" );
STDOUT->fdopen( $tty, ">" );
STDERR->fdopen( $tty, ">" );
close $tty;
$| = 1;
exec $cmd, #args;
}
Telnet and SSH are two different programs. You can't use telnet client for ssh server.

Perl script not executing some external calls

I have wrote this Perl script to automate my wireless connections:
#!/usr/bin/perl
use strict;
my #modes = ("start", "stop");
my $mode = $modes[0];
my $kill_command = "sudo kill -TERM ";
sub check_args
{
if($#ARGV != 0)
{
print(STDERR "Wrong arguments\n");
print(STDERR "Usage: ./wicd.pl start|stop\n");
exit();
}
my #aux = grep(/^$ARGV[0]$/, #modes);
if (!#aux)
{
print(STDERR "Unknown argument\n");
print(STDERR "Usage: ./wicd.pl start|stop\n");
exit();
}
$mode = $ARGV[0];
}
check_args();
my #is_wicd_running = `ps -A | grep wicd`;
# START
if ($mode eq $modes[0])
{
if (!#is_wicd_running)
{
system("gksudo ifconfig wlan0 down");
system("sudo macchanger -r wlan0");
system("sudo wicd");
}
my #is_wicd_gui_running = grep(/wicd-client/, #is_wicd_running);
if (!#is_wicd_gui_running)
{
system("gksudo wicd-gtk &");
}
}
# STOP
else
{
for (#is_wicd_running)
{
my #aux = split(/ /, $_);
system("$kill_command$aux[1]");
}
system("sudo ifconfig wlan0 down");
}
The problem is that macchanger and sudo ifconfig wlan0 down are not executing (only those...). The weird thing is that those call do execute when calling the script through Perl debugger (perl -d). I thought this could be a timing problem and added some sleep() calls before those calls, but no change. I also tried with system() calls with no change as well.
EDIT: more strange, I've found that if I run the script as perl wicd.pl it runs properly, while ./wicd.pl does not (it runs but has the problem described above). I've attached the whole script. The Perl interpreter used on the header is the same that which perl command returns.
Any clues? Thanks in advance!
More information may help, along with assuring that a \n always ends the output line. Try your running commands within
sub runx
{
foreach my $cmd ( #_ )
{
my $out = qx("$cmd 2>&1");
my $x = $?;
$out =~ s/\s*$/\n/s;
printf "\%s (0x\%0x):\n\%s", $cmd, $x, $out;
last if $x;
}
return $x;
}
No time to run this code this morning and can't delete my prior comment. But somethings running a "which" command can also assure your command is on PATH.

Resources