Skip to content

Instantly share code, notes, and snippets.

@eggbean
Last active March 4, 2024 14:12
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save eggbean/74db77c4f6404dd1f975bd6f048b86f8 to your computer and use it in GitHub Desktop.
Save eggbean/74db77c4f6404dd1f975bd6f048b86f8 to your computer and use it in GitHub Desktop.
Now moving from exa to eza fork. Wrapper script to give it nearly identical switches and appearance to ls. Also automatically adds --git switch when in a git repository.
#!/bin/bash
## Change following to '0' for output to be like ls and '1' for eza features
# Don't list implied . and .. by default with -a
dot=0
# Show human readable file sizes by default
hru=1
# Show file sizes in decimal (1KB=1000 bytes) as opposed to binary units (1KiB=1024 bytes)
meb=0
# Don't show group column
fgp=0
# Don't show hardlinks column
lnk=0
# Show file git status automatically (can cause a slight delay in large repo trees)
git=1
# Show icons
ico=0
# Show column headers
hed=0
# Group directories first in long listing by default
gpd=0
# Colour always even when piping (can be disabled with -N switch when not wanted)
col=1
help() {
cat << EOF
${0##*/} options:
-a all
-A almost all
-1 one file per line
-x list by lines, not columns
-l long listing format
-G display entries as a grid *
-k bytes
-h human readable file sizes
-F classify
-R recurse
-r reverse
-d don't list directory contents
-D directories only *
-P group directories first *
-I ignore [GLOBS]
-i show inodes
-o show octal permissions *
-N no colour *
-S sort by file size
-t sort by modified time
-u sort by accessed time
-c sort by created time *
-X sort by extension
-M time style [iso|long-iso|full-iso|relative] *
-T tree *
-L level [DEPTH] *
-s file system blocks
-g don't show/show file git status *
-O don't show/show icons *
-n ignore .gitignore files *
-b file sizes in binary/decimal (--si in ls)
-Z show each file's security context
-@ extended attributes and sizes *
* not used in ls
EOF
exit
}
[[ $* =~ --help ]] && help
eza_opts=()
while getopts ':aAbtucSI:rkhnsXL:M:PNg1lFGRdDioOTxZ@' arg; do
case $arg in
a) (( dot == 1 )) && eza_opts+=(-a) || eza_opts+=(-a -a) ;;
A) eza_opts+=(-a) ;;
t) eza_opts+=(-s modified); ((++rev)) ;;
u) eza_opts+=(-us accessed); ((++rev)) ;;
c) eza_opts+=(-Us created); ((++rev)) ;;
S) eza_opts+=(-s size); ((++rev)) ;;
I) eza_opts+=(--ignore-glob="${OPTARG}") ;;
r) ((++rev)) ;;
k) ((--hru)) ;;
h) ((++hru)) ;;
n) eza_opts+=(--git-ignore) ;;
s) eza_opts+=(-S) ;;
X) eza_opts+=(-s extension) ;;
L) eza_opts+=(--level="${OPTARG}") ;;
o) eza_opts+=(--octal-permissions) ;;
M) eza_opts+=(--time-style="${OPTARG}") ;;
P) ((++gpd)) ;;
N) ((++nco)) ;;
g) ((++git)) ;;
O) ((++ico)) ;;
b) ((--meb)) ;;
1|l|F|G|R|d|D|i|T|x|Z|@) eza_opts+=(-"$arg") ;;
:) printf "%s: -%s switch requires a value\n" "${0##*/}" "${OPTARG}" >&2; exit 1
;;
*) printf "Error: %s\n --help for help\n" "${0##*/}" >&2; exit 1
;;
esac
done
shift "$((OPTIND - 1))"
(( rev == 1 )) && eza_opts+=(-r)
(( fgp == 0 )) && eza_opts+=(-g)
(( lnk == 0 )) && eza_opts+=(-H)
(( hru <= 0 )) && eza_opts+=(-B)
(( hed == 1 )) && eza_opts+=(-h)
(( meb == 0 && hru > 0 )) && eza_opts+=(-b)
(( col == 1 )) && eza_opts+=(--color=always) || eza_opts+=(--color=auto)
(( nco == 1 )) && eza_opts+=(--color=never)
(( gpd >= 1 )) && eza_opts+=(--group-directories-first)
(( ico == 1 )) && eza_opts+=(--icons)
(( git == 1 )) && \
[[ $(git -C ${*:-.} rev-parse --is-inside-work-tree) == true ]] 2>/dev/null && eza_opts+=(--git)
eza "${eza_opts[@]}" "$@"
@eggbean
Copy link
Author

eggbean commented Apr 7, 2021

@tachoknight You can make an alias to replace ls by adding this to your ~/.bash_aliases file (assuming it is called exa-wrapper.sh and you are using bash):

if command -v exa >/dev/null; then
    alias ls="exa-wrapper.sh"
else
    alias ls="command ls $LS_OPTIONS"
fi

@tachoknight
Copy link

I considered making an alias but I have a number of jobs that make use of ls output with awk that would break, so I opted to leave ls as-is and go with something only I'd know. I'm also experimenting with ks as it's just one key over from l. Definitely need to work on the muscle memory!

@curoky
Copy link

curoky commented Jan 19, 2023

Very great script 🥳, just found a small problem, it seems that ((meb == 0)) && exa_opts+=(-b) should be changed to ((meb == 1)) && exa_opts+=(-b).

@eggbean
Copy link
Author

eggbean commented Jan 20, 2023

@curoky Thanks for spotting that. I only added that option recently and I think I got confused with what the ls default was. It was the top option that was the wrong way around. I've also add a -b switch to toggle.

@martin-braun
Copy link

@tachoknight Aliases should not be available within scripts though, so you can alias ls without your scripts breaking.

@martin-braun
Copy link

@eggbean How to do --icons --time-style long-iso --git --group-directories-first with this wrapper by using flags?

I see there are no flags for it, instead I need to modify the script. Why not simply making our own flags to set those options as well?

@eggbean
Copy link
Author

eggbean commented Oct 16, 2023

@martin-braun The options for those are at the top of the script, apart from --time-style which I think must be quite new. I might add something for that. There are also flags for --group-directories-first (-M) and --git (-g).

@martin-braun
Copy link

@eggbean --time-style is not new. How about -I for --icons and -T .... for --time-style ....?

@eggbean
Copy link
Author

eggbean commented Oct 16, 2023

-I is already used in ls for --ignore=PATTERN, which I've replicated here. -T is being used for --tree and is the eza default. I'm actually thinking about a way to incorporate --time-style at the moment, but we're running out of letters. Any other ideas for it?

I think most people would choose to have icons or not and then just stick with that decision. I don't use them myself.

@eggbean
Copy link
Author

eggbean commented Oct 16, 2023

@martin-braun I've changed --group-directories-first to -P and used -M for --time-style.

@martin-braun
Copy link

Thank you @eggbean. The reason why I ask for having a flag to toggle icons is I cloned your gist and want to keep it up to date without maintaining a fork, so that I can update it without much hassle in case you improve it further. Sorry about the -I, I absolutely missed it. The swap between -P and -M seems fine to me. For --icons we could use the -C. Alternatively, I would enjoy if you could allow environment variables with strong prefix, i.e. EZA_ICONS=1 eza-wrapper.sh. If I can alias it without touching the script itself, I'd be happy. :)

@eggbean
Copy link
Author

eggbean commented Oct 18, 2023

@martin-braun -C is used in ls for columns and I think it should be reserved for any possible column options in eza, so I've added an -O option for icons. I don't understand why you couldn't just change the top option to ico=1 though.

@martin-braun
Copy link

@eggbean Thank you. As I said, I cloned your gist. You can actually clone it via git clone. I don't want to drag working changes. Thanks a lot. :)

@eggbean
Copy link
Author

eggbean commented Oct 18, 2023

@martin-braun Oh, so that's the reason? Then I could revert this change and just make ico=1 the default? I would prefer to do that as I think this flag is unnecessary.

@martin-braun
Copy link

martin-braun commented Oct 20, 2023

@eggbean Yes you could, but what if somebody else want's to use the script in the same fashion, but don't like icons? Having a flag ultimately allows anyone to simply alias it properly, so I have to say, I really like that you introduced those flags, so I vote for keeping it this way. Thank you =)

@oxo-real
Copy link

oxo-real commented Nov 10, 2023

The lastest update of eza unfortunately broke eza-wrapper.sh (https://gist.github.com/eggbean/74db77c4f6404dd1f975bd6f048b86f8).

I now get the following error messages:
ls >> eza: Option --color-scale has no "-g" setting (choices: all, size, age)
ls -a >> eza: Option --color-scale has no "-a" setting (choices: all, size, age)
downgrading package eza (0.15.3-1 => 0.15.2-1) makes if work again.

Can please someone guide me when this is an easy fix? Thanks!

EDIT:
removing --color-scale from the last line seems to resolve this issue.
But does this break something else?

@eggbean
Copy link
Author

eggbean commented Nov 10, 2023

@oxo-real I have updated the script. It should be okay now? The --color--scale option just makes some gradient colours for the file sizes and/or relative dates.

--UPDATE Actually, I have removed the option for now, as I don't like these colours they have chosen. It's very distracting. I'll have to see what to do about this.

@oxo-real
Copy link

I agree, the color-scale option is not for me either.

@oxo-real
Copy link

oxo-real commented Nov 17, 2023

Release eza v0.16.0 · eza-community/eza · GitHub resolved the --color-scale issue mentioned before.

@eggbean
Copy link
Author

eggbean commented Nov 20, 2023

@oxo-real Thanks, but I'm going to keep it disabled for now, as the colours used for this are far too contrasty in my opinion. They should be much more subtle and not be so distracting.

@martin-braun
Copy link

@eggbean I have another suggestion for this great wrapper: Change the bang to #!/usr/bin/env sh and make the script POSIX compliant for the best portability. It seems there is not really much to it, except for porting the test expression [[ to [, or did I miss something?

@eggbean
Copy link
Author

eggbean commented Jan 16, 2024

@martin-braun Quite a lot would have to be changed and it'll be a more complex and less readable as a result. No arrays, no (( arithmetic expansion )), no =~ regex, $(process substitution) would need to be changed to `backticks` and I think getopts works differently. And then what would it be more portable for? It already can run on the old bash 3.2 that's installed on macOS. The zealots that I have met who only use sh and nothing as extravagant as bash would never use something as ostentatious as eza anyway😆 Thanks for the idea though.

@martin-braun
Copy link

martin-braun commented Jan 17, 2024

@eggbean Use case would be Alpine Linux, that doesn't ship with bash, but has eza available in its repository. It's probably neglectable, but I felt it was worth pointing out. 🥲

@eggbean
Copy link
Author

eggbean commented Jan 17, 2024

I see. I only use that docker containers. apk add bash only adds 3336 KiB, but I'd be surprised if minimalists who use it as a desktop OS would use eza.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment