Есть ли эквивалент rsync в PowerShell?

Вопрос или проблема

Rsync очень полезен, мне не нужно копировать все файлы в директории. Он обновляет только более новые файлы.

Я использую его с Cygwin, но я думаю, что есть некоторые несоответствия, которые не являются основной темой этого вопроса.

Так есть ли аналог?

Хотя это не точный аналог и не функция PowerShell, robocopy может выполнять некоторые из задач, для которых используется rsync.

Смотрите также https://serverfault.com/q/129098

Это работает для синхронизации директорий. Вызовите функцию “rsync”. У меня были проблемы с правами доступа с robocopy. У этой проблемы нет.

function rsync ($source,$target) {

  $sourceFiles = Get-ChildItem -Path $source -Recurse
  $targetFiles = Get-ChildItem -Path $target -Recurse

  if ($debug -eq $true) {
    Write-Output "Source=$source, Target=$target"
    Write-Output "sourcefiles = $sourceFiles TargetFiles = $targetFiles"
  }
  <#
  1=односторонняя синхронизация, 2=двусторонняя синхронизация.
  #>
  $syncMode = 1

  if ($sourceFiles -eq $null -or $targetFiles -eq $null) {
    Write-Host "Обнаружена пустая директория. Пропуск копирования файла."
  } else
  {
    $diff = Compare-Object -ReferenceObject $sourceFiles -DifferenceObject $targetFiles

    foreach ($f in $diff) {
      if ($f.SideIndicator -eq "<=") {
        $fullSourceObject = $f.InputObject.FullName
        $fullTargetObject = $f.InputObject.FullName.Replace($source,$target)

        Write-Host "Попытка скопировать следующее: " $fullSourceObject
        Copy-Item -Path $fullSourceObject -Destination $fullTargetObject
      }


      if ($f.SideIndicator -eq "=>" -and $syncMode -eq 2) {
        $fullSourceObject = $f.InputObject.FullName
        $fullTargetObject = $f.InputObject.FullName.Replace($target,$source)

        Write-Host "Попытка скопировать следующее: " $fullSourceObject
        Copy-Item -Path $fullSourceObject -Destination $fullTargetObject
      }

    }
  }
}

Спасибо за ваш скрипт rsync. Я обновляю его, добавляя третью опцию для удаления файлов, которых нет в исходной директории.

function rsync  {
param ( $source,
        $target 
      )

$WorkDir=Get-Location
Write-Output "PATH PWD:   $WorkDir"
Write-Host "SOURCE: $source"
Write-Host "TARGET: $target"

$sourceFiles = Get-ChildItem -Path $source -Recurse
$targetFiles = Get-ChildItem -Path $target -Recurse

Write-Host "SOURCEFILES $sourceFiles"
Write-Host "TARGETFILES: $targetFiles"


if ($debug -eq $true) {
  Write-Output "Source=$source, Target=$target"
  Write-Output "sourcefiles = $sourceFiles TargetFiles = $targetFiles"
}
<#
1=односторонняя синхронизация, 2=двусторонняя синхронизация, 3=одностороннее удаление файлов из целевой директории, которые не равны исходным файлам
#>
$syncMode = 3

#if ($sourceFiles -eq $null -or $targetFiles -eq $null) {
    if ($targetFiles -eq $null)
    {
        $targetFiles=""
    }

if ($sourceFiles -eq $null){
  Write-Host "Обнаружена пустая директория. Пропуск копирования файла."
} else
{
  $diff_command="Compare-Object -ReferenceObject $sourceFiles -DifferenceObject $targetFiles"
  Write-Host "команда разности: $diff_command"

  $diff = Compare-Object -ReferenceObject $sourceFiles -DifferenceObject $targetFiles
  Write-Host "---> Разные файлы из SOURCE в TARGET: $diff"

  #$diff_target = Compare-Object -ReferenceObject $targetFiles  -DifferenceObject  $sourceFiles
  #Write-Host "---> Разные файлы из TARGET в SOURCE: $diff_target"

  foreach ($f in $diff) {
    Write-Host "--> Индикатор: $f.SideIndicator "
    if ($f.SideIndicator -eq "<=") {
      $fullSourceObject = $f.InputObject.FullName
      $fullTargetObject = $f.InputObject.FullName.Replace($source,$target)

      Write-Host "Попытка скопировать следующее <= SourceTarget: " $fullSourceObject
      Copy-Item -Path $fullSourceObject -Destination $fullTargetObject
    }


    if ($f.SideIndicator -eq "=>" -and $syncMode -eq 2) {
      $fullSourceObject = $f.InputObject.FullName
      $fullTargetObject = $f.InputObject.FullName.Replace($target,$source)

      Write-Host "Попытка скопировать следующее => TargetSource: " $fullSourceObject
      Copy-Item -Path $fullSourceObject -Destination $fullTargetObject
    }

    if ($f.SideIndicator -eq "=>" -and $syncMode -eq 3 -and $targetFiles -ne "") {
        $fullSourceObject = $f.InputObject.FullName
        $fullTargetObject = $f.InputObject.FullName.Replace($target,$source)

        Write-Host "Удаление файлов из Target, которые отсутствуют в Source=> TargetSource: " $fullSourceObject
        Write-Host "Файлы, которых нет в источнике: $fullSourceObject"
        Remove-Item  $fullSourceObject 
      }

  }
}

}

##Вызов функции
rsync $SourcePathFull_Month_Day $DestinationPathFull_Month_Day

Ответ или решение

Вопрос об эквиваленте инструмента rsync в PowerShell часто возникает среди системных администраторов и ИТ-специалистов, работающих в среде Microsoft. rsync — это мощный инструмент, известный своей способностью синхронизировать файлы и каталоги между различными системами, обеспечивая высокую эффективность за счет копирования только тех файлов, которые были изменены.

Основные альтернативы для rsync в PowerShell

1. Robocopy

Хотя в PowerShell нет точного эквивалента rsync, утилита robocopy (Robust File Copy) может servir как альтернатива, предоставляя множество аналогичных функций, хотя и на более низком уровне. robocopy поддерживает:

  • Инкрементное копирование файлов (только измененные).
  • Возможность повторных попыток при сбоях.
  • Копирование файлов с учетом атрибутов и времени изменения.

Пример команды robocopy:

robocopy C:\Source D:\Destination /MIR

В данном примере ключ /MIR указывает на鏖истанный режим копирования, который синхронизирует содержимое каталогов, удаляя файлы в целевом каталоге, если они были удалены из исходного.

2. PowerShell Script

Еще одной альтернативой является использование пользовательских сценариев PowerShell для выполнения аналогичных задач, как это было показано в предоставленных кодах. Пример функции rsync написанной на PowerShell предлагает создание инкрементных резервных копий, а также возможность чистки целевого каталога от устаревших файлов. Ниже представлена модифицированная версия функции:

function rsync {
    param (
        [string]$source,
        [string]$target 
    )

    $sourceFiles = Get-ChildItem -Path $source -Recurse
    $targetFiles = Get-ChildItem -Path $target -Recurse

    $syncMode = 3 # 1 - односторонняя синхронизация, 2 - двусторонняя, 3 - очистка

    if ($targetFiles -eq $null) {
        $targetFiles = ""
    }

    if ($sourceFiles -eq $null) {
        Write-Host "Пустой каталог, пропускаем копирование."
    }
    else {
        $diff = Compare-Object -ReferenceObject $sourceFiles -DifferenceObject $targetFiles

        foreach ($f in $diff) {
            if ($f.SideIndicator -eq "<=") {
                $fullSourceObject = $f.InputObject.FullName
                $fullTargetObject = $fullSourceObject.Replace($source, $target)

                Write-Host "Копируем файл: $fullSourceObject"
                Copy-Item -Path $fullSourceObject -Destination $fullTargetObject
            }

            if ($f.SideIndicator -eq "=>" -and $syncMode -eq 3) {
                $fullTargetObject = $f.InputObject.FullName
                Write-Host "Удаляем файл из целевого каталога: $fullTargetObject"
                Remove-Item $fullTargetObject -Force
            }
        }
    }
}

Заключение

Несмотря на то, что robocopy и пользовательские сценарии PowerShell не完全 заменяют функциональность rsync, они способны эффективно выполнять задачи синхронизации данных в среде Windows. Использование robocopy рекомендуется для более надежных и безопасных переноса файлов, в то время как создание собственных PowerShell-скриптов может предоставить вам большую гибкость и контроль.

Выбор между robocopy и пользовательским скриптом будет зависеть от ваших конкретных требований и предпочтений. Но в любом случае, учитывая богатый инструментарий PowerShell и утилитов командной строки Windows, вы сможете найти подходящий инструмент для решения вашей задачи по синхронизации файлов.

Оцените материал
Добавить комментарий

Капча загружается...