The PowerShell aliases that conflicted with Linux and OS X were removed in #786, specifically commit 7d9f43966.
However, new discussion is happening on how to handle this better than just removing the aliases.
This makes using rm
, ls
, etc. sucky, since globbing isn't performed:
> touch blah.tmp
> ls *.tmp
ls: *.tmp: No such file or directory
> Get-ChildItem *.tmp
Directory: /Users/andrew/src/PowerShell
Mode LastWriteTime Length Name
---- ------------- ------ ----
------ 5/3/16 8:39 PM 0 blah.tmp
> rm *.tmp
rm: *.tmp: No such file or directory
> Remove-Item *.tmp
> Get-ChildItem *.tmp
Blah.
Usability sync generally agrees that the interactive experience sucks without the aliases. What we don't agree on is what alternatives should be offered to users who want to use the native binaries by default. Some options that have been floated include:
^
) that automatically falls into the native PATHbash -c
(many said this is too many characters to be usable)rm -e
, for instance, would not fail). I think this is something we want to figure out sooner rather than later, so I've moved it to v0.5.0. In my opinion, a PowerShell setting to switch modes is the best first step.
@andschwa and default would be ....?
@vors my _personal_ opinion: the PowerShell aliases enabled; because you're running PowerShell.
Eventually we're going to want a first-time startup "getting started" guide for PowerShell anyway, and would state that this is an available setting.
@BrucePay any updates on this?
Usability sync today reiterated that the aliases should go back in. (Piping to sort
is yet another data point in having a totally broken PS experience.)
Leaving Bruce as an assignee to determine the best path forward with the above mitigations. @andschwa: we probably need someone else assigned to do the work to put the aliases back.
I just had a conversation with @jpsnover and he is very clear that we are not putting aliases back. We should create inbox aliases.ps1
file and promote dot-sourcing it.
It's probably worth pointing out that ls
in bash typically isn't simply ls
, it's an alias with some default arguments, with maybe the most notable to output using color.
PowerShell aliases don't work at all like aliases in Linux, so we'd need to either define ls
as a function, or enhance our aliases to work more like bash aliases.
It might also be worth spending some time analyzing modules in the gallery to see how many wouldn't work as is with the aliases removed - sort
is especially concerning.
The aliases are not in today, and we should make sure for Aug17 we have a healthy discussion about the pros/cons of the alias situations for people to join into.
Looks like we have a story, closing the issue.
My 2p on this - a new PowerShell settings Variable similar to $PSModuleAutoLoadingPreference that was introduced in PSv3 would allow this to be controlled by the end user in their profiles (could also put together a simple example that shows some commands running with and without the PS Aliases as a good
Suggestive name $PSUsePowerShellAliases and if it is not explicitly set to true (within profile or interactively) then the standard *nix aliases would be used in place.
I believe that this would likely also give a better UX for those that may now decide to test the water with PowerShell that wouldn't have done before as its not taking away what they know but allows those of us that know the PS way the ability to do so as well.
not taking away what they know
Absolutely. If there has to be a compromise then it should be in favor of Linux Bash users i.e. potential new PowerShell users. The existing PowerShell faithful can recreate their *nix aliases easily enough or better yet, wean themselves off those aliases.
In fact, now that we have PowerShell on Linux, I'd like to see the built-in *nix aliases removed from all OS versions of PowerShell Core - if they aren't already. That would leave built-in aliases that match the built-in PowerShell commands and don't attempt to "fool" you.
I'm a fan for removing the common aliases from ps on Linux by default - I am not a fan of "fixing" this on Windows as Keith suggests. My argument for this is that if you win over a Linux user to PowerShell and then they decide to also try it on Windows, they will not have the common aliases.
Could this be added to PSReadline, the ability to enable Linux Aliases or not? For me, it's simple to fix my code which uses short names for functions. Still, I'm going to always type LS
first and expect it to operate like the PowerShell LS alias for Get-ChildItem
.
Please feel free to use this issue to voice your opinion on what PowerShell's behavior should be.
I think that what @kilasuit, @rkeithhill, and @1RedOne touched on seems like the best solution -- have it disabled by default on Linux and macOS but at the same time, make it easy for us to enable it in the console or in our scripts.
Existing scripts can be updated to check for this variable and disable or enable the option right then and there, and it beats pouring through a bunch of code to look for short names that won't behave as anticipated.
Off-topic -- beyond excited about PowerShell being available on other platforms! đ
regarding PSReadLine then @lzybkr should be able to suggest if that is a possibility at all though i'd prefer it as a PS Variable than a requirement for PSReadLine as there are those like @juneb that don't use PSReadline at all
I could certainly publish a sample for PSReadline to replace specific aliases with the PowerShell cmdlet, it would be based on this sample: https://github.com/lzybkr/PSReadLine/blob/master/PSReadLine/SamplePSReadlineProfile.ps1#L354
That said, I don't think it's a real solution..
The biggest issue in my mind is the conflict between script portability and familiarity. We've provided guidance that scripts shouldn't use aliases, but it's still common practice. Some aliases might be more problematic than others, e.g. sort
might be used more than ps
or ls
in scripts.
We've certainly discussed some options such as providing a module you just import to get those aliases back. But we haven't settled on anything yet and are hoping for more feedback.
Replacing PowerShell commands with native executables without globbing support definitely won't help with convincing bash guys to use PowerShell.
So, guys, maybe it'll be better to simply add globbing support to native executables? That will solve all the problems and make PowerShell more usable to everyone, right? Link #954.
As a *nix user who has barely ever touched windows, I'd like to put in a strong vote for leaving the aliases in. Many years of muscle memory have taught me to use ls
, rm
, etc. I don't want to have to re-learn my muscle memory (then re-re-learn it whenever I end up in bash) to get the native Powershell experience.
Correct me if I'm wrong here, but is this any different for dir
on windows? In PS on Windows, dir
isn't dir.exe
. It's Get-ChildItem
. On *nix, why should ls
be /bin/ls
instead of Get-ChildItem
?
@Gaelan I got your point, but please consider that there is no dir.exe
file in Windows. dir
is an internal command of cmd
command processor, similar to bash
builtin. Maybe that's the (one) reason because PowerShell wasn't designed to call that external dir.exe
command directly.
@Gaelan, @ForNeVeR: While cmd-built-ins won't ever clash because they don't exist as programs, there are PowerShell aliases that conflict with native executables, even on Windows.
In general I don't think there _is_ a safe way of keeping aliases and _not_ breaking things because theoretically every single alias (except maybe those that cannot exist in the file system, like ?
) could shadow a native executable which can then no longer be called (at least not by its basename).
PS> gal|?{gcm "$_.exe" -ea 0}
CommandType Name
----------- ----
Alias fc -> Format-Custom
Alias sc -> Set-Content
Alias sort -> Sort-Object
Alias where -> Where-Object
Alias write -> Write-Output
So the only _safe_ route would be to have no aliases at all, which kinda defeats the purpose. And no doubt, the default aliases are most of all convenient. I don't have a good answer here, actually.
I would personally prefer the aliases to be left in. They are generally there to make navigation and general shell usage faster and more comfortable. Removing them will degrade the experience of using PowerShell.
I support the idea of possibly adding a way to indicate you are calling the builtin Linux binary instead. Maybe even as a profile preference?
If you look through the history in here I have suggested what I think to be the best solution from a UX perspective for aliases that map to an equivalent non-Windows commands
This is a long-standing PowerShell issue. I complain that it has no command comparable to cmd's dir
or even to ls
. The response, every single time, is "but there's an alias!".
Aliases are not and have never been a solution to this problem. The dir
and ls
aliases do not provide the functionality that dir
and ls
provide. The same is true for the wget
and curl
aliases.
The entire approach to the aliases needs to be rethought, and that will mean breaking changes.
Why can't system defined aliases just be second class citizens to binaries in PATH?
I'd say remove all *nix aliases on Linux, OS X builds until you figured out what to do.
Edit: Thanks for clarifying that this has already been done, sorry for the interruption.
@okket that have been done already. We're discussing if something needs to be changed.
Seems to me that we should just put all the aliases in files people can source in their profiles, and then, provide a default system-specific profile ...
bash-aliases.ps1
dos-aliases.ps1
initial-aliases.ps1
If nothing else, that serves to remind people that not everyone has the same short names.
Let's not forget (@sleepypikachu) that PowerShell's aliases don't _do_ anything except rename the command and override command resolution order. Bash's alias
functionality requires _functions_ in PowerShell.
@Gaelan your muscle-memory gets you to use the alias, but would you be frustrated with the parameters and behavior not working the same as the real command?
That is the real issue here and @DrPizza is spot on. A great example is, _dir /s_. That command fails in PowerShell so you have to change it to dir -recurse.
So there are really three related issues here:
I don't think #1 is too bad of an issue and would make things worse if they were aliased. Dir -recurse is a more readable parameter than dir /s anyway. Plus with the cross-plat, it makes scripts inconsistent when trying to move from Windows to Linux and the reverse.
Short-term, I think you need both a config option as well as a way to call the native command if the alias is enabled.
Default, leave it enabled. This is PowerShell.... on Linux. It should behave as PowerShell so they can learn what CmdLets to use. My co-worker with a Linux and Perl background found it much easier to figure out the cmds he needed to get a script working. I think it was grep, ls, and man that was key for him. Using man should help them figure out how to use the cmd properly.
Long-term, add coverage to the native cmdlets to have all the parameters and capabilities of native commands. This enhances PowerShell for Windows and Linux by giving us more powerful options. Some of the behaviors will likely need to be converted to multiple CmdLets and use Objects and Pipelines, but that is a great thing! If it didn't do that, then what would be the point of PowerShell?
My opinion is to keep as is. No alias on PowerShell (except select and etc., they're required), alias on Windows PowerShell.
Providing an option is better, but to provide all aliases as options is... well, not impossible.
IMHO having ls alias to dir makes sense, since I could easily use Where-Object to filter files. I have been a Linux user for years and typing dir is not as natural as using ls.
It seems to me that consistency is important. I'm not against removing the aliases from other platforms, but having an interface that behaves differently depending upon the OS bothers me. One of the major points of having PS running on *nix is that it's one interface to manage everything. If the aliases are going to be removed from PowerShell on the newly supported platforms, I think some consideration should be made to whether they should be removed on Windows as well.
No, I strongly support that PS provide aliases by default, but the real thing beneath should have the exactly same functionality (and maybe parameter compatibility) with the original native binaries, except for typing support.
PowerShell without types is useless.
Using the underlying system binaries and adopting the unix tools philosophy will promote adoption. As a person who does devops at unix shops, I was pleasantly surprised to find that the normal unix binaries were somewhat working in this implementation. Regarding the * character issue, I think most people in the *nix side would be comfortable with using an escape character in front of the * when indicating *nix shell glob as opposed to whatever its currently behavior is in powershell. Probably would be an acceptable solution for | as a pipe producing an object instead of a stream of octets passing between files goes against published standards and will hinder adoption. http://pubs.opengroup.org/onlinepubs/009695399/functions/pipe.html
@be5invis please note: nobody is going to remove types from PowerShell; either gci
and Get-ChildItem
stays the same in both Windows PowerShell and Linux PowerShell. Here we're only talking about whether builtin alias like ls -> Get-ChildItem
should exist on Linux or not. Your scripts shouldn't call ls
or gci
anyways if you mean to call Get-ChildItem
(because using aliases in scripts is not recommended and never were recommended). ls
and gci
are only convenience aliases for command-line usage, and it _could_ confuse the Linux user if ls
is suddenly aliased to Get-ChildItem
and not his favorite native command; it will confuse him even more if he haven't a concise way to call this command directly.
I am for uses command to enable alias on powershell.
Keep all alias and slowly deprecate the them on Windows powershell.
I think using command like
Enable-Alias Unix
Enable-Alias dos
To enable alias has following advantages
@ForNeVeR I use ls
as gci
all the day because it is one letter shorter...
However introducing this change (remove unix-y and dos-y aliases) is definitely a breaking change (it is not like curl
). A âperfectâ solution may be implementing these commands to a typed enhancement of existing tools.
For scripts, maybe... a using
statement?
@ForNeVeR I think you have misunderstood @be5invis . He is a strong supporter of powershell. I think what he means by "powershell without type is useless" is that people should not use native curl in powershell.
@be5invis Also I think your idea of compatibility of native curl is far reaching. The powershell grammar is not compatible with standard unix grammar, for example you can do rm -rf
in unix but in powershell you have to do rm -r -fo
.
Therefore you will never reach parameter compatibility no matter what.
@chantisnake So why not add a parameter called ârfâ, which is equalivent to -recurse -force
?
@be5invis This goes against how parameters work in PowerShell. They are orthogonal, and if not, there are different parameter sets. They also only have long names and instead of short names they can individually be abbreviated as long as they remain unambiguous. In your case you'd also need to add an alias to that parameter, fr
. Also suddenly -Recurse
would no longer be able to be shortened to -r
but instead would have to be -re
to not clash with your proposed -rf
parameter.
You could ask the same question from the other side: Why not specify both parameters separately? You're willing to go against PowerShell code principles and conventions in quite a big way only to keep pretending you're still working with the same Unix tools, even if you're not. However, the GNU parameter conventions with their short and long names are hardly universal and lots of well-established tools go against them, e.g. tar
, or find
. Yet you're not up in arms on their bug trackers to change them. While a core part of Unix has always been that there are a billion different utility programs that each work in slightly different ways, suddenly having yet another one of them (admittedly doing a bit more and trying to encompass lots of other utilities in itself) is so disconcerting and problematic that it has to be changed? I don't think so.
Remember: The shell on your machine is yours. Just as people alias rm
to rm -i
for their own comfort, there is nothing preventing you from removing the rm
alias and have a function wrapping Remove-Item
called rm
with an -rf
parameter.
But trying to change PowerShell in its entirety to completely replicate every single Unix tool is fairly misguided.
The functionality and output of ls
has been well defined for many years. The ls
command outputs an octet stream in a well known format. The ls
command does not output DirectoryInfo and FileInfo objects. Having ls
output something different is at a minimum confusing and possibly a bit deceptive.
When the user is ready to have the benefits of objects in the pipeline, the user will learn about Get-ChildItem and gci. If the user does not want to have the benefits of, or deal with, objects in the pipeline, the user might be better off using using bash, ksh, csh, sh, etc.
The same thing can be said of the DIR
command on Windows.
Let *nix be *nix and make Powershell the best it can be.
@Liturgist
When the user is ready to have the benefits of objects in the pipeline, the user will learn about Get-ChildItem and gci. If the user does not want to have the benefits of, or deal with, objects in the pipeline, the user might be better off using using bash, ksh, csh, sh, etc.
This contradicts your point. If people are using Powershell, then they probably want objects in the pipeline. We shouldn't make then relearn basic commands to take advantage of this.
Agree with @Gaelan.
If someone does not want objects, they can simply switch to bash or zsh.
They want the benefits of objects, and aliasing things like ls
to a compatible but typed version will give them exactly what they want.
@Gaelan and @be5invis, I understand the desire to limit the amount of change a user must do to use Powershell. My fingers seem to type ls
before my brain even sends a signal to them.
The problem is that those existing basic commands to not produce objects. The actual change to be made is not from ls
to gci
. The bigger change is from the thinking done to process lines of text to thinking about the properties of and what methods can be applied to an object.
It is every user's right to make whatever aliases they want. I would agree that it could be made easy for the user to do this by adding a method and property to $Host (System.Management.Automation.Internal.Host.InternalHost) to enable or disable native command replacement. I have seen others, but is there a GUI profile configuration tool included with Powershell?
If someone does not want objects, they can simply switch to bash or zsh.
Why can't PowerShell provide an "easy on-ramp" for folks that have used bash for years and then decide to dip their toes in the PowerShell waters? Let them start with what they know and start to phase in PowerShell features (like object emitting commands and objects in the pipeline) as they grow more comfortable using PowerShell.
I can't tell you how many times I've had to use the line "_PowerShell is a shell. It will executable your favorite native utilities just fine_" to get people past the notion that they could only use PowerShell with those funny sounding commands and to get them to actually give PowerShell a try. PowerShell needs to respect and work with popular, native utilities as best as it can - period. That is after all, one of the primary jobs of a "shell".
@rkeithhill So let me clearify: For users want to use Powershell, they want types, right? However your native tools, like /bin/ls
, cannot communicate with types. Therefore, switching to a typed shell, but without typed utils, the change is meaningless.
Therefore, typical Unix users may want to type the identical command, but get the typed result directly. So there is two options:
ls
to a builtin with compatible parameters.For users want to use Powershell, they want types, right?
Eventually, they probably will. That said, I work with a number of devs I've started on PowerShell by merely selling them on using it with Git and Posh-Git (something CMD can't provide). They rarely pipeline anything at this point but I expect them to get there. That point is, the git.exe utility behaves under PowerShell just as it behaves under CMD. Easy transition.
To me, ls (like ps, grep, sed, awk, gcc, curl, etc) is just another native utility that any "shell" should be able to run. Now, if someone is ready for and wants the object emitting command for listing container contents, they can use Get-ChildItem
or its alias gci
. If they are of the bent that they will never use the native ls
utility, then they can create a ls
alias for Get-ChildItem in their profile.
BTW I don't think trying to make Get-ChildItem
parameter compatible with ls
is feasible. You'll get hung up pretty quickly with PowerShell parameters not being case-sensitive e.g. -c/-C, -d/-D, -i/-I. And PowerShell doesn't support parameter combining e.g. ls -rt. It's a reach and it violates PowerShell's Monad principle. A task like sorting would be done by a separate cmdlet (Sort-Object) and not by Get-ChildItem itself.
@rkeithhill I am not going to make Get-ChildItem
being compatible with ls
. I am purposing another cmdlet, may be called UnixCompatibles-ls
as its full name, and have a separate command parser which accepts GNU getopt flavor, instead of PowerShell.
@be5invis Isn't the easier option at that point a separate function that runs ls
, passing it all its arguments, parses the output and creates objects from them? A completely separate command parser (along with completely separate command metadata, formatting for Get-Help
, ...) is a bit overkill (apart from replicating much of PowerShell's internal workings in an incompatible manner.
There's always going to be two separate worlds here, one native, one typed. PowerShell already services both of them, by being able to execute native programs and cmdlets. I personally don't see any benefit (just a massive undertaking in development effort) in trying to add a layer above native commands that replicates their parameter metadata within PowerShell. Besides, what would you do about tar
, or find
(and lots of other programs), which AFAIK don't adhere to the GNU conventions. Implement yet _another_ command parser, along with wrapper functions to call those? Note also that for a command parser to work, the native program's arguments have to be parsed within PowerShell and must not conflict with the language. Something that might be difficult with weird things like [
.
@ygra It is okay either.
For users want to use Powershell, they want types, right?
@be5invis, perhaps this is where a bit of disconnect occurs. No, they do not want types. The user wants to get their work, or play, done. The user knows that ls
produces a stream of text.
Is UnixCompatibles
a verb? Would this change the user's $PROFILE script permanently, or only for this session? I would not want Get-ChildItem to be ls compatible. Let ls
be ls
and do what ls
does. It sounds like this would give the user a choice to replace ls
with Get-ChildItem
. That's fine. I am not sure that I want that, but for those who do, that's fine.
@Liturgist I think what @be5invis means is that if people went to the trouble of switching to Powershell (as opposed to staying with Bash), it is because they want something Powershell provides. If people wanted a stream of text out of ls
, (on Linux or macOS) they would never have bothered with Powershell.
@Gaelan So I shouldn't use PowerShell if I need to use gcc or git? What's wrong with letting folks decide if they want text (ls) or objects (gci)? There are more reasons to use PowerShell than just its OO nature - powerful as it is. Heck I'd rather use PowerShell just for its C/C# like control flow statements (vs if/fi and switch case/esac) and its proper type system (where numbers are numbers and not strings).
@rkeithhill
So I shouldn't use PowerShell if I need to use gcc or git?
On a *nix system, if users just wanted to use the shell for gcc or git they wouldn't bother with PowerShell, because the shell that came with their OS does that perfectly well.
Heck I'd rather use PowerShell just for its C/C# like control flow statements (vs if/fi and switch case/esac)
Perhaps if someone was already using PowerShell they would prefer it because of that, but I doubt that someone would install PS just for that.
its proper type system (where numbers are numbers and not strings)
/bin/ls
doesn't work with the type system either: if I run ls -l
, I will get file sizes as a string instead of a proper PS number.
I feel like the reasons a new user would switch to PS on *nix largely revolve around the OO and the type system. We should make it as easy as possible for new users to get started with PSâif I saw something about PS, tried to check it out, only to discover that I needed to relearn everything about the command line to use it, I would probably be much less likely to bother with learning it than if I could fire up PS, type ls
and immediately see the type system in action. Yes, I could use aliases, but if I'm just trying out PS in a few spare minutes I'm unlikely to want to do much configuration before I jump in and start playing around.
On a *nix system, if users just wanted to use the shell for gcc or git they wouldn't bother with PowerShell, because the shell that came with their OS does that perfectly well.
Perhaps if someone was already using PowerShell they would prefer it because of that, but I doubt that someone would install PS just for that.
Sorry, but I strongly disagree. As a Linux user, I want to use PowerShell instead of shell that came with my OS. For everything. Because it's awesome, you know :)
Heck, I am even packaging PowerShell for NixOS right now just to use it for everything.
Please consider that our target users are not only native Unix users who accidentally use Windows+PowerShell, but also Windows users who accidentally use Unix+PowerShell ;)
A single character (like ^) that automatically falls into the native PATH
I would also prefer to keep aliases compatible across OS whenever they are valid on these platforms and use an escape character (like ^ls
) to get an implicit access to native commands, as suggested by @joeyaiello
I'm not familiar with the whole PowersShell philosophy, but what could be wrong with such an approach?
Actually, one more point for using a single-character escaping: bash already does it. https://twitter.com/climagic/status/806536501232340992
\ls
ignores all aliases.
Is the answer to aliases solved by enabling WSL (Windows Subsystem for Linux)? This will provide native sed, awk, ls, etc. commands in a bash shell.
While it is still beta code for Windows 10, surely it will be coming and made available in Server 2016 and 2012.
@Liturgist Currently, the WSL is a very separate environment from PowerShell. The commands are not callable from a PowerShell session. Additionally, this would likely be considered a regression by many current Windows PowerShell users as many scripts would break if they received the output from, say, GNU ls
rather than ls -> Get-ChildItem
. While the use of aliases was never recommended in scripts, the fact remains that they have been used and breakage would cause difficulty for many people.
@Liturgist: @bgshacklett is on right here. The problem is not that something happens when you type ls
, the question is what parameters you expect while using that, and whether or not the output emitted is consumable in an object-oriented fashion by other PowerShell cmdlets (i.e. ls | Where-Object Name -like *foo*
won't work if you're using the WSL ls
).
The original issue with conflicting aliases with native cmds has been addressed. If there is a need to have the capability to add back popular Windows PowerShell aliases, that should be a separate issue.
Opened https://github.com/PowerShell/PowerShell/issues/3610 to capture secondary issue
Most helpful comment
@be5invis This goes against how parameters work in PowerShell. They are orthogonal, and if not, there are different parameter sets. They also only have long names and instead of short names they can individually be abbreviated as long as they remain unambiguous. In your case you'd also need to add an alias to that parameter,
fr
. Also suddenly-Recurse
would no longer be able to be shortened to-r
but instead would have to be-re
to not clash with your proposed-rf
parameter.You could ask the same question from the other side: Why not specify both parameters separately? You're willing to go against PowerShell code principles and conventions in quite a big way only to keep pretending you're still working with the same Unix tools, even if you're not. However, the GNU parameter conventions with their short and long names are hardly universal and lots of well-established tools go against them, e.g.
tar
, orfind
. Yet you're not up in arms on their bug trackers to change them. While a core part of Unix has always been that there are a billion different utility programs that each work in slightly different ways, suddenly having yet another one of them (admittedly doing a bit more and trying to encompass lots of other utilities in itself) is so disconcerting and problematic that it has to be changed? I don't think so.Remember: The shell on your machine is yours. Just as people alias
rm
torm -i
for their own comfort, there is nothing preventing you from removing therm
alias and have a function wrappingRemove-Item
calledrm
with an-rf
parameter.But trying to change PowerShell in its entirety to completely replicate every single Unix tool is fairly misguided.