9

Is there any way to add custom commands to /bin?

For example, I use docker container ls a lot, and would like to turn this into a shortcut command, like dcls.

If I add a file named dcls to /bin and inside the file, specify the exact command docker container ls, I assume this wouldn't work.

What is the right way, if there is one, to do something like this?

alex067
  • 193
  • 6
    Don't add to /bin, you can add to ~/bin (a bin in your own directory), or to /usr/local/bin (to share with all users of your system, but not interfere with package manager). Or better in this case, to use an alias. – ctrl-alt-delor May 03 '19 at 08:45

3 Answers3

27

An easy way for a shortcut is to define an alias

alias dcls='docker container ls'

This will execute docker container ls when you enter dcls and the command alias lists your defined aliases. To remove this alias use unalias dcls.

If you use bash, you can save the alias in your ~/.bashrc or ~/.bash_aliases.

If your ~/.bash_aliases is not read on startup, you can add this line to your ~/.bashrc:

[ -f ~/.bash_aliases ] && . ~/.bash_aliases
Freddy
  • 25,565
  • Thanks Freddy! Will I have to create this alias every time the server restarts? Or is it bounded to my user profile? – alex067 May 02 '19 at 23:37
  • 2
    You have to save it in your user's shell startup file ~/.bashrc or ~/.profile or ... If you don't save the alias it is lost when you logout or close the terminal. – Freddy May 02 '19 at 23:51
  • Thanks again. What if we dont have .bashrc or .profile in our ~ folder? – alex067 May 03 '19 at 00:04
  • 1
    Really? What an odd server! If you use bash, you can create it using echo "alias dcls='docker container ls'" >> ~/.bashrc, then source it with . ~/.bashrc or logout and login again. – Freddy May 03 '19 at 00:10
  • Cheers for your help, got it working! – alex067 May 03 '19 at 00:11
17

Actually, what you describe would work, with a few notes:

  1. You could simply put docker container ls into a file called /bin/dcls.  But the behavior of that can be a little complicated.  It’s a little more reliable to begin the file with a line called a “shebang”, so the file would look like
    #!/bin/sh
    docker container ls
    which specifies that the file is a shell script.
  2. Before you can run the command, you must make the file executable with a command like
    chmod +x /bin/dcls

    You probably need to be root to do this (i.e., run it with sudo).

  3. Follow the above two steps and you will be able to type dcls and it will do docker container ls. But, if you type dcls -l foo, it will still do docker container ls.  If you want it to do docker container ls -l foo, you should change the script to say

    #!/bin/sh
    docker container ls "$@"
    which specifies that any arguments that you type on the dcls command line should be passed along to the docker container ls command.

    Naturally, there are more complicated things you can do with command-line arguments.

For a mapping of one simple command → one simple command, that doesn’t need to be shared with other users, it’s simpler to define an alias (as Freddy suggested), or a shell function.  More complicated functions are often written as scripts; i.e., text files that contain commands.  But, if you don’t need to share it with other users, it’s more common to use a private bin directory.

$ cd                                    # (to your home directory)
$ mkdir bin
Then copy dcls to $HOME/bin, and add
export PATH="$HOME/bin:$PATH"
to your ~/.bashrc.

Also, it’s common to put personal scripts into /usr/local/bin, and leave /bin for the programs that came with the system.

  • Great answer. If I add it to bin like I mentioned, that would affect all users correct? – alex067 May 03 '19 at 00:55
  • Yes; all users look in /bin, /usr/bin, and typically shared directories like /usr/local/bin and sometimes /opt, so programs in those directories are available to all users. – G-Man Says 'Reinstate Monica' May 03 '19 at 02:57
  • 1
    If you want to share with others on you system use /usr/local/bin so it does not interfere with package manager. – ctrl-alt-delor May 03 '19 at 08:47
  • 5
    +1 for recommending $HOME/bin. You should really use this. This is not only the right scope, but helps when you reinstall your system (and keep your HOME) not to lose your custom command. – allo May 03 '19 at 08:52
  • I prefer this over alias because sooner or later you would want write a command longer than 1 line. Also, the command can be implemented using a language other than shell. – Alex Vong May 03 '19 at 12:28
  • 1
    FWIW I use ~/.local/bin instead. – Sparhawk May 04 '19 at 05:53
  • Save one PID by prepending the command with exec. – iBug May 04 '19 at 08:06
1

If just for you, an alias is fine but according to the Linux Filesystem Hierarchy Standard local system-wide scripts go in /usr/local/bin/, not /bin.

  1. Although it would certainly work in /bin, it's better to keep to standards especially if your software is going to be deployed at customer's sites.
  2. If your script would be optional, it should go in /opt
  3. The script itself would be:

    #!/bin/bash
    #
    # Version 1.0 DD 2019-05-04
    # dcls = docker container ls
    docker container ls "@0"
    if [[ $? -eq 0 ]]; then
      echo -e "Errors encountered..."
      exit 1
    fi
    
Fabby
  • 5,384