Search code examples
bashshellshzshls

Create a custom `ls` but only for manual use


I'm thinking of writing my own ls command. Mostly as a learning experience, but I also think I can make it a bit more useful (for me) than the default.

I'm worried though that if I alias ls, this also interferes with any bash/sh scripts that use ls as it's output.

Is there a way to override ls, but only when it's not used in scripts (or pipes?)


Solution

  • You're worried that aliasing your version of ls will interfere with other processes.

    Let's have a look at the POSIX standard.

    From the man page of alias:

    Historical versions of the KornShell have allowed aliases to be exported to scripts that are invoked by the same shell. This is triggered by the alias −x flag; it is allowed by this volume of POSIX.1‐2008 only when an explicit extension such as −x is used. The standard developers considered that aliases were of use primarily to interactive users and that they should normally not affect shell scripts called by those users; functions are available to such scripts.

    So, what does "normally" mean for bash? For instance, which version of ls would be used inside a shell script?

    From the man page of bash:

    Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS below).

    That means, you don't have to worry about shell scripts - they will use the unaliased version of ls.

    But what about pipes? Again, we can combine those two man pages for great good:

    From the man page of bash:

    Each command in a pipeline is executed as a separate process (i.e., in a subshell).

    From the man page of alias:

    An alias definition shall affect the current shell execution environment and the execution environments of the subshells of the current shell. When used as specified by this volume of POSIX.1‐2008, the alias definition shall not affect the parent process of the current shell nor any utility environment invoked by the shell

    That is, while your alias will not be used inside shell scripts, it will be used in pipes.