I am trying to use expect
using system calls in a Perl script to recursively create directories on a remote server. The relevant call is as follows:
system("expect -c 'spawn ssh $username\@$ip; expect '*?assword:*' {send \"$password\r\"}; expect '*?*' {send \"mkdir -p ~/$remote_start_folder/$remote_folder_name/$remote_username/$remote_date/\r\"}; expect '*?*' {send \"exit\r\"}; interact;'");
This works fine. However, if it is the first time that the remote amchine is accessed using ssh
, it asks for a (yes/no)
confirmation. I don't know where to add that in the above statement. Is there a way to incorporate it into the above statement(using some sort of or
-ing)?
Add a yes/no
match to the same invocation of expect
as the password match:
expect '*yes/no*' {send "yes\r"; exp_continue;} '*?assword:*' {send \"$password\r\"};
This will look for both matches, if yes/no
is encountered exp_continue
tells expect to keep looking for the password prompt.
Full example:
system( qq{expect -c 'spawn ssh $username\@$ip; expect '*yes/no*' {send "yes\r"; exp_continue;} '*?assword:*' {send "$password\r"}; expect '*?*' {send "mkdir -p ~/$remote_start_folder/$remote_folder_name/$remote_username/$remote_date/\r"}; expect '*?*' {send "exit\r"}; interact;'} );
I've also used qq
to avoid having to escape all the quotation. Running this command from a shell with -d
flag shows expect looking for either match:
Password:
expect: does "...\r\n\r\nPassword: " (spawn_id exp4) match glob pattern
"*yes/no*"? no
"*?assword:*"? yes
With yes/no
prompt:
expect: does "...continue connecting (yes/no)? " (spawn_id exp4) match glob pattern
"*yes/no*"? yes
...
send: sending "yes\r" to { exp4 }
expect: continuing expect
...
expect: does "...\r\nPassword: " (spawn_id exp4) match glob pattern
"*yes/no*"? no
"*?assword:*"? yes
...
send: sending "password\r" to { exp4 }
You are complicating your life unnecessarily.
If you want expect-like functionality from Perl, just use the Expect module.
If you want to interact with some remote server via SSH, use some of the SSH modules available from CPAN: Net::OpenSSH , Net::SSH2 , Net::SSH::Any .
Pass the option StrictHostKeyChecking=no
to ssh
if you don't want to confirm the remote host key.
For instance:
use Net::OpenSSH;
my $ssh = Net::OpenSSH->new($ip, user => $username, password => $password,
master_opts => [-o => 'StrictHostKeyChecking=no']);
my $path = "~/$remote_start_folder/$remote_folder_name/$remote_username/$remote_date";
$ssh->system('mkdir -p $path')
or die "remote command failed: " . $ssh->error;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.