Differences between revisions 12 and 161 (spanning 149 versions)
Revision 12 as of 2007-05-22 12:50:38
Size: 13834
Editor: GreyCat
Comment: proofreading
Revision 161 as of 2011-05-10 18:04:45
Size: 7882
Editor: GreyCat
Comment: cleanup
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#acl GreyCat:read,write,revert,admin,delete Lhunath:read,write,revert pgas:read,write,revert All:read
[[BashGuide/CommandsAndArguments|Commands and Arguments ->]]
----
Line 2: Line 5:

'''You are invited to make additions or modifications so long as you can keep them accurate. Please test any code samples you write.'''
Line 5: Line 10:
["BASH"] is a BourneShell compatible shell, which adds many new features to its ancestor. Most of them are available in the 'KornShell', too. --------
<<Anchor(About)>>
= About This Guide =
Line 7: Line 14:
[[TableOfContents]] This guide aims to be a starting point for people interested in learning to work with [[BASH]]. It aspires to teach its readers good practice techniques for developing scripts for the [[BASH]] interpreter, and to educate them about the internal operation of [[BASH]].
Line 9: Line 16:
-----

== About This Guide ==

This guide aims to become a point of reference for people interested in learning to work with ["BASH"]. It aspires to teach its readers good practice techniques in developing scripts for the ["BASH"] interpreter and educate them about the internal operation of ["BASH"].

This guide is targetted at beginning users. It assumes no basic knowledge, but rather expects you to have enough common sense to put two and two together. If something is unclear to you, you should report this so that it may be clearified in this document for future readers.
This guide is targeted at beginning users. It assumes no advanced knowledge, but rather expects you to have enough common sense to put two and two together. If something is unclear to you, you are invited to report this (use BashGuideFeedback, or the `#bash` channel on `irc.freenode.org`) so that it may be clarified in this document for future readers.
Line 19: Line 20:
The primary maintainer(s) of this document:
Line 20: Line 22:
== A Definition ==  * -- [[Lhunath]] (primary author)
 * -- GreyCat
Line 22: Line 25:
["BASH"] is an acronym for '''''B'''ourne '''A'''gain '''Sh'''ell''. It is based on the ''Bourne'' shell and is mostly compatible with its features. The guide is also available in [[http://stuff.lhunath.com/BashGuide.pdf|PDF format]].
Alternatively, you can just hit print after going to [[FullBashGuide]]. That guarantees you'll be printing the latest version of this document.
Line 24: Line 28:
Shells are applications that provide users with the ability to give commands to their operating system interactively, or to allow them to execute batch processes quickly. In no way are they required for execution of processes, they are merely a layer between system function calls and the user. --------
<<Anchor(Definition)>>
= A Definition =

[[BASH]] is an acronym for '''''B'''ourne '''A'''gain '''Sh'''ell''. It is based on the ''Bourne'' shell and is mostly compatible with its features.

Shells are command interpreters. They are applications that provide users with the ability to give commands to their operating system interactively, or to execute batches of commands quickly. In no way are they required for the execution of programs; they are merely a layer between system function calls and the user.

Think of a shell as a way for you to speak to your system. Your system doesn't need it for most of its work, but it is an excellent interface between you and what your system can offer. It allows you to perform basic math, run basic tests and execute applications. More importantly, it allows you to combine these operations and connect applications to each other to perform complex and automated tasks.

[[BASH]] is '''not''' your operating system. It is not your window manager. It is not your terminal (but it oftens runs ''inside'' your terminal). It does not control your mouse or keyboard. It does not configure your system, activate your screensaver, or open your files when you double-click them. It is generally not involved in launching applications from your window manager or desktop environment. It's important to understand that [[BASH]] is only an interface for you to execute statements (using [[BASH]] syntax), either at the interactive [[BASH]] prompt or via [[BASH]] scripts.
Line 27: Line 41:
== Using Bash == --------
 . '''In The Manual: [[http://www.gnu.org/software/bash/manual/bashref.html#Introduction|Introduction]]'''
----
 . ''Shell'': A (possibly interactive) command interpreter, acting as a layer between the user and the system. <<BR>> ''[[BASH]]'': The Bourne Again Shell, a ''Bourne'' compatible shell.
Line 29: Line 46:
Most users that think of ["BASH"] think of it as a prompt and a commandline. That is ["BASH"] in ''interactive mode''. ["BASH"] can also run in ''non-interactive mode'' through scripts. We can use scripts to automate certain logic. Scripts are basically lists of commands that you can type on the commandline. When such a script is executed, all these commands are executed sequentially; one after another. --------
<<Anchor(Using_Bash)>>
= Using Bash =
Line 31: Line 50:
We'll start with the basics in an ''interactive shell''. Once you're familiar with those, you can put them together in scripts. Most users that think of [[BASH]] think of it as a prompt and a command line. That is [[BASH]] in ''interactive mode''. [[BASH]] can also run in ''non-interactive mode'', as when executing scripts. We can use scripts to automate certain logic. Scripts are basically lists of commands (just like the ones you can type on the command line), but stored in a file. When a script is executed, all these commands are (generally) executed sequentially, one after another.
Line 33: Line 52:
----- We'll start with the basics in an ''interactive shell''. Once you're familiar with those, you can put them together in scripts.
Line 35: Line 54:
= The Basics =

== Commands And Arguments ==

["BASH"] takes commands on the commandline. Commands can be different things. They can be application executables, aliases, function names, etc.

  * '''Application Executables''': ["BASH"] keeps a variable that tells it where to find the executables for certain applications. This variable is called `PATH`, and it usually contains `/bin:/usr/bin`. This is a string of pathnames separated by colons. Each path can contain executables. When a command is specified in ["BASH"] without a pathname (e.g. `ls`), ["BASH"] searches these paths for the executable for this command.
  * '''Aliases''': ["BASH"] can use aliases to make it easier to quickly execute complex commands. An alias is a ''name'' that is mapped to a certain ''string''. Whenever that ''name'' is used as a command in bash, it is replaced by the ''string''.
  * '''Functions''': Functions in ["BASH"] are much like aliases. When a command is executed by the name of a function, the code of that function is executed instead.

Each command can be followed by arguments. It is very important that you understand how this works exactly. If you don't grasp these concepts well, the quality of your code will degrade significantly and you will introduce very dangerous bugs. So, pay close attention in the next few chapters.
'''Important! <<BR>> You should make yourself familiar with the `man` and `apropos` commands on the shell. They will be vital to your self-tutoring.'''
Line 48: Line 57:
    $ ls
    a  b c
    $ man man
    $ man apropos
Line 52: Line 61:
`ls` is a command that lists files in the current directory. In this guide, the `$` at the beginning of a line represents your [[BASH]] prompt. Traditionally, a shell prompt either ends with `$`, `%` or `#`. If it ends with `$`, this indicates a shell that's compatible with the Bourne shell (such as a POSIX shell, or a Korn shell, or [[BASH]]). If it ends with `%`, this indicates a ''C shell'' (csh or tcsh); this guide does not cover C shell. If it ends with `#`, this indicates that the shell is running as the system's superuser account (`root`), and that you should be extra careful.

Your actual [[BASH]] prompt will probably be much longer than `$`. Prompts are often highly individualized.

The `man` command stands for "manual"; it opens documentation (so-called "man pages") on various topics. You use it by running the command `man [topic]` at the [[BASH]] prompt, where `[topic]` is the name of the "page" you wish to read. Note that many of these "pages" are considerably longer than one printed page; nevertheless, the name persists. Each command (application) on your system is likely to have a man page. There are pages for other things too, such as system calls or specific configuration files. In this guide, we will only be covering commands.

Note that if you're looking for information on [[BASH]] built-ins (commands provided by [[BASH]], not by external applications) you should look in `man bash` instead. [[BASH]]'s manual is extensive and detailed. It is an excellent reference, albeit more technical than this guide.

[[BASH]] also offers a `help` command which contains brief summaries of its built-in commands (which we'll discuss in depth later on).
Line 55: Line 72:
    $ mkdir d
    $ cd d
    $ ls
    $ help
    $ help read
Line 60: Line 76:
`mkdir` is a command that creates a new directory. We specified the argument `d` to that command. This way, the application `mkdir` is instructed to create a directory called `d`. After that, we use the application `cd` to change the current directory to `d`. `ls` shows us that the current directory (which is now `d`) is empty, since it doesn't display any filenames. --------
 . '''In the FAQ: <<BR>> [[BashFAQ/061|Is there a list of which features were added to specific releases (versions) of Bash?]]'''
----
 . ''Interactive mode'': A mode of operation where a prompt asks you for one command at a time.
 . ''Script'': A file that contains a sequence of commands to execute one after the other.
--------
Line 62: Line 83:
= Contents =
Line 63: Line 85:
== Commandline Argument Splitting == The guide has been divided into sections, which are intended to be read roughly in the order presented. If you skip ahead to a specific section, you might find yourself missing some background information from previous sections. (Links to relevant sections are not always provided when a topic is mentioned.)
Line 65: Line 87:
Commands in ["BASH"] can take multiple arguments. These arguments are used to tell the command exactly what it's supposed to do. In ["BASH"], you separate these arguments by whitespace (spaces, tabs and newlines).  * [[/CommandsAndArguments|Commands and Arguments]]
  * Types of commands; argument splitting; writing scripts.
 * [[/SpecialCharacters|Special Characters]]
 * [[/Parameters|Parameters]]
  * Variables; special parameters; parameter types; parameter expansion.
 * [[/Patterns|Patterns]]
  * Globs; filename matching; extended globs; brace expansion; regular expressions.
 * [[/TestsAndConditionals|Tests and Conditionals]]
  * Exit status; {{{&&}}} and {{{||}}}; if, test and {{{[[}}}; while, until and for; case and select.
 * [[/Arrays|Arrays]]
  * Arrays; associative arrays.
 * [[/InputAndOutput|Input and Output]]
  * Redirection; here documents; here strings; pipes; process substitution.
 * [[/CompoundCommands|Compound Commands]]
  * Subshells; command grouping; arithmetic evaluation; functions; aliases.
 * [[/Sourcing|Sourcing]]
  * Reading commands from other files.
 * [[/JobControl|Job Control]]
 * [[/Practices|Practices]]
  * Choosing your shell; quoting; readability; debugging.
Line 67: Line 108:
{{{
    $ ls
    $ touch a b c
    $ ls
    a b c
}}}

`touch` is an application that changes the 'Last Modified'-time of a certain file to the current time. If the filename that it's given does not exist yet, it simply creates that file, as a new and empty file. In this example, we passed three arguments. `touch` creates a file for each argument. `ls` shows us that three files have been created.

{{{
    $ rm *
    $ ls
    $ touch a b c
    $ ls
    a b c
}}}

`rm` is an application that removes all the files that it was given. ''*'' is a ''glob''. It basically means ''all files in the current directory''. You will read more about this later on.

Now, did you notice that there are several spaces between `a` and `b`, and only one between `b` and `c`? Also, notice that the files that were created by `touch` are no different than the first time. You now know that the amount of whitespace between arguments does not matter. This is important to know. For example:

{{{
    $ echo This is a test.
    This is a test.
    $ echo This is a test.
    This is a test.
}}}

In this case, we provide the `echo` command with four arguments. 'This', 'is', 'a' and 'test.'. `echo` takes these arguments, and prints them out one by one with a space in between. In the second case, the exact same thing happens. The extra spaces make no difference. To protect the whitespace properly, we need to pass the sentence as one single argument. We can do this by using quotes:

{{{
    $ echo "This is a test."
    This is a test.
}}}

Quotes group everything together and pass it as a single argument. This argument is 'This is a test.', properly spaced. `echo` prints this single argument out just like it always does.

Be very careful to avoid the following:

{{{
    $ ls
    The secret voice in your head.mp3 secret
    $ rm The secret voice in your head.mp3
    rm: cannot remove `The': No such file or directory
    rm: cannot remove `voice': No such file or directory
    rm: cannot remove `in': No such file or directory
    rm: cannot remove `your': No such file or directory
    rm: cannot remove `head.mp3': No such file or directory
    $ ls
    The secret voice in your head.mp3
}}}

You need to make sure you quote filenames properly. If you don't you'll end up deleting the wrong things! `rm` takes filenames as arguments. If you do not quote filenames with spaces, `rm` thinks that each argument is another file. Since ["BASH"] splits your arguments at the spaces, `rm` will try to remove each word.

Please have a good look at http://bash-hackers.org/wiki/doku.php?id=syntax:words if all this isn't very clear to you yet.


== Globs ==

Globs are a very important concept in ["BASH"], if only for their incredible convenience. Properly understanding globs will benefit you in many ways. Globs are basically patterns that can be used to match filenames or other strings.

Globs are composed of normal characters and meta characters. Meta characters are characters that have a special meaning. These are the basic meta characters:

  * '''*''': Matches any string, including the null string.
  * '''?''': Matches any single character.
  * '''[...]''': Matches any one of the enclosed characters.

Here's an example of how we can use glob patterns to expand to filenames:

{{{
    $ ls
    a abc b c
    $ echo *
    a abc b c
    $ echo a*
    a abc
}}}

["BASH"] sees the glob, for example `a*`. It ''expands'' this glob, by looking in the current directory and matching it against all files there. Any filenames that match the glob, are enumerated and replaced by the glob. As a result, the statement `echo a*` is replaced by the statement `echo a abc`, and is then executed.

["BASH"] will always make sure that whitespace and special characters are escaped properly when expanding the glob. For example:

{{{
    $ touch "a b.txt"
    $ ls
    a b.txt
    $ rm *
    $ ls
}}}

Here, `rm *` is expanded into `rm a\ b.txt`. This makes sure that the string `a b.txt` is passed as a single argument to `rm`, since it represents a single file. It is important to understand that using globs to enumerate files is nearly '''always''' a better idea than using `ls` for that purpose. Here's an example with some more complex syntax which we will cover later on, but it will illustrate the problem very well:

{{{
    $ ls
    a b.txt
    $ for file in `ls`; do rm "$file"; done
    rm: cannot remove `a': No such file or directory
    rm: cannot remove `b.txt': No such file or directory
    $ for file in *; do rm "$file"; done
    $ ls
}}}

Here we use the `for` command to go through the output of the `ls` command. The `ls` command results in a string `a b.txt`. The `for` command splits that string into arguments over which it iterates. As a result, for iterates over `a` and `b.txt`. Naturally, this is '''not''' what we want. The glob however expands in the proper form. It results in the string `a\ b.txt`, which `for` takes as a single argument.

["BASH"] also supports a feature called `Extended Globs`. These globs are more powerful in nature. This feature is turned off by default, but can be turned on with the `shopt` command, which is used to toggle '''sh'''ell '''opt'''ions:

{{{
    $ shopt -s extglob
}}}

  * '''?(list)''': Matches zero or one occurrence of the given patterns.
  * '''*(list)''': Matches zero or more occurrences of the given patterns.
  * '''+(list)''': Matches one or more occurrences of the given patterns.
  * '''@(list)''': Matches one of the given patterns.
  * '''!(list)''': Matches anything except one of the given patterns.

The list inside the parentheses is a list of globs separated by the `|` character. Here's an example:

{{{
    $ ls
    names.txt tokyo.jpg california.bmp
    $ echo !(*jpg|*bmp)
    names.txt
}}}

Our glob now expands to anything that does not match the `*jpg` or the `*bmp` pattern. Only the text file passes for that, so it is expanded.

Then, there is Brace Expansion. Brace Expansion technically does not fit in the category of Globs, but it is similar. Globs only expand to actual filenames, where brace expansion will expand to any permutation of the pattern. Here's how they work:

{{{
    $ echo th{e,a}n
    then than
    $ echo {/home/*,/root}/.*profile
    /home/axxo/.bash_profile /home/lhunath/.profile /root/.bash_profile /root/.profile
    $ echo {1..9}
    1 2 3 4 5 6 7 8 9
    $ echo {0,1}{0..9}
    00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
}}}


== Special Characters ==

There are several special characters in ["BASH"] that have a non-literal meaning. When we use these characters, ["BASH"] evaluates these characters and their meaning, but usually does not pass them on to the underlying commands.

Here are a few of those special characters, and what they do:
  * '''"text"''': Double quotes. Double quotes protect the text inside from being split into multiple words or arguments. They also prevent the special meaning of single quotes inside.
  * ''''text'''': Single quotes. Single quotes protect the text inside from any kind of expansion by the shell and keeps it from being split into multiple words or arguments. They also prevent the special meaning of all special characters inside.
  * '''# text''': Comment character. Any text that follows until the first newline is not processed as shell commands or arguments.
  * ''';''': Command separator. The colon is used to separate multiple commands from each other if the user chooses to keep them on the same line. It's ''basically'' the same thing as a newline.
  * '''\''': Escape character. The escape character protects the next character from being used in any special sort of way.
  * '''>''' or '''<''': Redirection character. These characters are used to modify (redirect) the input and/or output of a command.
  * '''[[ expression ]]''': Test expression. This evaluates the conditional expression.
  * '''{ commands; }''': Command Group. This executes the commands inside the braces as though they were only one command. It is convenient for places where ["BASH"] syntax requires only one command to be present.
  * '''`command`''', '''$(command)''': Command substitution (The latter form is '''highly''' preferred). Command substitution executes the command inside the substitution form first, and replaces itself by that command's output.
  * '''(command)''': Subshell Execution. This executes the command in a new bash shell, instead of in the current.
  * '''((expression))''': Arithmetic Evaluation. Inside the parentheses, operators such as +, -, * and / are seen as mathematical operators.
  * '''$((expression))''': Arithmetic Expansion. Comparable to the above, however this expression is replaced the result of its arithmetic evaluation.
  * '''$''': Expansion character. This character is used for any form of parameter expansion. More about this later.

Some examples:

{{{
    $ echo "I am $USER"
    I am lhunath
    $ echo 'I am $USER'
    I am $USER
    $ # boo
    $ echo An open\ \ \ space
    An open space
    $ echo "My computer is $(hostname)"
    My computer is Lyndir
    $ echo boo > file
    $ echo $(( 5 + 5 ))
    10
    $ (( 5 > 0 )) && echo "Five is bigger than zero."
    Five is bigger than zero.
}}}
----
[[BashGuide/CommandsAndArguments|Commands and Arguments ->]]
----
CategoryShell

Commands and Arguments ->


Introduction

You are invited to make additions or modifications so long as you can keep them accurate. Please test any code samples you write.

All the information here is presented without any warranty or guarantee of accuracy. Use it at your own risk. When in doubt, please consult the man pages or the GNU info pages as the authoritative references.


About This Guide

This guide aims to be a starting point for people interested in learning to work with BASH. It aspires to teach its readers good practice techniques for developing scripts for the BASH interpreter, and to educate them about the internal operation of BASH.

This guide is targeted at beginning users. It assumes no advanced knowledge, but rather expects you to have enough common sense to put two and two together. If something is unclear to you, you are invited to report this (use BashGuideFeedback, or the #bash channel on irc.freenode.org) so that it may be clarified in this document for future readers.

You are invited to contribute to the development of this document by extending it or correcting invalid or incomplete information.

The primary maintainer(s) of this document:

The guide is also available in PDF format. Alternatively, you can just hit print after going to FullBashGuide. That guarantees you'll be printing the latest version of this document.


A Definition

BASH is an acronym for Bourne Again Shell. It is based on the Bourne shell and is mostly compatible with its features.

Shells are command interpreters. They are applications that provide users with the ability to give commands to their operating system interactively, or to execute batches of commands quickly. In no way are they required for the execution of programs; they are merely a layer between system function calls and the user.

Think of a shell as a way for you to speak to your system. Your system doesn't need it for most of its work, but it is an excellent interface between you and what your system can offer. It allows you to perform basic math, run basic tests and execute applications. More importantly, it allows you to combine these operations and connect applications to each other to perform complex and automated tasks.

BASH is not your operating system. It is not your window manager. It is not your terminal (but it oftens runs inside your terminal). It does not control your mouse or keyboard. It does not configure your system, activate your screensaver, or open your files when you double-click them. It is generally not involved in launching applications from your window manager or desktop environment. It's important to understand that BASH is only an interface for you to execute statements (using BASH syntax), either at the interactive BASH prompt or via BASH scripts.



  • Shell: A (possibly interactive) command interpreter, acting as a layer between the user and the system.
    BASH: The Bourne Again Shell, a Bourne compatible shell.


Using Bash

Most users that think of BASH think of it as a prompt and a command line. That is BASH in interactive mode. BASH can also run in non-interactive mode, as when executing scripts. We can use scripts to automate certain logic. Scripts are basically lists of commands (just like the ones you can type on the command line), but stored in a file. When a script is executed, all these commands are (generally) executed sequentially, one after another.

We'll start with the basics in an interactive shell. Once you're familiar with those, you can put them together in scripts.

Important!
You should make yourself familiar with the man and apropos commands on the shell. They will be vital to your self-tutoring.

    $ man man
    $ man apropos

In this guide, the $ at the beginning of a line represents your BASH prompt. Traditionally, a shell prompt either ends with $, % or #. If it ends with $, this indicates a shell that's compatible with the Bourne shell (such as a POSIX shell, or a Korn shell, or BASH). If it ends with %, this indicates a C shell (csh or tcsh); this guide does not cover C shell. If it ends with #, this indicates that the shell is running as the system's superuser account (root), and that you should be extra careful.

Your actual BASH prompt will probably be much longer than $. Prompts are often highly individualized.

The man command stands for "manual"; it opens documentation (so-called "man pages") on various topics. You use it by running the command man [topic] at the BASH prompt, where [topic] is the name of the "page" you wish to read. Note that many of these "pages" are considerably longer than one printed page; nevertheless, the name persists. Each command (application) on your system is likely to have a man page. There are pages for other things too, such as system calls or specific configuration files. In this guide, we will only be covering commands.

Note that if you're looking for information on BASH built-ins (commands provided by BASH, not by external applications) you should look in man bash instead. BASH's manual is extensive and detailed. It is an excellent reference, albeit more technical than this guide.

BASH also offers a help command which contains brief summaries of its built-in commands (which we'll discuss in depth later on).

    $ help
    $ help read



  • Interactive mode: A mode of operation where a prompt asks you for one command at a time.

  • Script: A file that contains a sequence of commands to execute one after the other.


Contents

The guide has been divided into sections, which are intended to be read roughly in the order presented. If you skip ahead to a specific section, you might find yourself missing some background information from previous sections. (Links to relevant sections are not always provided when a topic is mentioned.)


Commands and Arguments ->


CategoryShell

BashGuide (last edited 2021-05-27 20:29:49 by GreyCat)