windows 和 OS X 实现之间 PowerShell 别名 'ls' 和 'dir' 的不同行为是否有原因

Is there a reason for the different behaviour of PowerShell aliases 'ls' and 'dir' between the windows and OS X implementations

有谁知道下面两种情况输出不同的原因吗?

alias ls 的输出与 alias dir 在 OSX 上的输出不同。在 Help Get-Content -Examples 的 PowerShell 帮助中显示的示例中:

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: No such file or directory

上述两种情况在 Windows 10 上的 PowerShell v5 中给出相同的结果。

这个观察是错误吗?

您似乎在调用命令 /bin/ls/usr/bin/ls?)而不是 PowerShell 别名 ls,尽管别名应优先于外部命令。验证别名是否实际定义:

Get-Alias -Name ls

Windows-only 版本中的内置别名以 标准 Unix 实用程序 命名有意排除在跨平台版本之外,以免影响(覆盖)它们。

注意:从 PowerShell Core v6.0.0-alpha.10 开始,这是 正确的,但是这个设计决定引起了争议 - 找到讨论 here.
一个值得注意的陷阱是,PowerShell 在调用 外部 实用程序时不会执行 globbing,因此 ls *.txt 无法像在 Bash 中那样工作,例如.

因此,内置于 Windows-native 版本中的别名 ls 而不是 内置于 Linux 和 macOS 版本中,因为标准实用程序 /bin/ls 应该在那里优先。

相比之下,dir - 由于与任何标准 Unix 实用程序名称不冲突 - 是 所有 版本中的内置别名(并且指的是 Get-ChildItem,如 Windows).

当 PowerShell 仅 Windows 时,添加 ls(对于 Get-ChildItem)和 cat(对于 Get-Content)等别名是一种认可来自 Unix 背景的人。
在 Windows 上,这些命令名称没有预定义的含义,但在类 Unix 系统上,它们会隐藏标准实用程序 (CLI),从而导致潜在的意外行为。

安全、便携的方法是坚持:

  • 使用完整的 cmdlet 名称而不是别名。
  • and/or 使用完全基于 cmdlet 名称的别名(而不是像 lsdir 这样的遗留命令名称)。

PowerShell 具有从 cmdlet 名称派生的别名的命名约定,将每个批准的动词(例如 Get-Copy-)映射到批准的别名前缀(例如 gcp) - 参见 https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx.

如果对给定命令名称的含义有疑问,请使用 Get-Command <name>(或 gcm <name>)。