Error while running expect in unix - linux

Getting error while running expect script in bash script
Input:
{
/usr/bin/expect << EOF
spawn ssh execsped#10.150.10.194 "cd /home/execsped/ram_test_72;./testecho.sh \"$evenno\" \"$eisinno\" \"$efilename\""
expect "Password"
send "abc#123\r"
expect "*#*"
EOF
}
Output:
extra characters after close-quote
while executing
"spawn ssh execsped#10.150.10.72 "cd /home/execsped/evoting_test_72;./testecho.sh "10575" "_eVoting.pdf" "abc.pdf"
"

remove the escaped quotes. look at the final command it's trying to run: "cd /home/execsped/evoting_test_72;./testecho.sh "10575" "_eVoting.pdf" "abc.pdf" " it should run fine without the escaped quotes.

Related

use expect to enter password when need sudo in script

I am using Ubuntu 14.04 and installed expect. I am trying to write a script to enter password when it prompted.
UPDATED Code:
#!/usr/bin/expect -d
set timeout 20
set pw odroid
spawn sudo apt-get update
expect {\[sudo]\ password for odroid: }
send "$pw\r"
close
Any suggestions? thx
UPDATE Errors:
expect: does "" (spawn_id exp4) match glob pattern "\[sudo]\ password for odroid: "? no
[sudo] password for odroid:
expect: does "[sudo] password for odroid: " (spawn_id exp4) match glob pattern "\[sudo]\ password for odroid: "? yes
expect: set expect_out(0,string) "[sudo] password for odroid: "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "[sudo] password for odroid: "
send: sending "odroid\r" to { exp4 }
A more generic way of solving your issue would be matching on assword
expect "*?assword*"
This allows for a more generic script where the username is irrelevant.
I also had the following issue with the snippet below. Basically $pw gets interpreted by the shell and needs to be set outside the expect TCL code.
pw="Password1234"
expect -f - <<-EOF
set timeout 10
spawn sudo -k
spawn sudo mysql_secure_installation
expect "*?assword*"
send -- "$pw\r"
expect eof
EOF
You have too many quotes. Choose one of:
expect {\[sudo\] password for odroid: }
expect "\\\[sudo\\\] password for odroid: "
Clearly the first option is better.
Lots of escaping is necessary because 1) square brackets are special in a glob pattern, and 2) square brackets are special Tcl syntax (command substitution) in double quotes but not in curly braces.
Try to replace with this, it should work fine.
expect "\[sudo\] password for odroid:\r"

Open a executable with "sh" under Ubuntu

I'm working with the API for Sonar (http://javadocs.sonarsource.org/4.5/apidocs/org/sonar/api/utils/command/Command.html) and it says for the function to execute commands that "the command will be executed with sh executable."
What I want to to do is just use
tslint path/to/my/code.ts
in the terminal (since this works). But the damn method excutes the line with "sh" so it looks something like this
sh tslint path/to/my/code.ts
and gives me the error
sh: 0: can't open tslint
How do I work around this to just execute "tslint" even though the command starts with sh?
Thanks for the help
EDIT: Since many of you asked what the java code looks like that produces this command (not mine, it's from an open source project):
Command command = Command.create("tslint");
command.addArgument("--config " + configFile + " --format json " + file.trim());
final EDIT:
working version:
Command command = Command.create("node");
command.addArgument(pathToTsLint);
command.addArgument("--format");
command.addArgument("json");
command.addArgument("--config");
command.addArgument(configFile);
command.addArgument(file.trim());
command.setNewShell(false);
Check in the terminal with which tslint the full path of the file.
From the terminal you can all it with
/bin/sh -c "/path/to/tslint /path/to/my/code.ts"
With the Sonar API it is:
Command command = Comman.create('/full/path/name/to/tslint');
command.addArgument("--config " + configFile + " --format json " + file.trim());
You don't need the -c parameter from the sh command, but you must use the absolute path to the tslint command.

second "send" command in expect script is not waiting to finish the Output of first command

I have a very small expect script . The flow is as follows
ssh to remote machine
Execute a command and after executing the command you will be in a different prompt ( prompt name is Enter cmd>.
On the Enter cmd> prompt, I need to run many commands
Hence I designed this script
#!/usr/bin/expect
set FULL_CMD { #cmd1 #cmd2 #cmd3 }
puts "STARTING......."
log_file myfile.log ;# <<< === append output to a file
spawn ssh tempuser\#dummyserver
match_max 100000000
expect "password:"
send "temppasswd\r"
expect "*temp*"
send "cd \/home\r"
expect "*temp*"
send "new cmd prompt\r"
expect "Enter cmd>"
foreach tempcmd $FULL_CMD {
send "${tempcmd} \r "
expect -exact "Enter cmd>\r"
send -- "\r"
expect eof }
send "q"
send "exit\r"
puts "I HAVE ENDED......."
My problem: Actually the O/P of first command cmd#1 is very long and I can see that the expect script is not waiting for the O/P of the first command complete and is sending the second command cmd#2 after some time.
This script works fine on systems where O/P of cmd#1 is small, but on systems where the the O/P of cmd#1 is very large (say 1000000 lines), it has trouble, i.e. it issues the first command cmd#1 and the O/P follows, but before it get back to Enter cmd> prompt, the script issues the second command cmd#2
How can I ensure that command cmd#2 is sent only after the output of cmd#1 completes?
Try setting a timeout at the start:
set timeout 60
or use -1 to wait forever.
The problem lies in your foreach tempcmd $FULL_CMD loop:
foreach tempcmd $FULL_CMD {
send "${tempcmd} \r "
expect -exact "Enter cmd>\r"
send -- "\r"
expect eof }
The problem is that you're expecting "Enter cmd>\r", but you will never get the \r in your output.
What you should expect is "Enter cmd>$", where the $ implies the end of the current command output (and not '\nor '\r' oreof`).
foreach tempcmd $FULL_CMD {
send "${tempcmd} \r "
expect -exact "Enter cmd>$" # Check for spaces after '>' and fix as required
send -- "\r"
# expect eof
}
As for expect eof, it matches the end of the input stream which is connected to the output of the spawned process. It will only match once the spawned process terminates, thus it is of no use here
Why do you have "expect eof" in your for loop?
foreach tempcmd $FULL_CMD {
send "$tempcmd\r"
expect "Enter cmd>"
send -- "\r" # why do you need this?
}
It's smart, while developing your program, to enable debugging: add this near the top: exp_internal 1

how to ignore the backslash in expect script

I create the following script (expect under ksh ) ,
in order to copy the file data.txt from Linux machine to windows machine
scp process will be automatic by expect , so password question will be answered by expect
the problem is that expect can’t ignore the "\" backslash from the following line
spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:\'
so from output I see that expect send the line without the "\" backslash
what need to change in my syntax/script so expect will ignore the backslash ?
my script
#!/bin/ksh
PASSORD=secret123
SCP=`cat << EOF
set timeout -1
spawn scp /var/tmp/data.txt ADMIN#192.9.200.17:'c:\'
expect {
")?" { send "yes\r" ; exp_continue }
word: {send $PASSORD\r}
}
expect eof
EOF`
expect -c "$SCP"
.
results ( output )
spawn scp /var/tmp/data.txt ADMIN#192.9.200.17:'c:'
gcs#198.202.183.97's password:
scp: c:: Error opening file: The requested operation failed.
Killed by signal 1.
Use spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:/' instead as it should evaluate to the same path.
You need to escape \.
Try
spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:\\'

how to run command on telnet command prompt in perl script

i am executing telnet command in perl script as below.
$telnetOutput = `telnet localhost 4505`;
print "\n telnet command output: $telnetOutput \n";
$clients = `clients`;
print"\n $clients\n";
$clientNumber_or_anyOtherKey = `1`;
print "\n $clientNumber_or_anyOtherKey \n";
$pollers = `pollers`;
print "\n $pollers\n";`
but after running $telnetOutput = `telnet localhost 4505`; command, as we know it will open telnet command prompt but all other commands are still executing in same old command prmopt so it's saying clients or 1 or pollers are not recognized as internal or external commands.
can any 1 help me out pls?
thanks in advanch
Communicating with external processes like telnet is more complicated than you might imagine, as you have to correctly handle buffering, waiting for input, and so on.
The canonical way to approach this is to use Expect ( https://metacpan.org/module/RGIERSIG/Expect-1.21/Expect.pod ) if you really need full interaction.
If you don't actually need interaction then a remote command runner like ssh or rsh (which you can call from perl of course) is sufficient.
this is working example for telnet connection to d-link des-1228 router and executing 2 commands. change it if you want:
#!/usr/bin/perl
use strict;
use warnings;
use Net::Telnet;
my $params;
$params{'login'}='root';
$params{'password'}='hardpass';
$params{'default_prompt'}='/DES-[^:]+:.#/'; #change it to regexp matching your prompt
my $host = '192.168.1.20';
my $t=new Net::Telnet(Timeout=>5, Prompt=>$params{'default_prompt'}, Errmode=>sub{next;});
$t->open(Host=>$host, Timeout=>2);
my $res=$t->login($params{'login'}, $params{'password'});
return if $res!=1;
$t->cmd('disable clipaging');
my #lines=$t->cmd('show fdb'); #output here
$t->close();
install TCL (ActiveTcl8.5.13.0.296436-win32-ix86-threaded.exe for windows) in system.
Then install Expect Package from Command from as teacup install Expect
run below script after modification for requirement
#!/usr/bin/expect -f
#!usr/bin/expect
package require Expect
# Test expect script to telnet.
spawn telnet localhost portnumber
expect "TradeAggregator>"
send "3\r"
expect "Client:"
send "1\r"
expect "1-Client>"
send "2\r"
expect "Client Pollers"
send "2\r"
expect "1-NYMEX UTBAPI"
send "1\r"
expect "2-NYMEX UTBAPI"
send "Test_123\r"
expect "Are"
send "n\r"
send "exit\r"
send "exit\r"
send "exit\r"
# end of expect script.

Resources