Powershell's equivalent to Linux's: ls -al
The ls
Unix utility's options you're using:
-a
option includes hidden items, which on Unix-like platforms are file-system items whose name starts with.
-l
requests the so-called long format, which produces tabular output that includes the file-system items' mode, user and group ownership, the last-write timestamp, the item size, and its name.
The PowerShell equivalent is:
Get-ChildItem -Force
Get-ChildItem
's-Force
switch includes hidden items in the output - although, unlike withls
, the.
and..
entries representing the target directory itself and its parent directory are not included (which makes it the equivalent of the more useful-A
ls
option).The equivalent of long format formatting is used by default; if, conversely, you're interested in file names (relative paths) only, use the
-Name
switch.Note: By default,
Get-ChildItem
targets the current location (directory); to specify an input path explicitly, use either the-Path
parameter - for wildcard patterns - or the-LiteralPath
parameter - for literal (verbatim) paths. The first positional argument (one not prefixed by a parameter names) implicitly binds to-Path
; e.g., the following command targets the current user's home directory:Get-ChildItem -Force -LiteralPath $HOME
- See this answer for more information.
See the bottom section for shortening this command and defining a convenience "alias" (function).
There's one fundamental difference between ls
and Get-ChildItem
, however:
ls
outputs formatted text, and for that reason parsing its output is generally discouraged.In PowerShell, formatting is separated from data and it is objects, not strings that are output.
- That is, irrespective of the rich display formatting that
Get-ChildItem
output presents in the terminal, its actual output are objects of typeSystem.IO.FileInfo
andSystem.IO.DirectoryInfo
, which can safely be used for further programmatic processing if captured in a variable, sent to other PowerShell comments through a pipeline, or used in an expression.
- That is, irrespective of the rich display formatting that
For instance, expression
(Get-ChildItem -Force).FullName
outputs the full paths of all items in the current directory.
For interactive convenience (you shouldn't do that in scripts), you can use built-in aliases and unambiguous parameter-name prefixes to shorten the command:
gci -fo
gci
is built-in alias for Get-ChildItem
, and its name follows PowerShell's naming conventions, where each so-called approved verb also has an approved 1-2 letter alias form; running Get-Verb Get
reveals that the approved Get
verb's alias form is g
; while the noun part isn't formally regulated, remembering that ci
stands for ChildItem
should be easy.
-fo
is the shortest parameter-name prefix that unambiguously refers to the -Force
switch (just -f
alone could also refer to -Filter
[1])
- Note: Some parameters themselves have actual aliases, such as
-h
for-Hidden
or-ad
for-Directory
, but-Force
does not. - Unlike unambiguous parameter-name prefixes, which can become ambiguous over time if new parameters are added to a command, parameter aliases are safe to use in scripts, although for readability the full names are preferable.
To see all aliases defined for a given command (Get-ChildItem
in this example):
PS> Get-Alias -Definition Get-ChildItem
CommandType Name Version Source
----------- ---- ------- ------
Alias dir -> Get-ChildItem
Alias gci -> Get-ChildItem
To limit output to built-in aliases, i.e. to exclude aliases defined by other modules or $PROFILE
scripts, run pwsh -noprofile { Get-Alias -Definition Get-ChildItem }
(in Windows PowerShell, use powershell
instead of pwsh
.
- The above shows the output on macOS and Linux.
- On Windows you will see that
ls
is another built-in alias.This is a legacy alias from the time PowerShell was a Windows-only shell, and is best avoided:
In general, aliases take precedence over external programs with the same name, and it isn't a good idea to shadow (override) a platform's standard command-line utilities; while that doesn't apply to alias
ls
on Windows, it does in other cases, namelywhere
(shadowswhere.exe
) andsc
(Windows PowerShell-only, shadowssc.exe
)Specifically, given that the real
ls
Unix utility andGet-ChildItem
have such vastly different syntax (and behavior), exposing the latter asls
is likely to cause confusion.
Therefore, it is advisable to stick to those aliases that are abbreviated forms of the PowerShell command names, such as gci
for Get-ChildItem
, and gc
for Get-Content
. While that doesn't initially help with transitioning from familiar names such as ls
/ dir
and cat
, the fact that PowerShell cmdlet names as well as their abbreviated aliases are systematic and convention-based makes it easier to memorize them going forward.
Defining a convenience "alias" with preset arguments, using a function
:
POSIX-compatible shells such as bash
allow you to define aliases with preset arguments, such as alias ll='ls -al'
By contrast, aliases in PowerShell are mere name mappings and you need to declare a function instead (which you can add to your $PROFILE
file for availability in future session):
# Equivalent of bash alias `alias ll='ls -al'`
function ll { ls -al @args }
Or, an analogous gcih
function (h
denoting hidden) based on Get-ChildItem
:
function gcih { Get-ChildItem -Force @args }
See this answer for more information about aliases vs. functions in PowerShell, including how to create more sophisticated wrapper functions.
[1] Conceptually, it could also refer to the -File
parameter, but technically the latter is a dynamic parameter, specific to PowerShell's file-system provider, and is therefore not being considered during the ambiguity check.
ls' is not recognized as an internal or external command, operable program or batch file
I'm fairly certain that the ls
command is for Linux, not Windows (I'm assuming you're using Windows as you referred to cmd
, which is the command line for the Windows OS).
You should use dir
instead, which is the Windows equivalent of ls
.
Edit (since this post seems to be getting so many views :) ):
You can't use ls
on cmd
as it's not shipped with Windows
, but you can use it on other terminal programs (such as GitBash). Note, ls
might work on some FTP
servers if the servers are linux
based and the FTP
is being used from cmd
.
dir
on Windows
is similar to ls
. To find out the various options available, just do dir/?
.
If you really want to use ls
, you could install 3rd party tools to allow you to run unix
commands on Windows
. Such a program is Microsoft Windows Subsystem for Linux
(link to docs).
How to list files in windows using command prompt (cmd). I've tried using ' ls ' as in Linux but it shows an error?
Use the command dir
to list all the directories and files in a directory; ls
is a unix command.
Is there a way to create an alias to a cmdlet in a way that it only runs if arguments are passed to the alias?
You can't do it with an alias, because PowerShell aliases can only refer to another command name or path, and can therefore neither include arguments nor custom logic.
Therefore you do need a function, but it can be a short and simple one:
function which { if ($args.count) { Get-Command @args } else { Throw "Missing command name." } }
Note that while passing -?
for showing Get-Command
's help does work, tab completion of arguments does not.
In order to get tab completion as well, you'll need to write a wrapper (proxy) function or at least replicate Get-Command
's parameter declarations - which then does make the function definition sizable.
If the concern is just the size of the $PROFILE
file itself, you can write a proxy script instead - which.ps1
- which you can invoke with just which
as well, assuming you place it in one of the directories listed in $env:Path
[1]; see next section.
Defining a wrapper (proxy) script or function:
Defining a wrapper (proxy) function or script is a nontrivial undertaking, but allows you to implement a robust wrapper that supports tab completion and even forwarding to the original command's help.
Note:
Bug alert: As zett42 points out, as of PowerShell [Core] 7.1,
System.Management.Automation.ProxyCommand.Create
neglects to include dynamic parameters if the target command is an (advanced) function or script; however, compiled cmdlets are not affected; see GitHub issue #4792 and this answer for a workaround.For simplicity, the following creates a wrapper script,
which.ps1
, and saves it in the current directory. As stated, if you place it in one of the directories listed in$env:PATH
, you'll be able to invoke it as justwhich
.The code below can easily be adapted to create a wrapper function instead: simply take the contents of the
$wrapperCmdSource
variable below and enclose it infunction which { ... }
.As of PowerShell Core 7.0.0-preview.5, there are some problems with the auto-generated code, which may or may not affect you; they will be fixed at some point; to learn more and to learn how to manually correct them, see GitHub issue #10863.
# Create the wrapper scaffolding as source code (outputs a single [string])
$wrapperCmdSource =
[System.Management.Automation.ProxyCommand]::Create((Get-Command Get-Command))
# Write the auto-generated source code to a script file
$wrapperCmdSource > which.ps1
Note:
Even though
System.Management.Automation.ProxyCommand.Create
requires aSystem.Management.Automation.CommandMetadata
instance to identify the target command, theSystem.Management.Automation.CommandInfo
instances output byGet-Command
can be used as-is.Re comment-based help: By default, the proxy function simply forwards to the original cmdlet's help; however, you can optionally pass a string to serve as the comment-based help as the 2nd argument.
- By using
[System.Management.Automation.ProxyCommand]::GetHelpComments()
in combination with output fromGet-Help
, you could start with a copy of the original command's help and modify it:[System.Management.Automation.ProxyCommand]::GetHelpComments((Get-Help Get-Command))
- By using
You now have a fully functional which.ps1
wrapper script that behaves like Get-Command
itself.
You can invoke it as follows:
./which # Same as: Get-Command; tab completion of parameters supported.
./which -? # Shows Get-Command's help.
You can now edit the script file to perform the desired customization.
Note: The auto-generated source code contains a lot of boilerplate code; however, typically only one or two places need tweaking to implement the custom functionality.
Specifically, place the following command as the first statement inside the begin { ... }
block:
if (-not $MyInvocation.ExpectingInput -and -not ($Name -or $CommandType -or $Module -or $FullyQualifiedModule)) {
Throw "Missing command name or filter."
}
This causes the script to throw an error if the caller didn't provide some way of targeting a specific command or group of commands, either by direct argument or via the pipeline.
If you invoke the modified script without arguments now, you should see the desired error:
PS> ./which.ps1
Missing command name or filter.
...
Other common types of customizations are:
Removing parameters from the wrapper, by simply removing the parameter declaration.
Adding additional parameters to the invocation of the wrapped command, by modifying the following line in the
begin
block:# Add parameters, as needed.
$scriptCmd = { & $wrappedCmd @PSBoundParameters }Preprocessing pipeline input before passing it to the wrapped command, by customizing the
process
block and replacing$_
with your preprocessed input in the following line:# Replace $_ with a preprocessed version of it, as needed.
$steppablePipeline.Process($_)
For an example of a complete implementation of a proxy function, see this answer.
[1] Caveat for Linux users: since the Linux file-system is case is case-sensitive, invocation of your script won't work case-insensitively, the way commands normally work in PowerShell. E.g., if your script file name is Get-Foo.ps1
, only Get-Foo
- using the exact same case - will work, not also get-foo
, for instance.
How to pass arguments to Unix-like commands (via MinGW) in PowerShell
ls
is an alias in Powershell for the get-childitem
command. If you want to run an external command called ls
you will need to force Powershell to ignore its own ls
command.
You could try running ls.exe
, or specify the path to the MinGW command, or undefine the Powershell alias. Or learn to use the options for Powershell's own ls
command instead.
The nearest Powershell equivalent to ls -al
would be ls -Force
This will display all hidden and system files and Powershell's default output for ls
looks somewhat like the ls -l
format anyway.
You can check which command will be run using Powershell's get-command
which does a similar job to which
(or use gcm
as shorthand for less typing:
PS C:\Users\IEUser> get-command ls.exe
CommandType Name Version Source
----------- ---- ------- ------
Application ls.exe 0.0.0.0 C:\Program Files\OpenSSH\bin\ls.exe
PS C:\Users\IEUser> get-command ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
PS C:\Users\IEUser> gcm ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
PS C:\Users\IEUser> gcm ls.exe
CommandType Name Version Source
----------- ---- ------- ------
Application ls.exe 0.0.0.0 C:\Program Files\OpenSSH\bin\ls.exe
and if you don't want to learn a new command:
PS C:\Users\IEUser> set-alias which gcm
PS C:\Users\IEUser> which ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
Why does an error keep popping up when ls -a is used?
That tutorial is meant for POSIXy systems such as Linux, and you're using Windows.
Windows' PowerShell happens to have an alias ls
for listing items in a directory, but it does not directly support -a
(which the POSIX ls
command does support).
Related Topics
Vagrant Ssh -C and Keeping a Background Process Running After Connection Closed
In Linux, Physical Memory Pages Belong to The Kernel Data Segment Are Swappable or Not
How to Provide Extend-On-Write Functionality for Memory Mapped Files in Linux
How Does Linux Support More Than 512Gb of Virtual Address Range in X86-64
Udev Rule with Few Parent Device Attributes
How to Access Raspberry Pi Qemu Vm via Network
How Can Beaglebone Black Be Used as Mass Storage Device
Powershell's Equivalent to Linux's: Ls -Al
Transpose Rows into Column in Unix
What Ncurses Frameworks Are Available for Bash
Berkeley Db Mismatch Error While Configuring Ldap
Find The Depth of The Current Path
How to Do a While Loop with a String Redirected into It
Does I2C Driver Need to Be Implemented Just Like Any Other Character Device Driver
Time Waste of Execv() and Fork()
Can Upstart Expect/Respawn Be Used on Processes That Fork More Than Twice