Потому что таблица имеет хоть какую-то структуру, описание данных. А абсолютно пустой файл - нет. Запишите в текстовый файл заголовок в формате CSV и передайте Import-Csv - вот тогда сравнение будет более сопоставимым.
Далее, что именно ужасно и почему? В каждом языке программирования есть свои особенности. В случае PowerShell, возвращения всего-всего в stdout (пайплайн) позволяют делать всякие прикольные штуки и в некоторых случаях даже более лаконичный синтаксис, чем в других языках.
Я наверное чего-то не понимаю: если, например, мы открыли Notepad, не написали ничего, сохранили как txt-файл, размер файла в таком случае будет 0 байт. Строк в файле нет ни одной - там вообще данных нет. Get-Content на такое вернёт $null
Возвращать на такое объект типа string было бы странно: с чего мы вдруг занимаемся неявной конвертацией пустоты в строки - командлет в конце концов же не Get-String называется.
Если же в файл записать один виндовый перевод строки 0D0A и больше ничего, то Get-Content вернёт объект типа System.String - т.е. одну пустую строку.
Если файл существует, но первая строка пуста (там нет даже пробела), то Get-Content возвращает $null!
PS C:\> Get-Content C:\Temp\1.txt
one
two
Вот пример файла с пустой первой строкой - нет такого поведения, о котором вы говорите
Теперь вас не удивит поведение следующего кода:
В PS принято возвращать один объект как один объект, а не коллекцию, когда он один. Так в других языках есть свои конвенции, которые разработчики соблюдают.
Тем не менее, никто не заставляет разработчиков командлетов соблюдать эту конвенцию, поэтому в случае Invoke-SqlCmd адресуйте свой вопрос разработчикам модуля SqlServer, а не разработчикам языка.
Где-то плачут математики, для которых множество из двух элементов, и одного, и нуля элементов - это объекты одного "типа". Но создатели PowerShell похоже считают в парадигме: ноль, один, много.
Никто не запрещает разработчикам командлетов даже при возвращении одного объекта заворачивать его в коллекцию - разработчики PowerShell тут ни причём.
Какого черта? На самом деле в PowerShell функция возвращает не только то, что в return (это ключевое слово можно и не писать), а собирает все выводы по ходу выполнения. Вывод new-Item прилепился до того, что мы вывели в return.
На это натыкаются примерно все новички в PowerShell - ничего страшного =)
Это действительно особенность архитектуры: ключевое слово return на самом деле нужно не для вывода в stdout, а для прерывания работы функции. Т.е. для случая, когда стандартный workflow функции по какой-то причине закончить нельзя и нужно преждевременно остановиться.
дописав | Out-Null после New-Item
Не нужно так делать: вызов командлетов довольно дорогая операция. Гораздо лучше написать $null = New-Item
при выводе они склеиваются - хорошо что хоть через пробел.
PowerShell в первую очередь сделан для упрощения работы администратора, а не ради математических идеалов
Потому что таблица имеет хоть какую-то структуру, описание данных. А абсолютно пустой файл - нет. Запишите в текстовый файл заголовок в формате CSV и передайте
Import-Csv
- вот тогда сравнение будет более сопоставимым.https://habr.com/ru/post/723730/#comment_25375712
Далее, что именно ужасно и почему? В каждом языке программирования есть свои особенности. В случае PowerShell, возвращения всего-всего в stdout (пайплайн) позволяют делать всякие прикольные штуки и в некоторых случаях даже более лаконичный синтаксис, чем в других языках.
Я наверное чего-то не понимаю: если, например, мы открыли Notepad, не написали ничего, сохранили как txt-файл, размер файла в таком случае будет 0 байт. Строк в файле нет ни одной - там вообще данных нет.
Get-Content
на такое вернёт$null
Возвращать на такое объект типа
string
было бы странно: с чего мы вдруг занимаемся неявной конвертацией пустоты в строки - командлет в конце концов же не Get-String называется.Если же в файл записать один виндовый перевод строки
0D0A
и больше ничего, тоGet-Content
вернёт объект типаSystem.String
- т.е. одну пустую строку.Всё правильно вроде, что не так?
Если в файле нет данных, что вы предлагаете тогда возвращать?
Вот пример файла с пустой первой строкой - нет такого поведения, о котором вы говорите
В PS принято возвращать один объект как один объект, а не коллекцию, когда он один. Так в других языках есть свои конвенции, которые разработчики соблюдают.
Тем не менее, никто не заставляет разработчиков командлетов соблюдать эту конвенцию, поэтому в случае
Invoke-SqlCmd
адресуйте свой вопрос разработчикам модуляSqlServer
, а не разработчикам языка.$found -is [System.Management.Automation.PSCustomObject]
Никто не запрещает разработчикам командлетов даже при возвращении одного объекта заворачивать его в коллекцию - разработчики PowerShell тут ни причём.
На это натыкаются примерно все новички в PowerShell - ничего страшного =)
Это действительно особенность архитектуры: ключевое слово
return
на самом деле нужно не для вывода в stdout, а для прерывания работы функции. Т.е. для случая, когда стандартный workflow функции по какой-то причине закончить нельзя и нужно преждевременно остановиться.Не нужно так делать: вызов командлетов довольно дорогая операция. Гораздо лучше написать
$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.