This question already has an answer here:
Parsing command line using argc and argv in expect
(1 answer)
Closed 3 years ago.
I would like to remove all log files inside directory /var/log/$some_project/
I can remove them using shell command :
sudo rm /var/log/$some_project/*.log
But I have created expect script as shown below. Where I pass the PASS (my system password) and FILES (/var/log/$some_project/*.log) but it does not delete the files. It deleted only one file the first one.
I also tried instead of passing FILES/*.log, I just passed /var/log/$some_project and use the second script. But still, I am not able to remove all the log files.
I have also tried passing each file to expect script and remove still it does not work.
First Script
set timeout -1
set PASS [lindex $argv 0];
set FILES [lindex $argv 1];
spawn sudo rm $FILES
expect "Password:"
send $PASS\r
set timeout -1
exit 0
expect eof
Second Script
set timeout -1
set PASS [lindex $argv 0];
set FILES [lindex $argv 1];
spawn sudo rm $FILES/*.log
expect "Password:"
send $PASS\r
set timeout -1
exit 0
expect eof
Please, I would want to expect to understand the wildcard character and remove the files from the directory specified.
If you pass a wildcard expression to a script, the shell in which you run the script expands the wildcard before starting the script. So by the time Expect runs, [lindex $argv 1] really contains only the first one of the files you want to removed
Related
I have written an expect script which I am calling from my bash script, which removes the content in the directories, copies the jar and extracts it. I am doing it through expect script shown below:
I have used sleep and wait between the process and nothing helps. I do not get the desired output as expected. Please check the script is fairly simple, it removes content inside the directory, created one, add jar and tries to extract it.
set timeout -1
set PASS [lindex $argv 0];
set DIRECTORY [lindex $argv 1];
set FOLDER_NAME [lindex $argv 2];
set WAR_PATH [lindex $argv 3];
set WAR_NAME [lindex $argv 4];
spawn sudo rm -rf $DIRECTORY/$FOLDER_NAME
expect "Password:"
send $PASS\r
spawn sudo mkdir $DIRECTORY/$FOLDER_NAME
expect "Password:"
send $PASS\r
spawn sudo cp $WAR_PATH $DIRECTORY/$FOLDER_NAME
expect "Password:"
send $PASS\r
spawn sudo jar -xf $DIRECTORY/$FOLDER_NAME/$WAR_NAME
expect "Password:"
send $PASS\r
set timeout -1
expect eof
exit 0
Please help me so that this process is completed one after another without any problem. Thanks for your help.
After each send $PASS\r, you should expect eof to wait for the spawned process to complete.
I want to remotely delete a file/execute another script on my server. Manually this could be done by ssh-login -> cd /path/ -> rm somefiles -> . script.sh
I want to automatic this process. So that when I execute expect expectscript.sh port serverip user userpasswd, the script would do the whole process for me.
So I write the following script. Things go smoothly till the ssh-login process finished. I don't know what is wrong with the last 3 lines of the code. Could someone help?
#!/usr/bin/expect
set timeout 20
set port [lindex $argv 0]
set ip [lindex $argv 1]
set user [lindex $argv 2]
set password [lindex $argv 3]
spawn ssh "$user\#$ip" "-p" "$port"
expect "password:"
send "$password\r"
spawn "cd /etc/abcd/"
spawn "rm -f efg/*"
spawn ". somescriptinefg.sh"
Change the spawn to send solve the problem~
Literally,
spawn "Creates a new process by running a given program."
send "Sends string to the current process."
The problem seems to be that the password is being sent with a spawn command rather than a send command. Additionally, ssh can be called with a specific command to run during the session, for example:
#!/usr/bin/expect
set timeout 20
set port [lindex $argv 0]
set ip [lindex $argv 1]
set user [lindex $argv 2]
set password [lindex $argv 3]
spawn ssh $user#$ip -p $port "cd /etc/abcd/; rm -f efg/*; . somescriptinefg.sh"
expect "password:*"
send "$password\r"
expect eof
It might be worth configuring ssh keys for passwordless access instead. This would eliminate the need for an expect script and reduce the whole thing to a single line. If you really need to have an interactive ssh session, then a tool such as sshpass could be a less impractical alternative.
I have the following shell(/expect) script.
#!/bin/bash
expect -c '
set user [lindex $argv 0]
set password [lindex $argv 1]
set ipaddr [lindex $argv 2]
set timeout 10
spawn ssh $user#$ipaddr mkdir -p ~/Tested
expect "*?assword:*"
send -- "$password\r"
interact
'
when I run the script as follows
. test.sh abcd test 10.xx.xxx.xxx
It gives the following error
can't read "argv": no such variable
while executing
"lindex $argv 0"
invoked from within
"set user [lindex $argv 0]"
Does anybody know what the error is , if I replace [lindex $argv 0] lines with actual value the script runs.
Thanks in advance.
The -c flag in expect provides a way of executing commands specified on the command line rather than in a script.
In general, -c is flag is used in command line used to execute commands before a script takes control.
They are used as below.
expect -c "set debug 1" myscript.exp
Inside myscript.exp, you can check the value of this variable:
if [info exists debug] {
puts "debugging mode: on"
}
else {
set debug 0
# imagine more commands here
if $debug {puts "value of x = $x"}
}
When the script is run, it checks if debug is defined by evaluating info exists, a
Tcl command which returns 1 if the variable is defined or 0 if it is not. If it is defined,
the script can then test it later to determine if it should print debugging information internal to the script. The else clause sets debug to 0 just so that later a simple if $debug test can be used.
Now, lets come to your question. You are using the variable argv which is the command line argument list passed to some script and with -c flag in use, you cant make use of it since argv is intended to be used inside a script, not outside.
Instead of doing this way, you can put your code inside a script file and call the code as below.
expect yourscript.exp username pwd ip_address
If you still interested in command line arguments, then you can try what fwilson suggested in comments.
expect yourscript.exp $1 $2 $3
With this, yourscript.exp will get the arguments from the shell script.
Reference : Exploring Expect
I am using a following script which connects to windows server from Linux, but after connecting i have to call the a command by doing to a location under D: drive of windows followed by some folders (Where the Folder names consists of spaces eg: d:\Rakesh Tatineni\not able to execute\Manager.exe 1 1)
Above is the some how i want to execute/call a command with 2 argument 1 1.
Script using to connect to windows
#!/usr/bin/expect -f
# Expect script to supply username/admin password for remote ssh server
# and execute command.
# This script needs three argument to(s) connect to remote server:
# password = Password of remote Windows server, for Windows user.
# For example:
# ./call_engine.sh password
# set Variables
set password [lrange $argv 0 0]
set timeout -1
# now connect to remote windows box (ipaddr/hostname) with given script to execute
spawn ssh userid#<WindowsserverName>
match_max 100000
# Look for passwod prompt
expect "*?assword:*"
# Send password aka $password
send "$password\r"
# send blank line (\r) to make sure we get back to gui
send "\r"
expect eof
Appreciate your help , in between what kind of code we have to include to call a command as i mentioned above "d:\Rakesh Tatineni\not able to execute\Manager.exe 1 1"
Thanks,
Rakesh T
I see that you already give the script an argument of password. So you can change your script slighlty to add two more arguments like this:
set password [lrange $argv 0 0]
set arg1 [lrange $argv 1 1]
set arg2 [lrange $argv 2 2]
I have a script(dobrt) which upon executing asks for a password.How can i write a script which executes dobrt and automatically supplies the password it asks for.
when i execute ./dobrt -p file.txt , the system asks for a password. I want the password to be sent in automatically by the script. Here is the output
$ ./dobrt -p file.txt
Found 194 tests to execute
------------ 2010 February 11 11:27:33 ------------
Password: ***************
I tried using shell and expecxt scripts for this. here is what i did.
I have 2 scripts. I call the second script(run_dobrt.exp) from the first one(run_dobrt.sh).
Script 1 : run_dobrt.sh
#!/bin/ksh
TESTCASE_HOME="/home/abhijeet/code/testcases";
TESTCASE_LIST="file.txt";
PASSWORD="*****";
echo "Running Expect Script"
`./run_dobrt.exp $TESTCASE_HOME $TESTCASE_LIST $PASSWORD`
Script 2: run_dobrt.exp
#!/usr/local/bin/expect -f
set TESTCASE_HOME [lindex $argv 0];
set TESTCASE_LIST [lindex $argv 1];
set PASSWORD [lindex $argv 3];
set timeout 200
spawn $TESTCASE_HOME/dobrt -p $TESTCASE_HOME/$TESTCASE_LIST
expect "*?assword:*" {send -- "$PASSWORD\r";}
expect eof
Now when i run run_dobrt.sh i get the following error
run_dobrt.sh[20]: spawn: not found
How to get rid of this error and get this task done? Please help.
What is dobrt? is a self-made program? If this is the case I think you will have to recode it to parse an extra argument that accepts the password. Then you will be able to pass this passowrd to dobrt just as you do it like "-p file.txt" in the command line (through a script).
I see two problems:
In the last line of your shell script, remove the back-quotes `` around the command,
they will cause the output of the expect script to be executed as a shell command.
In the expect script, change
set PASSWORD [lindex $argv 3];
to
set PASSWORD [lindex $argv 2];
you are skipping an argument.
If the password is the only input dobrt prompts for, you could try this:
Script 1 : run_dobrt.sh
#!/bin/ksh
TESTCASE_HOME="/home/abhijeet/code/testcases";
TESTCASE_LIST="file.txt";
PASSWORD="*****";
./run_dobrt.exp $TESTCASE_HOME $TESTCASE_LIST << EOF
$PASSWORD
EOF