Linux expect script if

Using if/else in expect script

I think I have a basic grasp of the concept of «if/else» in expect, but I don’t fully understand how to nest them, if there is a better way, or if I’m completely off-base to begin with.

This is what I have right now:

set file1 [open [lindex $argv 0] r] set pw1 [exec cat /home/user/.pw1.txt] set pw2 [exec cat /home/user/.pw2.txt] while <[gets $file1 host] != -1> < puts $host spawn -noecho "ssh $host" expect < "continue connecting"< send "yes\r" expect < "current" < send $pw2\r >"New password" < send $pw1\r >"Retype new password" < send $pw1\r >> expect "msnyder" send "exit\r" > interact > 

The file1 variable is the list of hosts to run the script against.

I know it isn’t accurate because it errors on line 22. But, I have no idea what needs to be fixed.

2 Answers 2

  1. missing close brace, probably for the «continue connecting» block
  2. missing space before the open brace of «continue connecting». Tcl (hence Expect) is very sensitive to whitespace as it is parsed into words before the commands are evaluated. For the very few gory details, see the 12 syntax rules of Tcl.

Your code might look like:

while <[gets $file1 host] != -1> < puts $host spawn -noecho "ssh $host" expect < "continue connecting" < send "yes\r" expect < "current" < send -- $pw2\r exp_continue >"New password" < send -- $pw1\r exp_continue >"Retype new password" < send -- $pw1\r exp_continue >msnyder > send "exit\r" > > interact > 
  • exp_continue is used to «loop» back up to the expect statement: in this case, you will expect to see all of «current», «new» and «retype», so you don’t want to bail out until you see your prompt.
  • get into the habit of typing send — something . Without the double dash, you’ll be surprised the day someone types in a password with a leading dash.

Thank you. I’m looking through the code before I run it so I can get a feel for what it’s doing and how to implement similar methods in the future. One thing that dawned on me is that I now have a couple systems that don’t need the RSA fingerprint to be accepted. Does this script assume it will be asked? If it doesn’t appear and drops straight to the command prompt on the remote server will the block be short-circuited and simply send the «exit» from the msnyder block? Seems like I would just need to move it up one level to be an «else» under the «continue connecting» «if». Is that correct?

Or maybe I need it in two places: once after accepting the RSA fingerprint if presented and once in lieu of the RSA fingerprint if I’ve already accepted it.

I ran the script. I think I’m seeing some changes that can be made to my method, but I»m running into problems with it. I’ll probably consider this issue resolved and open another question with the new problem to keep a separation of issues.

Источник

‘if else’ statement in Expect script

I am trying to create a script which will «send» input as per the output received from executing the previous script.

#!/usr/bin/expect -- set timeout 60 spawn ssh user@server1 expect "*assword*" < send "password\r"; >expect "*$*" < send "./jboss.sh status \r"; >if [ expect "*running*" ]; then < send "echo running \r"; >else < send "./jboss.sh start \r"; >fi 

1 Answer 1

You can simply group them into single expect statement and whichever matched, it can be processed accordingly.

#!/usr/bin/expect set timeout 60 spawn ssh user@server1 expect "assword" < send "password\r"; ># We escaped the `$` symbol with backslash to match literal '$' # The last '$' sign is to represent end-of-line set prompt "#|%|>|\\\$ $" expect < "(yes/no)" "password:" -re $prompt > send "./jboss.sh status\r" expect < "running" -re $prompt > expect -re $prompt 

This compound expect < "(yes/no)" «password:» -re $prompt > Is extremely important since you can get multiple responses back, otherwise the procedures are basically individual if statements and become mutually exclusive, this handles the first time connection «save RSA key» (or whatever algo) question prompted on a first connection. Also, if you are doing this is a loop be sure to close or the program can continue spawning and run away effectively becoming a fork bomb

Источник

Expect / Bash: Running a bash if statement in expect

I am trying to ssh into a server, and check if id_rsa.pub exists. If it does not exist, I would like to run ssh-keygen, otherwise I don’t want to do anything. I can run simply commands like «cat» or «rm» using send in Tcl/Expect, but when I try to do something like this it does not work:

send "if [ ! -f $USER_SSH_PATH/id_rsa.pub ]; then CREATE_FILE=true; fi\r" expect "# " < >send "if $CREATE_FILE; then; ssh-keygen -t rsa -C $USER -f $USER_SSH_PATH/id_rsa\r" . 

I get the following error message: # invalid command name «!» while executing «! -f /root/.ssh/id_rsa.pub » invoked from within Is it possible to run such a command please?

4 Answers 4

You need to escape the square brackets because it’s part of tcl syntax:

send "if \[ ! -f $USER_SSH_PATH/id_rsa.pub \]; then CREATE_FILE=true; fi\r" 

In tcl, [] works the same way « or $() works in bash. So what’s happening is that before executing the send command the interpreter first does a substitution on the string and it sees two things it needs to substitute:

  1. $USER_SSH_PATH gets substituted with the value contained in the variable USER_SSH_PATH
  2. [! . ] gets substituted with the result of calling the ! function/command. Which as you discovered doesn’t exist.

Note that in tcl (and by extension expect) variable and function names aren’t limited to alphanumeric. It’s valid to have variable and function names like $ or ! or even the NUL character (a byte with the value of 0):

proc ! <> proc "$" <> proc \0 <> ! ;# this prints ! \$ ;# this prints $ \0 ;# this prints "NUL character" 

As slebetman already pointed out, the characters [ , ] , $ and \ have a special meaning inside » .

  • [ and ] are used for command subsitution, so [expr ] would be replaced by 5 (the result).
  • $ is used for variable substitution.
  • \ is used for special characters (like \r for the character with the code point 13)

You can either escape those characters inside » with \ : I assume that $USER_SSH_PATH is a local (tcl) variable

send "if \[ ! -f $USER_SSH_PATH/id_rsa.pub \]; then CREATE_FILE=true; fi\r" 

or use < and >to surround your string.
If you use < and >no substitution will be done. This also includes that \r will be send as \r to the server, and not as single character.

There are a few other options to create such things:

    subst can do the substitution on a string. It is also possible that only certain kinds of substitution take place (use the -nocommands switch to prevent [] substitution, -novariables for $ substitution and -nobackslashes for \ )
    Example:

send [string map [list \r $USER_SSH_PATH] \ ] 

There are many ways to do such things.

Источник

Expect Script Tutorial: Expressions, If Conditions, For Loop, and While Loop Examples

Note: For expect command line arguments, read 6 Expect Script Command Line Argument Examples.

Expect Expressions – expr command

To evaluate the expressions, use the expr command, which executes the given expression and returns the result. Expect expressions are similar to the C expressions. Some of the valid expressions are listed below.

# To add two simple numerical values set sum "[expr 1 + 1]" # To multiple the value of variables set mul "[expr $sum * $sum]" # To evaluate conditions and returns 1 or 0 to indicate success or failure accordingly. set ret "[expr (1+1) == 2]" # Conditions may contain the command return values. set ret [expr [pid] == 0]

Expect Conditional Expressions – If command

If command is used for conditional flow of execution of statements as shown in the example below.

Just like any other programming language, you can use the elseif command in expect as shown below.

Expect Looping Constructs

Expect For Loop Examples:

As we know, for loop is used to do repeated execution of expression until certain condition.

General for loop construct :

Note: You should place the loop open brace in the same line as it contains “for” keyword.

Expect While Loop Examples:

If you enjoyed this article, you might also like..

Comments on this entry are closed.

hi vivek,
I am trying to call a function in a for loop like below:
#!/bin/bash
abc()
/usr/bin/ftp -inv 9 user
get
bye
ENDFTP > for ((i=0; i do
abc
done
the error I am getting is : syntax error: unexpected endof file

Hello, everybody! This is my question
How can I assign a command output to a variable? For example, the result of any ASCII text manipulation, a result of which could be one lines or one word.
Thanks in advance,
israel

@Balak
# To set the variable value which includes output of another command
set proc_id “process id : [pid]” This is wrong, the pid command returns the expect PID: try this and expect will close itself:
[sko@aemaeth:~]$ expect
expect1.1> set pid [pid]
27552
expect1.2> exec kill -15 $pid @Kashyap
you’re not using expect @Israel
set variablename [exec shellcommand], for example: [sko@aemaeth:~]$ expect
expect1.1> set aaa [exec echo “/bin/ls”]
/bin/ls
expect1.2> set b “/tmp/test”
/tmp/test
expect1.3> exec $aaa $b
/tmp/test

This is very good. Can you include an example to open more than one session (e.g. 3 telnet sessions) _simultanesously_ and send/receive text with each session?

hi,
I need 1 help.
I want to search file with current date and with perticular pattern containing some data ie,greter than 0 bytes.and then paste the content of that file. myfile=$(sed -n ‘4,$p’ /tmp/vij/auto/batch_cd.txt) for each in `find /opt/sploutput/RMBP5UAT -mtime 1`
do #echo $each if read each (find . name *$myfile*_*stderr* – size +0c 2>/dev/null)
then
echo “no any log file generated”
ls -lrt
fi
done

Источник

Читайте также:  Linux base files package
Оцените статью
Adblock
detector