13

I am planning to create a function that would simplify things for me. The function would be something like

function lazymode()
{
echo "Hello World!";
}

so that when I use the command lazymode in the shell , it will output the Hello World!.

What file should I put the user-defined function?

12

Depends on the function. If it's just a super-simple one-liner like that you could create an alias or stick the function in ~/.bashrc (a file that bash loads when it starts).

If you're creating something a bit more meaty, it might make more sense to create its own executable script in ~/bin/ which won't exist by default (it's just a directory) but should be in your path. Remember for this the file will need to be executable (chmod +x filename) and start with a proper #!/bin/bash stanza.

The second route has some clear benefits:

  • It's easier to see what's available
  • A syntax error won't tank your profile
  • You don't need to keep re-sourcing your bash config if you change the script
  • It's available to any shell as long as the full path is used or ~/bin/ is in the path for that shell too (which it should be in most cases AFAIK).
  • I used the later option. My function contains commands that delete files, wget's something, executes the commands javac and java. and when I tried it on the gnome-terminal, it's not working fine. Do you think there is an issue? – Abel Melquiades Callejo Sep 12 '13 at 9:14
  • What does it do instead? – Oli Sep 12 '13 at 9:37
  • It's already fixed. Fixed through this answer – Abel Melquiades Callejo Sep 13 '13 at 17:02
  • umm... shouldn't user scripts be in the /usr/local/bin instead messing with the $PATH? – Braiam Sep 15 '13 at 2:28
  • It seems to me that a small but worth-mentioning advantage of putting functions in ~/.bashrc (as it is sourced) is that Bash looks for functions before doing PATH lookup. – Zanna Sep 27 '18 at 19:42
4

The best choice would be ~/.bashrc file.

You can either write your shell function definitions directly in your ~/.bashrc file, or, if you have lots of them and don't want to clutter your ~/.bashrc file, you can put them all in another file of your choosing -- just be sure to source that file in your ~/.bashrc file. For example, if the file with your functions is named bash_functions, simply add in your ~/.bashrc file the lines:

if [[ -f /path/to/bash_functions ]]; then
    source /path/to/bash_functions
fi

or, equivalently:

if [[ -f /path/to/bash_functions ]]; then
    . /path/to/bash_functions
fi

where the . is just a symbolic representation of source. The if test makes sure the file /path/to/bash_functions exists before trying to source it.

This technique is very similar to establishing aliases in ~/.bashrc by creating a file called ~/.bash_aliases and using similar syntax to that above in ~/.bashrc to test for its existence and then source it.

  • thanks, it worked. by the way, what is its difference with .profile? in some linux, I cannot put functions in bashrc – Abel Melquiades Callejo Sep 12 '13 at 8:15
  • 2
    ~/.profile file is executed by the command interpreter for login shells. When you use GUI and you open the terminal, that file is not executed because you will be in a not login shell. – Radu Rădeanu Sep 12 '13 at 8:18
1

Here's an essential procedure for declaring a permanent function:

  1. Open ~/.bashrc file in a text editor. Doesn't matter which text editor, so long as you know how to use it and so long as you open the /home/<username>/.bashrc

  2. At the end of the ~/.bashrc declare your own function, for instance:

    find_dirs(){
        find "$1" -type d
    }
    
  3. Save and close the file.

The ~/.bashrc file is read every time you open interactive shell (that is new terminal tab, login via ssh, or open TTY1 or other virtual console). This will not be available in script files, because ~/.bashrc is not read for non-interactive shells. It is also not available if you run bash with --norc option.

If you want the function to be available immediately in the currently open tab, use source ~/.bashrc command.


Functions take arguments just like regular commands. For example, $1 through $9 indicate the positional parameters when you call a function. In the example above find_dirs takes one positional parameter only, and would be called as find_dirs /etc. You can also use $@ to refer to all positional parameters. Functions also accept redirection. You can call a function with find_dirs $1 > /dev/null; we also could declare it as follows:

find_dirs(){
    find "$1" -type d
}

Note from man bash: "Functions are executed in the context of the current shell; no new process is created to interpret them". That means that you also should be aware of functions having ability to alter your shell execution environment - change variables and terminal settings.

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.