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 名称的别名(而不是像
ls
或 dir
这样的遗留命令名称)。
PowerShell 具有从 cmdlet 名称派生的别名的命名约定,将每个批准的动词(例如 Get-
和 Copy-
)映射到批准的别名前缀(例如 g
和 cp
) - 参见 https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx.
如果对给定命令名称的含义有疑问,请使用 Get-Command <name>
(或 gcm <name>
)。
有谁知道下面两种情况输出不同的原因吗?
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 名称的别名(而不是像
ls
或dir
这样的遗留命令名称)。
PowerShell 具有从 cmdlet 名称派生的别名的命名约定,将每个批准的动词(例如 Get-
和 Copy-
)映射到批准的别名前缀(例如 g
和 cp
) - 参见 https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx.
如果对给定命令名称的含义有疑问,请使用 Get-Command <name>
(或 gcm <name>
)。