Linux 将Perl中的expect与system()一起使用

Linux 将Perl中的expect与system()一起使用,linux,perl,bash,centos,expect,Linux,Perl,Bash,Centos,Expect,我试图在Perl脚本中使用expect系统调用在远程服务器上递归创建目录。有关电话如下: 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\"}; exp

我试图在Perl脚本中使用
expect
系统调用在远程服务器上递归创建目录。有关电话如下:

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;'");

这个很好用。但是,如果是第一次使用
ssh
访问远程机器,它会要求
(是/否)
确认。我不知道在上面的声明中该在哪里补充这一点。是否有办法将其合并到上述语句中(使用某种
-ing)?

yes/no
匹配添加到与密码匹配相同的
expect
调用中:

expect '*yes/no*' {send "yes\r"; exp_continue;} '*?assword:*' {send \"$password\r\"};
如果遇到
yes/no
exp\u continue
告诉expect继续查找密码提示,则将查找两个匹配项

完整示例:

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;'} );
我也曾经避免逃避所有的引用。从带有
-d
标志的shell运行此命令将显示expect正在查找以下任一匹配项:

Password: 
expect: does "...\r\n\r\nPassword: " (spawn_id exp4) match glob pattern
    "*yes/no*"? no
    "*?assword:*"? yes
yes/no
提示下:

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 }

你不必要地使你的生活复杂化了

如果您想从Perl获得类似expect的功能,只需使用模块即可

如果您想通过SSH与某个远程服务器交互,请使用CPAN中提供的一些SSH模块:

如果不想确认远程主机密钥,请将选项
strichhostkeychecking=no
传递给
ssh

例如:

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;