7

This question already has an answer here:

I know how to create my custom terminal commands and that would be really useful for me in compiling all my java classes in a folder. I also see that for doing this people usually creates a folder ~/bin and put files .sh with the lines they wish they run, but I could not understand it well, I create a compile.sh with some lines for example

-gcc file -o file
-gcc file1 -o file1

but as I was reading I also need to add a line to a file called .bashrc that is hidden in my home folder and I don't know how to do that, is there any way easier of editing this file? After I do it, my custom command will be the name of the .sh file (compile)?

marked as duplicate by Braiam, muru command-line Jun 21 '16 at 5:30

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    I think you're interested in basic shell scripting; there are plenty of tutorials and resources online if you search for "linux basic shell scripting" (or similar). The existing resources can likely explain it more clearly and thoroughly than we can here – Nick Weinberg Jun 20 '16 at 21:57
  • 1
    Once you know how to create your own scripts, stop and find a simple tutorial for make. It's the right tool for controlling compilation of your projects. – alexis Jun 21 '16 at 0:59
  • Urgh, I hate the dupe hammer sometimes. The dupe is for this part: "[I] need to add a line to a file called .bashrc that is hidden in my home folder and I don't know how to do that, is there any way easier of editing this file" - what you mean to do is add your command to the PATH. – muru Jun 21 '16 at 5:32
8

The easiest way to make Bash scripts that are available to all users of your computer is to place them in /usr/local/bin. This requires you to have admin privileges though.

  1. Create you script:

    Open your favourite text editor and write all the commands you wish the script to run, one command per line.

    You can add comments to Bash scripts by beginning a line with #.

    When you're done, add this exact line below as first line at the top of your script. It's called a "shebang" and tells the shell with which interpreter to execute your script.

    #!/bin/bash
    

    Here's a simple example of a full script, running the two commands you mentioned in your question:

    #!/bin/bash
    
    # Compile 'file':
    gcc file -o file
    # Compile 'file1':
    gcc file1 -o file1
    
  2. Move your script to the correct location:

    The location where you should place own scripts for all users is /usr/local/bin.

    As this directory is owned by user root, you must be an admin and use sudo to move files there.

    I assume you created your script in your home directory, ~/my_script.sh. Simply open a terminal and type the command below, replacing SCRIPTNAME with the name you want to give it. This name will be the command you have to type to run it. The .sh file extension is not necessary.

    sudo mv ~/myscript.sh /usr/local/bin/SCRIPTNAME
    
  3. Set the correct owner and permissions:

    The script should be owned by and writable for root, but readable and executable for everyone. The two commands below ensure this:

    sudo chown root: /usr/local/bin/SCRIPTNAME
    sudo chmod 755 /usr/local/bin/SCRIPTNAME
    
  4. Run your script and enjoy:

    Now you can simply type SCRIPTNAME (or however you called it) to your terminal and the script will get executed.

  • 1
    a lot of this fooling around can be avoided by putting things in ~/.local/bin instead; Ubuntu (and maybe Debian?) automagically links dot-folders in the home directory to where they would be off of /usr/. Main advantage there is your home directory becomes portable between upgrades (especially if mounting the home directory separately) so you never lose the custom little commands. – Andrew Keech Jun 20 '16 at 23:11
  • 2
    @AndrewKeech I just tried that and it didn't work. A better place for user scripts is ~/bin, because Ubuntu will automatically add it to $PATH. See here. – wjandrea Jun 20 '16 at 23:43
  • I did everything in this answer and worked really well to me but Andrew's way also didn't work here @wjandrea – Vitor Falcão Jun 21 '16 at 1:08
  • oh quite right! looking at my own $PATH I must have added /home/<user>/.local/bin myself. Whatever the case, I feel it's best to put anything that you make yourself somewhere in ~/ to keep it during wipe-clean upgrades – Andrew Keech Jun 21 '16 at 1:29
  • 1
    @VitorCosta wjandrea's suggestion will work; I also recommend putting custom scripts in ~/bin rather than /usr/local/bin for portability. – edwinksl Jun 21 '16 at 2:20
4

While writing scripts is a very convenient way to execute many commands from one file , I would suggest using functions where it requires just one or two commands.

Take for example function definition bellow

compile()
{
  gcc "$1" -o "${1%%.*}" && printf "<<< Compiled successfully\n"
}

By placing it into your .bashrc file (and then running source ~/.bashrc or opening new terminal tab) , you can run this command from anywhere without having ~/bin added to your PATH variable, and provide a filename as command line argument like so

compile somecode.c

On a side note, you can edit that file just by calling gedit ~/.bashrc from command line

For those of you wondering what does "$1" and "${1%%.*}" , the "$1" refers to the first command line parameter ( in this case "somecode.c" ), as for "${1%%.*}" - that's parameter expansion , particularly the one that does suffix removal , and will throw away anything after the dot. In other words , that turns somecode.c into somecode . For more info, read bash manual page section about parameter expansion

  • ~/bin is in $PATH by default. See here. – wjandrea Jun 21 '16 at 16:42
  • 1
    1. ~/bin is there by default because .bashrc sources .profile ; it's not there by default if you or your sysadmin decide to use a different shell and 2. That's not the point. The point is that writing shell functions over scripts has some advantages – Sergiy Kolodyazhnyy Jun 21 '16 at 17:34
  • I am a little bit lazy to learn bash now, would you mind telling me the comand I would put to run after compile @Serg ? – Vitor Falcão Jun 22 '16 at 22:24
  • What do you mean ? – Sergiy Kolodyazhnyy Jun 22 '16 at 22:27
3

Before getting into this, I wanted to clarify that you're not creating new commands, you're creating scripts that can be run as executables. But they can behave in the same way as a command because you can run them from anywhere.

If you don't have a folder in your home folder called "bin", create one.

Now open a terminal window and type nano ~/.bashrc.

This will open an editor. At the bottom of this file, add a new line that says PATH="$HOME/bin:$PATH".

Now save the file by pressing CTRL+O (the letter o, not zero), then press ENTER. Exit the editor with CTRL+X. Logout and back in for changes to take effect, or restart your computer if that doesn't work.

Now any scripts you create in your bin folder will be accessible anywhere in a terminal window.

You can create these scripts with either nano, or gedit (the Ubuntu graphical text editor) or any text editor you wish. Just remember to save your script in the ~/bin folder and make your file executable. There 2 ways to do this:

GUI : Right click the file and go to the permissions tab, and check the box "Allow executing as a program".

TERMINAL : chmod +x /location/of/your/file

  • This is good advice, but executable scripts are new commands. – alexis Jun 21 '16 at 0:58
  • @alexis I disagree. A script is a script. A script runs commands. Bash has a set of commands that you can run using a programming language in the form of a script. – Dorian Jun 21 '16 at 3:23
  • Some of those commands (which are not provided by bash, but by the Unix environment) are themselves shell scripts :-) Have you looked in /usr/bin recently? Call them whatever you want, but don't correct the OP for calling them commands. – alexis Jun 21 '16 at 8:52

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