Powershell с Robocopy (или как # $ (*&передать аргументы правильно?)
Я пытаюсь написать сценарий, который использует robocopy. Если бы я просто делал это вручную, моя команда была бы:
robocopy c:holdtest1 c:holdtest2 тест.txt /NJH / NJS
но, когда я делаю это из powershell, например:
$source = "C:holdfirst test"
$destination = "C:holdsecond test"
$robocopyOptions = " /NJH /NJS "
$fileList = "test.txt"
robocopy $source $destination $fileLIst $robocopyOptions
Я:
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Fri Apr 10 09:20:03 2015
Source - C:holdfirst test
Dest - C:holdsecond test
Files : test.txt
Options : /COPY:DAT /R:1000000 /W:30
------------------------------------------------------------------------------
ERROR : Invalid Parameter #4 : " /NJH /NJS "
однако, если я изменю команду robocopy на
robocopy $source $destination $fileLIst /NJH /NJS
все успешно работает.
Итак, мой вопрос в том, как я могу передать строку в качестве моей robocopy параметры команды (и, в более широком смысле, сделайте то же самое для любой данной внешней команды)
3 ответов
Start robocopy -args "$source $destination $fileLIst $robocopyOptions"
илиrobocopy $source $destination $fileLIst $robocopyOptions.split(' ')
вы не можете использовать строку для передачи параметров таким образом, потому что когда вы пишете
robocopy $source $destination $fileList $robocopyOptions
PowerShell оценит последнюю переменную ($robocopyOptions
) как одна строка, и она будет цитировать ее. Это означает, что robocopy получит "/NJH /NHS"
(одна строка, в кавычках) в командной строке. (Очевидно, не намерение.)
подробнее о том, как обойти эти вопросы, см. здесь:
http://windowsitpro.com/powershell/running-executables-powershell
статья включает в себя следующую функцию:
function Start-Executable {
param(
[String] $FilePath,
[String[]] $ArgumentList
)
$OFS = " "
$process = New-Object System.Diagnostics.Process
$process.StartInfo.FileName = $FilePath
$process.StartInfo.Arguments = $ArgumentList
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.RedirectStandardOutput = $true
if ( $process.Start() ) {
$output = $process.StandardOutput.ReadToEnd() `
-replace "\r\n$",""
if ( $output ) {
if ( $output.Contains("`r`n") ) {
$output -split "`r`n"
}
elseif ( $output.Contains("`n") ) {
$output -split "`n"
}
else {
$output
}
}
$process.WaitForExit()
& "$Env:SystemRoot\system32\cmd.exe" `
/c exit $process.ExitCode
}
}
эта функция позволит вам запустить исполняемый файл в текущем окне консоли, а также создать массив строковых параметров для его передачи.
поэтому в вашем случае вы можете использовать эту функцию примерно так:
Start-Executable robocopy.exe $source,$destination,$fileList,$robocopyOptions
используй массивы, Люк. Если указать массив значений, PowerShell автоматически развернет их в отдельные параметры. По моему опыту, это самый надежный способ. И это не требует от вас возиться с Start-Process
командлет, который, на мой взгляд, является излишним для таких задач.
этот трюк из лучшей статьи, которую я видел в поведении PowerShell по отношению к внешним исполняемым файлам:PowerShell и внешние команды сделал право.
пример:
$source = 'C:\hold\first test'
$destination = 'C:\hold\second test'
$robocopyOptions = @('/NJH', '/NJS')
$fileList = 'test.txt'
$CmdLine = @($source, $destination, $fileList) + $robocopyOptions
& 'robocopy.exe' $CmdLine