SSH使用Perl脚本在远程站点中创建目录

时间:2018-12-20 23:40:34

标签: linux perl ssh

以前,我在这里询问过question,以了解如何使用SSH确定路径是否为远程站点中的目录。如果路径不是目录,则希望创建目录。我尝试用两种方法遵循代码,但似乎无法正常工作。谢谢大家的帮助。

use File::Path;

my $destination_path = "<path>";
my $ssh = "usr/bin/ssh";
my $user_id = getpwuid( $< );
my $site = "<site_name>";
my $host = "rsync.$site.com";

if (system("$ssh $user_id\@$host [ -d $destination_path ]") == 0) {
    print "It is a directory.\n";   

} else {
    print "It is not a directory.\n";

    #First Way
    if(system("$ssh $user_id\@$host [ make_path ($d_path_full) ]") == 0{

    #Second Way
    if(system("$ssh $user_id\@$host [ mkdir -p $d_path_full ]") == 0{
       print "Create directory successfully.\n";

    } else {
       print "Create directory fail.\n";
    }
}

2 个答案:

答案 0 :(得分:4)

括号(单个[或成对[ ])内置于bash中,它是一个测试运算符(请参见man test),最后一个使用它是不正确的。但是您不需要它来建立目录

use warnings;
use strict;
use feature 'say';

my $ssh = '/usr/bin/ssh';

my $user_id = ...
my $host    = ...

my $to = quotemeta $user_id.'@'.$host;

my $cmd = 'mkdir -p TEST_MKDIR_OVER_SSH';

system("$ssh $to $cmd") == 0  or die "Can't mkdir: $!";

如果目录已经存在,则mkdir-p保持安静,并且它返回成功,这也违反了[ ]的目的(如果这样做是故意的)。但是实际的错误-存在具有该名称的 file ,路径上没有权限等-确实可以根据需要返回脚本,并且包含错​​误的字符串消息位于$!中,因此请对此进行测试。

如果您只是想知道目录是否存在,请放回您的测试分支,或者只是忽略-p并分析$!,以了解系统中的消息内容。

对于第二次尝试:要执行的命令在远程系统上运行,并且与该脚本无关(除了插值变量)。因此,该命令中的Perl函数或库对该命令毫无意义。

对于下一步,我建议研究用于(准备和)运行外部命令的模块,它们比简单的system有用。

从简单到功能更强大的一些产品:IPC::System::SimpleCapture::TinyIPC::Run3IPC::Run。另请参见String::ShellQuote,以准备命令并避免引用问题,shell注入错误以及其他问题。最近的post提供了其中一些示例;搜索更多。

答案 1 :(得分:2)

我建议使用适当的模块来执行SSH,即Net::OpenSSH,这是基于OpenSSH构建的SSH客户端。

虽然在纯Perl中实现,但它快速且稳定,并且没有强制性的依赖关系(当然,还包括OpenSSH二进制文件)。 As explained in the docs,在某些情况下,它将自动在命令列表中引用任何外壳程序元字符。

以下代码演示了它如何响应您的用例。它依赖于@zdim使用mkdir -p解释的相同快捷方式:

  • 如果目录不存在,则会创建该目录(如果失败,则会发生错误)
  • 如果它已经存在,什么也不会发生
  • 如果目标名称存在文件,则会发生错误

代码:

use warnings;
use strict;
use Net::OpenSSH;

my $host = ...;
my $user_id = ...;
my $destination_path = ...;

# connect
my $ssh = Net::OpenSSH->new($host, user => $user_id);
$ssh->error and die "Can't ssh to $host: " . $ssh->error;

# try to create the directory
if ( $ssh->system('mkdir', '-p', $destination_path) ) {
    print "dir created !\n";
} else {
   print "can't mkdir $dir on $host : " . $ssh->error . "\n";
}

# disconnect
undef $ssh;