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

zpf6vheq  于 2022-11-02  发布在  Linux
关注(0)|答案(2)|浏览(166)

Previously I have asked a question here on how to determine whether a path is a directory or not in remote site using SSH. I wish to create the directory if the path is not a directory. I have tried following code with two ways but it seem not to be working. Thanks for everyone that helps here.

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";
    }
}
bhmjp9jg

bhmjp9jg1#

括号,单个[或一对[ ],是内置的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是安静的,并且它返回succes,这也违背了[ ]的目的但是实际的错误--存在具有该名称的 file、对路径没有权限等--确实会返回到脚本,正如您所希望的,并且带有错误消息的字符串位于$!中,因此请对此进行测试。
如果你只是想知道这个目录是否存在,请放回测试分支,或者忽略-p,然后分析$!以确定系统上的消息是什么。
至于第二次尝试:要执行的命令在远程系统上运行,并且与此脚本不再有任何关系(除了插入的变量)。
下一步,我建议研究用于(准备和)运行外部命令的模块,这些模块比裸system更有帮助。
一些,从简单到更强大:IPC::System::SimpleCapture::TinyIPC::Run3IPC::Run。另请参阅String::ShellQuote,以准备命令并避免引用问题、shell注入错误和其他问题。最近的post就是一个很好的例子,还有很多其他的例子。

50pmv0ei

50pmv0ei2#

我建议使用一个合适的模块来执行SSH,即Net::OpenSSH,它是一个基于OpenSSH的SSH客户端。
虽然是在纯Perl中实现的,但是它快速而稳定,并且没有强制性的依赖关系(当然,OpenSSH二进制文件除外)。正如文档中所解释的,在某些情况下,它会自动引用命令列表中的任何shell元字符。
下面的代码演示了它如何响应您的用例。它依赖于@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;

相关问题