Как стать автором
Обновить

Комментарии 53

Сравнивать PS с Питоном - очень странное занятие

  1. Здесь мне нечего сказать. Переменная есть? Есть. Значение в ней, как во многих языках программирования может быть стандартное (по умолчанию). Мы можем объявить строку и вывести её. Компилятор может даже не ругаться. А здесь переменная объявляется в момент её непосредственного вызова. PS. в js тогда вообще лучше не лезьте

  2. Тип "переменной" определяется содержимым файла! Вот и всё объяснение твоего недоумения. На питоне вы грузите содержимое совершенно иначе и если сделать так же на PS результат будет как и в питоне

  3. И не только файла, но и данными, полученными откуда-то ещё.

  4. А забрать значение из функции не пробовали? Ну там, в переменную и вывести потом? При чем тут результат функции, если вы просто выводите значение на экран?
    Аналогичный код на псевдо языке:

функция(text1, text2) {
  print(text1);
  return text2;
}

  1. Так оно и забирается в переменную $res

В PowerShell результаты каждой инструкции возвращаются в виде выходных данных, даже без оператора, содержащего ключевое слово Return.

https://learn.microsoft.com/ru-ru/powershell/module/microsoft.powershell.core/about/about_return?view=powershell-7.3

Стоит еще упомянуть, что просто так скрипт на Powershell вообще не запустишь, надо или прописывать какие-то непонятные заклинания в реестр, или ставить не менее непонятные ключи при вызове.

Кто мешает проставить их же злоумышленникам - вообще не понятно.

О чем именно речь? Всегда запускал скрипты без всяких проблем

Execution policy.

Одна строчка

Set-ExecutionPolicy Unrestricted

... и корпоративная безопасность после этого выходит из чата.

Т.е. я не могу написать код переименования файликов и распространить его между коллег. Мне надо пойти к безопасникам, долго и упорно просить выдать мне сертификат для подписи кода и, возможно, если соответствующая инфраструктура есть в организации, мне его дадут.

...или надо распространить код в текстовом виде и просить коллег сделать Ctrl+C, Ctrl+V в *.ps1.

По сравнению с bash'ем выглядит как создание проблем на ровном месте.

Если у вас "корпоративные безопасники" не понимают, что делают - вряд ли это проблема powershell.

Безопасники люди простые - чем меньше разрешено, тем меньше риски. Т.е. проблемы индейцев шерифа не волнуют. И вот дальше ваша задача объяснить что эта штука ооочень нужна, она безопасна и все такое прочее.

Странный наезд на безопасников. Нужно скрипт на куче машинок выполнить? Подпишите код. Примите политику выполнения "только подписанный код".

Это нормально.

А как же bat файлы? Из не надо подписывать)

Подписать можно только если есть соответствующая инфра, в остальном вас пошлют...

Надо отловить безопасника о объяснить что код безопасен и его можно выполнять, если человека (для этой задачи) нет, вас пошлют...

Выдавать вам сертификат которым можно подписать вообще любой код никто не будет, так что вы должны отправить код безопасникам, они подпишут и уже после этого его можно распространять подписанным. Ну или вам там CI\CD должны настроить.

Сравните, насколько это проблемнее, чем просить коллег сделать копипасту с текстового файла. И насколько это абсурдно для простого ps1 скрипта который переименовывает файлы определенным образом. И насколько это все еще становится абсурднее если у пользователя стоит какой-нибудь python.

В линуксе sh-ники существуют без всех этих проблем с подписями. Накидал код, он выполнится только в рамках текущих разрешений пользователя. Всё.

Если пользователь сидит как рядовой пользователь, а не локальный админ, то разницы Linux/Windows нет. Скрипт затронет только то, что можно пользователю. Без разницы, .bat/.cmd или .ps1

Запрет выполнения неподписанных скриптов скорее заточен на те, которые от имени системы, централизованно или удалённо пытаются выполнить.

Я не вижу, чем это хуже, чем бесконтрольно bash скрипты раздавать

У PS есть дополнительный по сравнению с bash функционал по ограничению исполнения скриптов. Вы его можете использовать, можете нет. Повесьте политику unrestricted на выполнение, и будет у вас ваше "без всех этих проблем с подписями. Накидал код, он выполнится только в рамках текущих разрешений пользователя."

Дополнительный функционал - преимущество, а не недостаток, ибо иметь выбор обычно лучше, чем не иметь. А если вашим выбором кто-то управляет за вас - это не недостаток продукта, а в чистом виде вопрос ваших взаимоотношений с этими людьми. У вас неквалифицированные безопасники? Это проблемы вашего предприятия, а не PS.

А если вашим выбором кто-то управляет за вас - это не недостаток продукта, а в чистом виде вопрос ваших взаимоотношений с этими людьми. У вас неквалифицированные безопасники? Это проблемы вашего предприятия, а не PS.

Из-за этой проблемы, из-за этой искусственно созданной на ровном месте проблемы, PS и не идет в массы. Люди продолжают пользоваться python\cmd\VBA(S\H) и пр.

А казалось бы сделали бы полиси по дефолту Unrestricted и было бы счастье

Set-ExecutionPolicy Unrestricted -Scope 'LocalUser'

У вас юзеры под локальными админами сидят? Дальше про безопасность можно не говорить.

В корпоративной среде для этого есть настройка политики глобально и подписание скрипта. Чтоб всякого рода Пети и Васи не могли их выполнять таки

Кто мешает проставить их же злоумышленникам — вообще не понятно.

Это защита от неопытного пользователя:
ExecutionPolicy is like a baby door. The ExecutionPolicy keeps babies safe but every grown-up surpasses it easily.
There are like over 20 ways to surpass the ExecutionPolicy even as a standard user.


надо или прописывать какие-то непонятные заклинания в реестр, или ставить не менее непонятные ключи при вызове.

  • Good God! — сказал Ойра-Ойра, протирая запорошенные глаза. — Canst thou not come in by usually way as decent people do? Sir… <Ужель обычный путь тебе заказан — путь достойного человека? Сэр… — (англ.)> — добавил он.

image

Зачем PowerShell сравнивать с Python с точки зрения функциональности? Это же совершенно разные инструменты...

Кстати, Python скрипт везде стартует быстрее. PowerShell тупит доли секунды. Обычно это неважно, но когда на любое действие GUI вызывается скрипт то разница чувствуется.

Да у меня на винде powershell.exe запускается долго и жрёт много памяти (по сравнению с bash). Что он там делает - без понятия. Загадка.

Тут надо версию powershell указать и антивирус, который каждый запуск powershell сканирует.

Powershell медленный.

Pwsh (core который) быстрый - на моём i7 загрузился, вместе с моим кастомным профилем с темой, модулями, функциями за 853 миллисекунды и кушает 30мб памяти. Без всех моих обвесов должно быть меньше.

А можно сравнить с Python? Спасибо

Для этого надо питон нативно в систему добавлять, мне боязно. Если таки решусь, то отпишусь.

Он у меня есть в контейнере и в WSL. Но через эти инструменты нормально загрузку терминала не проверить.

Поставил Python 3.11 из Microsoft Store и добавил его в профиль в Windows Terminal:

\AppData\Local\Microsoft\WindowsApps\python.exe

Он загружается тоже где-то за 10мс и кушает 8мб.

P.S. мне не кажется, что 0.8s это быстро

Убрал все мои обвесы и обе версии powershell загрузились за 10мс.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
C:\Program Files\WindowsApps\Microsoft.PowerShell_7.3.3.0_x64__8wekyb3d8bbwe\pwsh.exe

Старый powershell кушает 25мб памяти.

Новый pwsh кушает 16мб.

Ждём от вас ссылку на статью, в которой объясняется, как эти красивости сделать

Прочитал как "кривости" и минуту не мог понять, о каких кривостях речь.

Для красоты используется вот это https://ohmyposh.dev/

Для функционала вот эти модули:
https://github.com/PowerShell/PSReadLine
https://github.com/dahlbyk/posh-git

Прочие ссылки:

https://www.youtube.com/watch?v=n1sFkbPlDww
https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal

Автодополнение - крутая штука. Из истории по умолчанию и можно добавить разных умных дополнений с подсказками для git, docker, kubectl, az, aws, и прочее.

.
.

.

Вы не любите Powershell? Да вы просто не умееете его готовить! ;-)


Вам не нравится расхлябанность с неописанными переменными? Включите строгий режим (Set-StrictMode -Version Latest).
Вам не нравится, что Powershell по-разному работает с последовательностями из 0, 1 и нескольких элементов? Используйте операцию @(...)
Вам не нравится, что Powershell передает результаты функций через конвейер? Да, отучить его от этого нельзя — потому что он все-таки shell. Идеология у него такая. Но к этому можно приноровиться — просто привыкните сразу выбрасывать все лишнее: ставьте [Void] перед вызовами внешних команд, функций и в прочих местах, где значение результата надо проигнорировать.
И тогда вы наверняка перестанете бояться и полюбите Powershell. Потому что он позволяет ещё много чего. В частности — с легкостью пользоваться практически всей библиотекой времени выполнения .NET (мне, как человеку, хорошо знакомому с C#, это очень полезно).
PS Лично я полюбил Powershell, потому что много работал с MS Exchange, а там, начиная с Exch2K7, альтернатив просто не было.


PPS Вы, AFAIK давно работаете с MS SQL. Не поделетесь, чем вы пользовались для написания скриптов до появления в нем Powershell? vbscript/jscript+ADO? Или — isql/osql с последующим мучением разбора текстового вывода средствами cmd? Это я чисто для себя интересуюсь — потому что я в те давние времена этот вопрос для себя так и не решил.

Сейчас я использую PowerShell, потому что так принято в фирме, где сейчас работаю. Вроде 1000 строк, скоро будет статья)

Если бы было всё равно, то писал бы на Питоне

До PowerShell я все писал на SQL, вызовешь команду в xp_cmdshell и парзишь вывод там же)

Что вы ему пытаетесь доказать? :) Человек 3 строки на нем написал и сразу кинулся катать статью. Это же классика: если что-то не знаешь, то не надо гуглить и разбираться хоть в чем-то, а надо сразу катай статью!

Языки программирования РАЗНЫЕ. И особенности каждого из них надо изучать, а не пытаться действовать по кальке с другого языка. Описанные вами "неожиданности" PS либо прямо следуют из логики происходящего, либо просто явным образом описаны в документации (про ваш пример с return там вообще почти цитата в about_return есть).

Что до неявного преобразования типов - так в той области, где PS обычно используется, это однозначное благо, сильно упрощающее жизнь. А там, где оно вдруг работает не так, как ожидается, всегда можно сделать явное.

Откроем wiki на каждый из "языков" и осилим первое предложение:

Python is a high-level, general-purpose programming language.


PowerShell is a task automation and configuration management program from Microsoft, consisting of a command-line shell and the associated scripting language.

Так что сравнение теплого с мягким.

Из всех "неприятностей" реально утомляет в скриптах только одна: проверка, что за тип нам вернули. $null , объект или массив.
Остальное, как мне кажется, надумано или просто противоречит старым привычкам.

Плюсы "всё объект" и "всё можно отправить в конвейер" перевешивают минусы. Не надо парсить строки, где у каждого автора "утилиты, которая делает только одно, но отлично" своё, блин, представлние о прекрасном. И где простое True может быть написано десятком разных и порой весьма извращённых вариантов.

реально утомляет в скриптах только одна: проверка, что за тип нам вернули. $null , объект или массив.

С пониманием, что это не баг а уникальная и желанная фича - приходит просветление.

Да, в идеологию фича нормально укладывается. Просто принять.

Давно работаю с PowerShell и недавно начал осваивать python (без особого энтузиазма). PowerShell прекрасный инструмент и мне очень нравиться. Но у меня нет желания написать статью с кликбейтным названием "ужасы python", только потому что я плохо знаю python. Почему автор решил устроить холивар, для меня осталось загадкой.

Почему автор сравнивает powershell с python, а не с bash?

"Чукча не читатель, чукча писатель". Пост ни о чём. Если есть время на такие посты-навряд ли автор часто пользуется компом для программирования

Если файл существует, но первая строка пуста (там нет даже пробела), то Get-Content возвращает $null!

PS C:\> Get-Content C:\Temp\1.txt

one
two

Вот пример файла с пустой первой строкой - нет такого поведения, о котором вы говорите

Теперь вас не удивит поведение следующего кода:

  1. В PS принято возвращать один объект как один объект, а не коллекцию, когда он один. Так в других языках есть свои конвенции, которые разработчики соблюдают.

  2. Тем не менее, никто не заставляет разработчиков командлетов соблюдать эту конвенцию, поэтому в случае Invoke-SqlCmd адресуйте свой вопрос разработчикам модуля SqlServer, а не разработчикам языка.

($found.getType().FullName -eq 'System.Management.Automation.PSCustomObject')

$found -is [System.Management.Automation.PSCustomObject]

Где-то плачут математики, для которых множество из двух элементов, и одного, и нуля элементов - это объекты одного "типа". Но создатели PowerShell похоже считают в парадигме: ноль, один, много.

Никто не запрещает разработчикам командлетов даже при возвращении одного объекта заворачивать его в коллекцию - разработчики PowerShell тут ни причём.

Какого черта? На самом деле в PowerShell функция возвращает не только то, что в return (это ключевое слово можно и не писать), а собирает все выводы по ходу выполнения. Вывод new-Item прилепился до того, что мы вывели в return.

  1. На это натыкаются примерно все новички в PowerShell - ничего страшного =)

  2. Это действительно особенность архитектуры: ключевое слово return на самом деле нужно не для вывода в stdout, а для прерывания работы функции. Т.е. для случая, когда стандартный workflow функции по какой-то причине закончить нельзя и нужно преждевременно остановиться.

дописав | Out-Null после New-Item

Не нужно так делать: вызов командлетов довольно дорогая операция. Гораздо лучше написать $null = New-Item

при выводе они склеиваются - хорошо что хоть через пробел.

Это настраивается под ваши предпочтения: https://devblogs.microsoft.com/powershell/psmdtagfaq-what-is-ofs/

мы можем забыть присвоить хоть какое-то значение переменной:

Это настраивается: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/set-strictmode. Хорошей практикой считается разработка в среде с включённым Strict Mode.

Имелось в виду, первая и единственная строка файла пуста

В остальном да, это так, но это ужасно

Если в файле нет данных, что вы предлагаете тогда возвращать?

Нет, PS ведет себя так если файл пуст (0 байт).
А если там есть реальная пустая строка (в наличии символ(ы) конца строки), то будет возвращена именно пустая строка.

Далее, что именно ужасно и почему? В каждом языке программирования есть свои особенности. В случае PowerShell, возвращения всего-всего в stdout (пайплайн) позволяют делать всякие прикольные штуки и в некоторых случаях даже более лаконичный синтаксис, чем в других языках.

Ужасно потому что нарушает математические принципы типизации. Пустое множество, множество из одного элемента и множество из многих элементов это объект типа множество

В PowerShell возникает нечто вроде {el} == el потому что дескать элемент один

PowerShell в первую очередь сделан для упрощения работы администратора, а не ради математических идеалов

Массив из одного элемента (в файле же одна строка).

Этим элементом будет пустая строка

По питонячи это [""]

Я наверное чего-то не понимаю: если, например, мы открыли Notepad, не написали ничего, сохранили как txt-файл, размер файла в таком случае будет 0 байт. Строк в файле нет ни одной - там вообще данных нет. Get-Content на такое вернёт $null

Возвращать на такое объект типа string было бы странно: с чего мы вдруг занимаемся неявной конвертацией пустоты в строки - командлет в конце концов же не Get-String называется.

Если же в файл записать один виндовый перевод строки 0D0A и больше ничего, то Get-Content вернёт объект типа System.String - т.е. одну пустую строку.

Всё правильно вроде, что не так?

Поясню с другой стороны. Выполните в Microsoft management studio кверь из таблицы с условием 0=1. Вы получите пустой грид, но с именем колонок. Вот это логично

А PowerShell это превращает в null

Потому что таблица имеет хоть какую-то структуру, описание данных. А абсолютно пустой файл - нет. Запишите в текстовый файл заголовок в формате CSV и передайте Import-Csv - вот тогда сравнение будет более сопоставимым.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории