Мне очень сложно понять, что PS пытается мне сказать. Я создал сценарий, предназначенный для сравнения файлов в двух каталогах. Я хочу вывести любые различия в имени, количестве файлов или длине в любом каталоге. В конце концов, я бы хотел, чтобы он ошибался, если есть различия. Вот что у меня есть:
Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin"
$bin_src = Get-ChildItem $deploy_src
$bin_dst = Get-ChildItem $deploy_dst
if (Compare-Object $bin_src.Name $bin_dst.Name) {
# throw "Directories differ"
}
И вот (менее чем полезный) результат, который я вижу:
02/24/2020 09:57:36 - Comparing J:\AdvantageProxy\Development\bin J:\AdvantageProxy\Deploy-QA-2020-02-21\bin
02/24/2020 09:57:36 - done.
Name Length SideIndicator
---- ------ -------------
38 =>
20 <=
Обновление: файлы находятся в общей папке FSx, доступной для Mac. Это то, что выводится для diff, который показывает только .DS_Store в каталоге, доступ к которому осуществляется напрямую с Mac:
$ rsync -n -a -i --delete /Volumes/share/AdvantageProxy/Development/bin/. /Volumes/share/AdvantageProxy/Deploy-QA-2020-02-21/bin/.
*deleting .DS_Store
.d..t....... ./
.d..t....... de/
.d..t....... es/
.d..t....... ja/
.d..t....... ru/
(Я использовал rsync, чтобы не тратить время на сравнение содержимого файлов. ... Это показывает, что в $ deploy_dst \ bin есть файл, которого нет в $ deploy_src \ bin, и отметки времени на несколько папок отличается. Я ожидаю увидеть нечто подобное с решением Powershell.)
Также обратите внимание - я стараюсь по возможности избегать установки дополнительных зависимостей, поэтому я пытаюсь сделать это через PS.
В итоге я создал собственное решение. Соответствующие его части выглядят так:
function Compare_Directory
{
[CmdletBinding()]
Param(
[string]
[Parameter(Mandatory=$true)]
$src_dir,
[Parameter(Mandatory=$true)]
[string]
$dest_dir
)
Write-Host "$(Get-Date) - Diffing files in $src_dir to $dest_dir (will only report differences)"
# Get .FullName to avoid issues with string replace not matching FullName to non-full file names (ie, paths using PSdrives)
$src_str = (Get-Item $src_dir).FullName
$dest_str = (Get-Item $dest_dir).FullName
if ($verbose>1){
Write-Host "$(Get-Date) - $src_str -> $dest_str"
}
# Get all files under $folder1, filter out directories
$src_files = Get-ChildItem $src_dir -force | Where-Object { -not $_.PsIsContainer } # -Recurse
# -force will pick up dotfiles (or windowspeak, files with the hidden attribute set)
$i=0
$mismatches=0
$src_files | ForEach-Object {
$src_fl = (Get-Item $_.FullName -force)
$dest_flnm = $_.FullName.replace($src_str, $dest_str)
$dest_fl = (Get-Item $dest_flnm -force)
# Currently, this will cause an error if a file exists in src directory but not dest directory
# I don't know how to write this so that it can error more than once depending on verbosity
# like the rest of the script and it's not a priority for me.
if ($verbose>1){
Write-Host "$src_fl ?? $dest_fl"
}
If ( Compare-Object $src_fl $dest_fl -Property Name, Length ) {
# List files not matching
Write-Host "src- $src_fl"
Write-Host "dest- $dest_fl"
# if verbosity <0, fail fast, otherwise provide maximum insight (logging)
if ($verbose -lt 0){
throw "Verbosity set to intolerant; First mismatch found- $src_fl"
}
else{
$mismatches+=1
}
}
}
Write-Host "$i files compared"
if ($mismatches -gt 0){
throw "Mismatching files found: $mismatches"
}
}
# Diff directories in both directions to identify differences in file names
Write-host "$(Get-Date) - Comparing $backup_src and $deploy_dst (->)"
Compare_Directory $backup_src $deploy_dst
Write-host "$(Get-Date) - Comparing $backup_src and $deploy_dst (<-)"
Compare_Directory $deploy_dst $backup_src
Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin (->)"
Compare_Directory $deploy_src\bin $deploy_dst\bin
Write-host "$(Get-Date) - Comparing $deploy_src\bin $deploy_dst\bin (->)"
Compare_Directory $deploy_dst\bin $deploy_src\bin