Есть ли причина для различного поведения псевдонимов PowerShell «ls» и «dir» между реализациями Windows и OS X

Кто-нибудь знает причину разницы в выводе между двумя нижеприведенными случаями?

Вывод псевдонима ls отличается от вывода псевдонима dir в OSX. В примере, показанном в справке PowerShell для Help Get-Content -Examples :

dir ./*.txt | foreach {Get-Content $_ -Head 1; Get-Content $_ -Tail 1} 

работает по образцу. Однако, если dir заменить на ls:

ls ./*.txt | foreach {Get-Content $_ -Head 1; Get-Content $_ -Tail 1} 

возвращается ошибка:

ls: ./*.txt: нет такого файла или каталога

Оба приведенных выше случая дают одинаковый результат в PowerShell v5 в Windows 10.

Является ли это наблюдение ошибкой?


person Chris Poff    schedule 03.10.2016    source источник


Ответы (2)


Похоже, вы вызываете команду /bin/ls (/usr/bin/ls?), а не псевдоним PowerShell ls, хотя псевдоним должен иметь приоритет над внешней командой. Убедитесь, что псевдоним действительно определен:

Get-Alias -Name ls
person Ansgar Wiechers    schedule 03.10.2016

Встроенные псевдонимы в версии только для Windows, названные в честь стандартных утилит Unix, были намеренно исключены из межплатформенных версий, чтобы не затенять (переопределять ) их.

Примечание. Это верно для PowerShell Core v6.0.0-alpha.10, но это проектное решение вызвало споры — см. обсуждение здесь.
Одной из примечательных ошибок является то, что PowerShell не выполняет подстановку при вызове внешних утилит, поэтому что-то вроде ls *.txt работает не так, как, например, в Bash.

Таким образом, псевдоним ls, встроенный в версию для Windows, не встроен в версии для Linux и macOS, поскольку стандартная утилита /bin/ls должна иметь там приоритет.

Напротив, dir — из-за того, что оно не конфликтует ни с одним стандартным именем утилиты Unix — является встроенным псевдонимом во всех редакциях (и относится к Get-ChildItem, как в Windows).

Когда PowerShell был только для Windows, добавление псевдонимов, таких как ls (для Get-ChildItem) и cat (для Get-Content), было данью уважения людям, пришедшим из Unix.
В Windows эти имена команд не имеют предопределенного значения, но в Unix- как и системы, они будут затенять стандартные утилиты (CLI), что может привести к неожиданному поведению.

Безопасный, портативный подход заключается в том, чтобы придерживаться:

  • используя полные имена командлетов вместо псевдонимов.
  • и/или использование псевдонимов исключительно на основе имен командлетов (а не на устаревших именах команд, таких как ls или dir).

PowerShell имеет соглашения об именовании псевдонимов, полученных из имен командлетов, сопоставляя каждую утвержденную команду (например, Get- и Copy-) с утвержденным префиксом псевдонима (например, g и cp) — см. https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx .

Если вы сомневаетесь в том, к чему относится данное имя команды, используйте Get-Command <name> (или gcm <name>).

person mklement0    schedule 04.10.2016