【问题标题】:perl scipt:syntax error of unexpected token while spawing bash command using expect moduleperl scipt:使用 expect 模块生成 bash 命令时出现意外令牌的语法错误
【发布时间】:2014-03-04 11:27:06
【问题描述】:

我正在编写 perl 脚本来将目录复制到远程机器。 我正在使用一个期望模块来接收密码并发送密码。

但出现如下语法错误

sh: -c: line 0: 意外标记附近的语法错误scp'
sh: -c: line 0:
system(scp -r /home/user1/data/192.168.0.1:/tmp/)'

perl 脚本是:

use Expect;  
$Expect::Debug=2;

$cmd="scp -r /home/user1/data/ 192.168.0.1:/tmp/";

my $exp1=Expect-> spawn("system($cmd)") or die print "cannot spwan process\n";


$exp1-> expect(10,["root@192.168.0.1's password: "=>sub{ $exp1-> send("usr1234\r");}]);

提前谢谢你

【问题讨论】:

  • 你不想要spawn($cmd) 而不是spawn("system($cmd)") 吗?
  • spawn($cmd) 没有给出错误..
  • 只要我执行这个脚本并设置一个调试 root@192.168.0.1 的密码:等待新数据(10 秒)...正在出现 ..此时它没有获取任何数据......所以密码不会发送......你能帮我解决这个问题......leeduhem
  • 错误没有再次出现,但是现在无法发送密码..因为它应该期待的字符串甚至在它开始期待之前就已经出现了......
  • 这不应该发生。如果输出出现在控制台上,这通常意味着 Expect 已完成。例如,如果对象被破坏或您明确清空句柄。我会假设它会立即匹配,但您的子无法执行您想要的操作。

标签: perl expect


【解决方案1】:

spawn 需要一个 shell 命令,而不是 Perl 代码。所以:

my $exp1=Expect-> spawn($cmd)) or die;

您看到的错误消息只是您的 shell 说它不知道如何处理 'system(scp...'。

并且:您需要屏蔽“@”。

【讨论】:

    【解决方案2】:

    我不完全确定你的脚本出了什么问题(当然是 spawn(system($cmd)) 的执行,但这已经在 cmets 中解决了。也许 => 不需要?或者你需要结束密码\n 而不是 \r?不管怎样,这很简单。我使用了类似下面的东西来达到很好的效果(注意 $rsync 是我的 Expect 对象)。

        $rsync=Expect->spawn ("rsync $remUser\@$remIp:$remFiles $locFolder");
    
        if (! defined($rsync))
        {
            die "spawning failed. Probably fork failed: $!";
        }
    
        my $matchStatus = $rsync->expect(100, '-re', '(.+)');
    
        if (! defined $matchStatus)
        {
            die "Nothing got returned within 100 seconds. $!";
        }
    
        my $spawned = 0;
        while ($spawned eq 0)
        {
            my $return = $rsync->match();
    
            if ($return =~ m/command not found/)
            {
                die "Command not found, there appears to be no rsync... $!";
            }
            elsif ($return =~ m/RSA key fingerprint is/)
            {
                $rsync->send ("yes\n");
                sleep(5);
            }
            elsif ($return =~ m/password/)
            {
                $rsync->send($password,"\n");
                $spawned = 1;
            }
            else 
            {
                print "rsync answered:\n\n";
                print "$return \n";
                print "I did not expect that. EXIT\n";
                exit(1);
            }
        }
    
    print "Sent Pw...\n";
    

    这可以处理更多不同的答案,并且可以更轻松地进行修改和调试。但显然要长得多。不过,我更喜欢明确而不是优雅。

    【讨论】:

    • 我认为问题在于生成“scp -r /home/data/ 192.168.0.1:/tmp/”而不是发送密码.....srcipt 能够发送密码,但它是不将目录复制到远程系统..任何人都可以帮我解决这个问题
    • 谁能区分 spawn($cmd) 和 spawn("system($cmd)") ,这是讨论的第一点
    • @ar777:基本上spawn() 需要一个shell 命令,而system($cmd) 是一个perl 命令。你不会在你的shell上写system(scp bla bla),所以当spawn()试图这样做时它没有多大意义。另外我现在相信您的第二个问题可能是密码后的\r 而不是\n。如果答案确实对您有所帮助,那么接受并可能投票会很高兴。
    • :实际上\n或\r产生相同的结果,正在发送密码但目录没有复制
    • @ar777:如果发送了密码但未复制目录,则说明您的目录有问题或需要其他输入。您是否也尝试删除命令中的=>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多