غير قادر على حذف دليل به أقواس مربعة في الاسم باستخدام WinSCP وPowerShell
-
21-12-2019 - |
سؤال
أحاول كتابة برنامج PowerShell النصي الذي يحذف تلقائيًا الدلائل الفارغة على خادم FTP الخاص بنا.ليس لدي أي وصول مباشر إلى الخادم الذي توجد عليه الدلائل - لا يمكنني الوصول إليها إلا عبر FTP.لهذا السبب، قمت بكتابة برنامج PowerShell النصي الذي يستخدم مجموعة WinSCP .NET لـ (محاولة) حذف الدلائل الفارغة.ومع ذلك، لدي مشكلة، حيث أن العديد من الدلائل الموجودة على الخادم تحتوي على أقواس مربعة في اسم الدليل.
على سبيل المثال، يمكن استدعاء اسم الدليل: [a]153432
هناك الكثير من هذه الأدلة، ومن هنا رغبتي في كتابة برنامج نصي لحذفها.يحدث هذا لأنه تم إنشاؤها بواسطة برنامج يستخدم رقمًا لإنشاء الدلائل التي يتطلبها.من أجل العمل على هذا البرنامج، قمت بإنشاء دليل فارغ
/latest/[b]test
برنامجي يذهب مثل هذا:
# program to test deletion of directories with square-brackets in the name.
$HOSTNAME="myftpservername"
$USERNAME="myftpusername"
$PASSWORD="myftppassword"
$DLL_LOCATION="C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$LOCAL_DIRECTORY="C:\testdir\extended\baseroot"
# Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom($DLL_LOCATION) | Out-Null
# Session.FileTransferred event handler
try
{
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::ftp
$sessionOptions.HostName = $HOSTNAME
$sessionOptions.UserName = $USERNAME
$sessionOptions.Password = $PASSWORD
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
$remoteFileWithUnixPath = "/latest/[b]test"
$removalResult = $session.RemoveFiles($remoteFileWithUnixPath)
if ($removalResult.IsSuccess)
{
Write-Host ("Removal of remote file {0} succeeded" -f $remoteFileWithUnixPath)
}
else
{
Write-Host ("Removal of remote file {0} failed" -f $remoteFileWithUnixPath)
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
catch [Exception]
{
Write-Host $_.Exception.Message
exit 1
}
وعندما أقوم بتشغيله تظهر الرسالة التالية:
PS C:\Users\dbuddrige\Documents\dps> .\delete-squarebracket-dir.ps1
Removal of remote file /latest/[b]test succeeded
ومع ذلك، لا يتم حذف الدليل.
لقد حاولت أيضًا تحديد اسم الدليل بمحددات مثل:
$remoteFileWithUnixPath = "/latest/\[b\]test"
لكن هذا فشل أيضًا (لكنه على الأقل يقول ذلك):
PS C:\Users\dbuddrige\Documents\dps> .\delete-squarebracket-dir.ps1
Removal of remote file /latest/\[b\]test failed
ولكن، إذا قمت بتغيير اسم الدليل [والمتغير $remoteFileWithUnixPath
] إلى شيء من هذا القبيل
/latest/foo
ومن ثم إعادة تشغيل البرنامج، فإنه يحذف الدليل /latest/foo
بخير.
هل لدى أي شخص أي أفكار عما يجب علي فعله حتى ينجح هذا؟
تمت الإشارة إلى الإجابة على هذا السؤال بواسطة مارتن بريكريل [شكرًا!]
رمز العمل الكامل يلي:
# program to test deletion of directories with square-brackets in the name.
$HOSTNAME="myftpservername"
$USERNAME="myftpusername"
$PASSWORD="myftppassword"
$DLL_LOCATION="C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$LOCAL_DIRECTORY="C:\testdir\extended\baseroot"
# Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom($DLL_LOCATION) | Out-Null
# Session.FileTransferred event handler
try
{
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::ftp
$sessionOptions.HostName = $HOSTNAME
$sessionOptions.UserName = $USERNAME
$sessionOptions.Password = $PASSWORD
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
$remoteFileWithUnixPath = "/latest/[b]test"
$removalResult =
$session.RemoveFiles($session.EscapeFileMask($remoteFileWithUnixPath))
if ($removalResult.IsSuccess)
{
Write-Host ("Removal of remote file {0} succeeded" -f $remoteFileWithUnixPath)
}
else
{
Write-Host ("Removal of remote file {0} failed" -f $remoteFileWithUnixPath)
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
catch [Exception]
{
Write-Host $_.Exception.Message
exit 1
}
المحلول
بعض أساليب تجميع WinSCP .NET، بما في ذلك Session.RemoveFiles
, ، اقبل قناع ملف، وليس مسارًا بسيطًا.
الأقواس المربعة لها معنى خاص في قناع الملف.
يجب عليك دائمًا استخدام RemotePath.EscapeFileMask
طريقة على مسارات الملفات، قبل تمريرها إلى أساليب التجميع.
نصائح أخرى
سأستخدم تسلسل الهروب في سطر الأوامر:
Remove-Item 'C:\Scripts\Test`[1`].txt'
أو استخدم -LiteralPath
معامل.
Remove-Item -LiteralPath C:\scripts\test[1].txt
لا تحاول المعلمة -LiteralPath تحويل السلسلة.