Войти

Показать полную графическую версию : [решено] Пути к файлам в Powershell 7


DJ Mogarych
05-03-2021, 21:03
Привет!

Почему-то в модном Пауэршелле не работают пути, которые забиты в переменную. Например:

Out-File:
Line |
3 | … coding UTF8 |Out-File "$path\$($_.basename).txt" -Encoding default
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Access to the path 'C:\Текст.txt' is denied.


В $path забито C:\temp\test, какого лешего он в C: пишет? Если вместо переменной вбить путь руками, работает нормально.

Такая же шляпа, если вызывать программу, например,

$prog = "C:\scripts\prog1\exec.exe"
& "$prog" parameters

, то также не работает.

Почему, кто знает? Какой теперь способ прописывания путей?

Foreigner
05-03-2021, 22:27
Access to the path 'C:\Текст.txt' is denied. »

У меня все работает, если хватает прав на запись. И вызов программы через переменную.

DJ Mogarych
05-03-2021, 22:34
Мне непонятно, почему он пишет в корень-то, когда в переменной другой путь.

А вызов программы выдаёт такое:

InvalidOperation:
Line |
2 | & "$prog" ".\$($_.name)" "$($_.basename)" -arg value
| ~~~~~~~~~~~~
| The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object.

Foreigner
05-03-2021, 23:08
[q=DJ Mogarych]А вызов программы выдаёт такое: »

Я не могу придумать подходящий пример с пайпом, чтобы напрямую без Foreach-Object. Такой работает:

$exe = "C:\Program Files\7-zip\7z.exe"
dir *.ps1 | % { & $exe a "$($_.basename).7z" "$($_.Name)" }

Fors1k
05-03-2021, 23:27
$prog = "C:\scripts\prog1\exec.exe"
& "$prog" parameters »
$arg = ni $env:TEMP\gg.txt -Value testString -Force
$prog = "C:\Windows\System32\notepad.exe"

& $prog $arg
Такой код сработает?

DJ Mogarych
06-03-2021, 09:25
Да, ваши примеры работают. Вот что у меня:


$tesseract = "C:\scripts\Tesseract\tesseract.exe"

PS C:\temp\ocr20210306092926> $images |ForEach-Object -Parallel {
>> & "$tesseract" ".\$($_.name)" "$($_.basename)" -l rus+eng
>> } -ThrottleLimit $threads

InvalidOperation:
Line |
2 | & "$tesseract" ".\$($_.name)" "$($_.basename)" -l rus+eng
| ~~~~~~~~~~~~
| The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object.
InvalidOperation:
Line |
2 | & "$tesseract" ".\$($_.name)" "$($_.basename)" -l rus+eng
| ~~~~~~~~~~~~
| The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script block, or a CommandInfo object.


Вместе с тем, объект-то есть.

PS C:\temp\ocr20210306092926> get-item $tesseract

Directory: C:\scripts\Tesseract

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 27.11.2020 20:33 665382 tesseract.exe


И если забить путь руками, то всё работает:

PS C:\temp\ocr20210306092926> $images |ForEach-Object -Parallel {
>> & "C:\scripts\Tesseract\tesseract.exe" ".\$($_.name)" "$($_.basename)" -l rus+eng
>> } -ThrottleLimit $threads
Tesseract Open Source OCR Engine v5.0.0-alpha.20201127 with Leptonica
Page 1
Tesseract Open Source OCR Engine v5.0.0-alpha.20201127 with Leptonica
Page 1
Tesseract Open Source OCR Engine v5.0.0-alpha.20201127 with Leptonica
Warning: Invalid resolution 0 dpi. Using 70 instead.
Estimating resolution as 146

YuS_2
06-03-2021, 10:14
Вот что у меня »
Здесь (https://docs.microsoft.com/ru-ru/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.1#call-operator-)

DJ Mogarych
06-03-2021, 10:25
YuS_2, это хорошо, но я всё равно не понял, в чём проблема, и почему это работало в PS 5.1.

Fors1k
06-03-2021, 12:09
ForEach-Object -Parallel »Ну теперь понятно. Почему сразу не выложить код?


Такие скриптблоки ничего не знают о переменных из внешней области.
$arg = ((ni $env:TEMP\gg.txt -Value testString -Force),
(ni $env:TEMP\gg1.txt -Value testString -Force))
$prog = "C:\Windows\System32\notepad.exe"

$arg|ForEach -parallel{& $using:prog $_}

YuS_2
06-03-2021, 19:01
почему это работало в PS 5.1 »
Да, именно так, как сказали выше, всё дело в параллельности, её не было у foreach-object в PS 5.1, параметр появился только с версии 7.0

Fors1k
06-03-2021, 19:21
А я вот не пойму что работало в 5.1, если такого кода там вообще не может быть))
В 5.1 есть конечно параллельность, но именно такой записи там нет.
как сказали выше »
Тот, кого нельзя называть))

YuS_2
06-03-2021, 20:21
В 5.1 есть конечно параллельность »
да, есть, но работает она только в workflow (и не так, не в foreach-object), которые исключили в версиях PS новее 5.1

Тот, кого нельзя называть)) »
тс-с-с, а то услышит! :)

DJ Mogarych
06-03-2021, 22:05
$using:prog »
Вот геморрой-то.

Используйте область $using: для передачи ссылок на переменные в выполняемый блок скрипта.

https://docs.microsoft.com/ru-ru/powershell/scripting/whats-new/what-s-new-in-powershell-70?view=powershell-7.1#parallel-execution-added-to-foreach-object

Спасибо!




© OSzone.net 2001-2012