166

I am trying to create an aliases in bash. What I want to do is map ls -la to ls -la | more

In my .bashrc file this is what I attempted:

alias 'ls -la'='ls -la | more'

However it does not work because (I assume) it has spaces in the alias name. Is there a work around for this?

1
  • 11
    Why not do alias lsm='ls -la | more'
    – Nifle
    Feb 5, 2010 at 22:52

4 Answers 4

192

The Bash documentation states "For almost every purpose, shell functions are preferred over aliases." Here is a shell function that replaces ls and causes output to be piped to more if the argument consists of (only) -la.

ls() {
    if [[ $@ == "-la" ]]; then
        command ls -la | more
    else
        command ls "$@"
    fi
}

As a one-liner:

ls() { if [[ $@ == "-la" ]]; then command ls -la | more; else command ls "$@"; fi; }

Automatically pipe output:

ls -la
12
  • 2
    why do you need to use double brackets inside the if statement? Feb 8, 2010 at 14:55
  • 5
    @sixtyfootersdude: The double-bracket form is more powerful and I use it by habit. See mywiki.wooledge.org/BashFAQ/031 Feb 8, 2010 at 18:35
  • 1
    @Jeef: No, my answer uses a function instead of an alias. I have edited it to try to make it clearer. Apr 1, 2015 at 14:14
  • 13
    @merlinpatt: command prevents the function from being called recursively. Mar 13, 2016 at 18:05
  • 1
    @Simonlbc To make sure that tutorials online will surely work on my environment. Maybe more of a personal choice. Aug 9, 2016 at 19:19
73

From the alias man page:

The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The alias name and the replacement text may contain any valid shell input, including shell metacharacters, with the exception that the alias name may not contain `='.

So, only the first word is checked for alias matches which makes multi-word aliases impossible. You may be able to write a shell script which checks the arguments and calls your command if they match and otherwise just calls the normal ls (See @Dennis Williamson's answer)

3
  • 11
    +1 For explaining why I am not allowed to use ls -la as an alias. Feb 8, 2010 at 14:49
  • 10
    This was helpful because instead of trying to solve it it answered the question. I came here because i wanted to create an alias with a space in it and that just won't happen. Feb 11, 2014 at 21:15
  • 2
    This not only answered my question, but gave me valuable insight into how the aliasing mechanism actually works. Your quote from the man page was quite helpful. Jan 21, 2019 at 14:32
23

A slightly improved approach taken from Dennis' answer:

function ls() {
  case $* in
    -la* ) shift 1; command ls -la "$@" | more ;;
    * ) command ls "$@" ;;
  esac
}

Or the one-liner:

function ls() { case $* in -la* ) shift 1; command ls -la "$@" | more ;; * ) command ls "$@" ;; esac }

This allows for further options/arguments to be appended after the command if needed, for example ls -la -h

2
  • 2
    How does this handle if I want ls -lat to be excluded from this treatment? I would need to put a case to handle it above the -la* entry, yes?
    – Steven Lu
    Apr 28, 2014 at 5:36
  • Thanks. Useful for me with docker : function d() { case $* in c* ) shift 1; command docker container "$@" ;; n* ) shift 1; command docker network "$@" ;; * ) command docker "$@" ;; esac } . But unfortunately autocomplete won't work
    – trogne
    Oct 11, 2020 at 19:36
-1

You can invoke this alias still, but you need quotation in order that the space is part of the command word. So "ls -la" -p pattern will pass the -p pattern option to more, not ls.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .