Вопрос или проблема
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, вы сможете найти подходящий инструмент для решения вашей задачи по синхронизации файлов.