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

问题描述 投票:2回答:2

以前我在这里问过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";
    }
}
linux perl ssh
2个回答
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很安静,并且它返回成功,这也违背了[ ]的目的(如果那是意图)。但实际的错误 - 存在该名称的文件,路径上没有权限等 - 确实会回到脚本,如你所愿,并且带有错误消息的字符串在$!中,所以请测试为了这。

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

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

对于下一步,我建议查看(准备和)运行外部命令的模块,这比nazxswpoi更有帮助。

一些,从简单到更有能力:systemIPC::System::SimpleCapture::TinyIPC::Run3。另请参阅IPC::Run,准备命令并避免引用问题,shell注入错误和其他问题。最近的String::ShellQuote有一些例子;寻找更多。


2
投票

我建议使用适当的模块进行SSH,即post,一个基于OpenSSH的SSH客户端。

虽然在纯Perl中实现,但它快速而稳定,并且没有强制依赖性(当然,OpenSSH二进制文件除外)。 Net::OpenSSH,它会在某些条件下自动引用命令列表中的任何shell元字符。

以下代码演示了它如何响应您的用例。它依赖于@zdim解释的相同快捷方式,使用As explained in the docs

  • 如果目录不存在,则会创建该目录(如果失败,则会发生错误)
  • 如果已经存在,则没有任何反应
  • 如果存在具有目标名称的文件,则会发生错误

代码:

mkdir -p
© www.soinside.com 2019 - 2024. All rights reserved.