3

I am trying to figure out how to add new runtime flags to commands that are run from the terminal.

For eg. : I have recently started experimenting with Docker and find it tedious to clean up exited containers by copy pasting IDs. I want to add a command line option clean to the docker runtime, so that when I run docker clean (or perhaps docker --clean if we're going that way) I can internally map it to run a cleanup command with already supported options by the docker runtime (namely docker rm $(docker ps -a -q -f status=exited)) Is it possible to establish such a mapping?

I know one option is to use aliases, however aliases don't allow for having spaces / command line flags in the alias names, to the best of my knowledge. Similarly, shell functions don't help because they override the entire functionality (or perhaps I'm doing it wrong). I have wanted to explore this possibility for a while, so any help will be appreciated.

  • Probably what you need is a shell function - see Aliases - able to pass arguments? – steeldriver Sep 18 '16 at 13:02
  • Edited the original post. Functions don't help because they don't really allow me to add options to pre-existing executables. Instead it ends up overriding everything. – fwx Sep 18 '16 at 17:03
4

You can define a bash function with the same name as an executable, and have it process your additional parameter and call the original function unambiguously using the command builtin. From man bash:

command [-pVv] command [arg ...]
       Run  command  with  args  suppressing  the normal shell function
       lookup. Only builtin commands or commands found in the PATH  are
       executed.

To illustrate,

function ls() { 
  case "$1" in 
    "foo")  shift
            echo "do new thing with remaining args: $@" 
            ;; 
    *)      command ls "$@"
            ;;
  esac
}

Then

$ ls -ltr --color=always
total 12
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:16 subdir1
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:17 subdir2
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:17 subdir3

works as normal, whereas

$ ls foo -ltr --color=always
do new thing with remaining args: -ltr --color=always

(you may need to unalias the ls command in order to try this out).

Obviously a real-world implementation should do proper error checking - perhaps using getopts to process the entire command line rather than a simple switch/case on $1.


Alternatively (and more traditionally) you could achieve the same by writing a wrapper script and placing it somewhere that comes earlier in your $PATH than the original executable (such as /usr/local/bin or $HOME/bin). Within the wrapper, refer to the original executable by its absolute path.

  • 1
    I took inspiration from (see man less) the LESS environment variable, and have grouped my favorite options in environment variables, so I do pstree $PSTREE ..., dmesg $DMESG, sudo less $LESS ..., and Profit! – waltinator Sep 19 '16 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.