ls
seems to have a number of limitations that seem odd to me that are not included in its switches (such as --max-depth=
as other tools have). I like to maintain common standards (so ls
and ll
follow what most normal distros have), but my additional aliases follow some kind of easy to remember syntax (lls
is 'long listing, security' etc). I could split this up into a few different questions, but since it all relates to this attempt to find common ways of manipulating ls
, a listing of my working to describe what I am talking about felt more appropriate as they are all related. Some specific questions:
I've often heard it said that you should never use
ls
infor
loops etc. That makes sense in terms of howls
will look inside subdirectories by default etc, but is there a simple way to clipls
to never look inside subdirectory? I see nothing like--max-depth=
in theman
page, but it seems to me that if we clipls
to not go into subdirectories then it should be reliable to use infor
loops or other constructs. Is there a reliable way to clipls
to only output for one directory and then use that in a for loop?I have used what I feel are quite clunky constructs for
lld
(long listing with directories) andllf
(long listing with files). Is there a better way to say "I just want to see files?" or "I just want to see directories?"; again, there is nothing in theman
page that I can see. In particular, I can only do this listing in-l
format as otherwise I could not grep out the items that I do not want to display. In general, I think using grep in this way is probably a bad idea (as locks into-l
format), so is there a better way to achieve just picking directory items or just picking files, instead of using grep?If any other approaches in the below are malformed, I would appreciate knowing better ways?
Attempt to have a standard set of ls
outputs (as are often setup differently on each distribution).
The []
character set wildcards. e.g. ls name[03][17].c
, would match name01.c
, name07.c
, name31.c
, name37.c
, and []
also allows ranges: ls name[07][1-9].c
Note the use of \ls
to run the bare command, ignoring an alias.
The -F
appends an indicator (one of */=>@|
) to entries
color=always
vs color=auto
.
ls
is quite awkward with respect to recursion, e.g. ls *
will look into every subfolder even without the -R
flag, and ls c*
would look through every folder starting c
.
Never use the output of an ls
in a for i in ls
as that can be unpredictable.
Don't want to do anything obscure with aliases, follow widely used settings for ls
, ll
, l
, then have additional aliases for other tasks.
[[ $(type ls) == *"aliased"* ]] && then unalias ls
: Don't need this, but in general on testing for typealias
to act upon themalias ls='\ls --color=always --group-directories-first
':l
will print the normalls
in most distros (i.e. will not show.*
files!). Note that\
before a command revets a command back its non-aliased form.alias l='ls -AFh --color=always --group-directories-first'
: Using-A
(almost all, ignores./
and../
, but show all.*
files, putting this tols
as almost always want to see.*
files)alias la='ls -Ah'
: long format (-AFh
and also-l
): Note that the abovel
alias uses\ls
to run ls bare without flags (to remove-A
mainly)alias ll='ls -lAh'
: long format (-AFh
and also-l
): Note that the abovel
alias uses\ls
to runls
bare without flags (to remove-A
mainly)
alias l.='ls -d .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag
alias ls.='ls -d .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag, long format
alias ll.='ls -dl .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag, long format
alias lld='ls -FlA | grep :*/' # Only directories
alias llf='ls -FlA | grep -v "/"' # Only files (broken as will show symlinks etc, if have to use `/`, then `/$` would be better, but using grep at all is probably not optimal)
alias ldot="ls -ld .??*" # Dotfiles only
alias lx="ls -FlA | grep *" # Executable files only, below 'lxext' is just trying to find 'executable-like' files by their extension
alias lnox="ls -FlA | grep -v *" # Everything except executable files
alias lxext='ll *.sh *.csh *.ksh *.c *.cpp *.py *.jar *.exe *.bat *.cmd *.com *.js *.vbs *.wsh *.ahk *.ps1 *.psm1 2> /dev/null' # List possible executables and scripts by extensions, discarding error output (as will generate for every type that is not there)
alias lext='ls -Fla | egrep "\."' # Files without extensions only ".|/"
alias lnoext='ls -Fla | egrep -v "\."' # Files without extensions only
alias lsp='find . -maxdepth 1 -perm -111 -type f' # List executable by permissions. ls -lsa | grep -E "[d\-](([rw\-]{2})x){1,3}" https://stackoverflow.com/q/7812324
alias lsum="ls -Fla \$1 \$2 \$3 \$4 \$5 | awk '{ print; x=x+\$5 } END { print \"total bytes = \",x }'" # ls on required info then awk will sum the sizes
alias lll='ls --human-readable --size -1 -S --classify' # Long-list with just size and name and total size summary line
alias lm='ls -Am'; alias lcsv='lm' # comma separated view (-m), -A almost all, except '.' and '..'
alias lsz='ls -lAshSr'; alias lsize='lsz' # -s size, -h human readable, -S by size, -r reverse so largest are easily visible at end
alias lt='ls -lAth' ; alias ltime='lt'; alias ldate='lt'; alias lst='lt' # sort by -t time/date, human readable
# replicate 'ls', but using 'stat' to show both normal 'ls' permission flags *and* octal.
lsec() { if [ -z "$@" ]; then args='. .*'; else args="$@"; fi; stat --printf="%A\t%a\t%h\t%U\t%G\t%s\t%.19y\t%n\n" $args; }; alias lstat='lsec';
lperm() { if [ -z "$@" ]; then args='. .*'; else args="$@"; fi; stat --printf="%A %a %n\n" $args; }; # Just permissions, %A (ls format), %a (Octal format) and names
sanitize() { chmod -R u=rwX,g=rX,o= "$@" ;} # Make directory and file access rights the same
alias 000='echo "---------- (Owner -, Group -, and Other -)"; chmod 000' # Remove permissions: append with file/directory to apply to
alias 644='echo "-rw-r--r-- (Owner rw, Group r, and Other r)"; chmod 644' # Onwer rw, everyone else read-only
alias 755='echo "-rwxr-xr-x (Owner rwx, Group r-x, and Other r-x)"; chmod 755' # Make executable, but only Owner has write permissions
alias mx='chmod a+x' # Make Executable
alias lls='lss' # Since the 'stat' output is in long format 'll', also use 'lls' for 'long listing with ecurity'
alias sl='ls' # Common typo, also just overwrite the 'Steam Locotomive' toy if present, as that gets boring
alias lg='exa -lG' # 'ls grid', exa is an interesting potential successor to 'ls', in Ubuntu 20.10 repo by default, colours each permission item and -lG is a useful 2x column long view.
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null; then
for d in /mnt/[a-z]; do [ -d /mnt/$(basename ${d}) ] && alias "$(basename ${d}):"="cd $d"; done # "d:" => cd to /mnt/d
for d in /mnt/[a-z]; do [ -d /mnt/$(basename ${d}) ] && alias "l$(basename ${d}):"="cd $d && ll"; done # "ld:" => cd to and list d:""
fi
ls
in a shell loop is more to do with the output being potentially ambiguous, in particular with filenames containing newlines. And the fact that something like$(ls *.txt)
could just be replaced with*.txt
, since it's the shell that expands the glob, and thels
there would just repeat what it got on the command line. A bit like if you did$(echo *.txt)
. – ilkkachu Oct 12 '21 at 11:42ls -FlA | grep *"
does not do what you think it does, again because the shell expands the*
... – ilkkachu Oct 12 '21 at 11:45ls
, and possibly the way that wildcards interact with the filesystem, often make these quite difficult to achieve. In a way, my collection of aliases here is also a means for me to have an effective library of techniques that will answer these questions. – YorSubs Oct 12 '21 at 11:56/
since that is part of path definitions and\0
(null). Everything else is fair game and has been since long before Linux was developed. – terdon Oct 12 '21 at 12:02ls | grep
without too many ill effects if your know your files don't have newlines, and you only e.g. clone git trees from sensible people. I mean, part of the reason people do it is that they can get away with it. But of course unix.SE has a tendency of being a bit more strict about things like that, if only for the possibility of encountering such abominations. (Or highlighting the suckiness of most POSIX-like shells and other tools...) – ilkkachu Oct 12 '21 at 14:46