I'm trying to automate the process of adding ufw rules on multiple servers. I use an expect script to run commands on multiple remote servers and I would like to get the IP of the server that is in a specific range.
the servers are on the ovh public cloud and therefore they have a public IP and a private IP. I would like to allow access to some ports on the private IP. The expect script looks like this :
#!/usr/bin/expect
#grab the user
send_user "user: "
expect_user -re "(.*)\n"
set user $expect_out(1,string)
# grab the password
stty -echo
send_user -- "Password for $user: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)
for {set i 1} {$i < 10} {incr i 1} {
spawn ssh -t [email protected].$i "sudo ufw allow from X.X.X.X to $(ip a |grep '192.168.1' | grep -Po 'inet \K\[\d.\] ') port YYYY"
set timeout 5
expect {
timeout {
puts "Connection timed out"
exit 1
}
"yes/no" {
send "yes\r"
exp_continue
}
"assword:" {
send -- "$pass\r"
exp_continue
}
" $user:" {
send -- "$pass\r"
exp_continue
}
}
}
I'm getting the following error when running the script :
can't read "(ip a |grep '192.168.1' | grep -Po 'inet K[d.] ')": no such variable
Is there a way to do what I'm trying to achieve ?
CodePudding user response:
Expect uses the tcl language. In Tcl $(ip a | grep ...)
is a valid expression though it's not defined in your code.
You can \-escape the $
char or use { ... }
.
$ tclsh
% set "(ip a | grep ...)" "hello world"
hello world
% puts "$(ip a | grep ...)"
hello world
% puts "\$(ip a | grep ...)"
$(ip a | grep ...)
% puts {$(ip a | grep ...)}
$(a var)
%