问题
Does anyone know the reason for the difference in output between the below 2 cases?
The output from alias ls
differs from the output of alias dir
on OSX. In an example shown in the PowerShell help for Help Get-Content -Examples
:
dir ./*.txt | foreach {Get-Content $_ -Head 1; Get-Content $_ -Tail 1}
works as per the example. However, if dir
is replaced with ls
:
ls ./*.txt | foreach {Get-Content $_ -Head 1; Get-Content $_ -Tail 1}
an error is returned:
ls: ./*.txt: No such file or directory
Both the above cases give the same result in PowerShell v5 on Windows 10.
Is this observation a bug?
回答1:
You seem to be invoking the command /bin/ls
(/usr/bin/ls
?) rather than the PowerShell alias ls
, even though an alias should take precedence over an external command. Verify that the alias is actually defined:
Get-Alias -Name ls
回答2:
Built-in aliases in the Windows-only edition named for standard Unix utilities were intentionally left out of the cross-platform editions, so as not to shadow (override) them.
Note: This is true as of PowerShell Core v6.0.0-alpha.10, but this design decision has attracted controversy - find the discussion here.
One notable pitfall is that PowerShell doesn't perform globbing when invoking external utilities, so something like ls *.txt
doesn't work as it would in Bash, for instance.
Thus, alias ls
, built into the Windows-native edition, is not built into the Linux & macOS editions, because standard utility /bin/ls
should take precedence there.
By contrast, dir
- due to not conflicting with any standard Unix utility name - is a built-in alias in all editions (and refers to Get-ChildItem
, as on Windows).
When PowerShell was Windows-only, adding aliases such as ls
(for Get-ChildItem
) and cat
(for Get-Content
) was a nod to people coming from Unix backgrounds.
On Windows, these command names have no predefined meaning, but on Unix-like systems they would shadow standard utilities (CLIs), resulting in potentially unexpected behavior.
The safe, portable approach is to stick with:
- using the full cmdlet names instead of aliases.
- and/or using aliases solely based on cmdlet names (rather than on legacy command names such as
ls
ordir
).
PowerShell has naming conventions for aliases derived from cmdlet names, mapping each approved verb (such as Get-
and Copy-
) to an approved alias prefix (such as g
and cp
) - see https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx.
When in doubt about what a given command name refers to, use Get-Command <name>
(or gcm <name>
).
来源:https://stackoverflow.com/questions/39823655/is-there-a-reason-for-the-different-behaviour-of-powershell-aliases-ls-and-di