The first category of essential commands that we'll examine are builtins: they are included as part of the bash program. In fact, the very first command we'll look at, called type, is itself designed to help you tell what any kind of command is.
For all of these commands, Bash can provide help on usage with the help program. For example, to get help on the type command, you would type:
The type command, given the name of any command or commands, gives you information about what kind of command it is:
bash$ type echo echo is a shell builtin bash$ type grep grep is /bin/grep
It identifies shell keyword, too:
bash$ type for for is a shell keyword
We can define a function and an alias to test that it correctly detects those:
bash$ myfunc() { : ; } bash$ type myfunc myfunc is a function
myfunc ()
{
:
}
bash$ alias myalias=: bash$ type myalias myalias is aliased to `:' The type command has a few useful options. If you use the -t option, you can get a single word specifying the command type. This is sometimes useful in scripts:
bash$ type -t echo builtin bash$ type -t grep file
If you use the -a option, you can see all commands that have the same name. Bash will print them in order of preference. For example, the true name probably has both a builtin command and a system command on your system:
bash$ type -a true true is a shell builtin true is /bin/true
Bash will always prefer builtin commands for a given name over system commands. If you want to call the system's implementation of true, you could do it by specifying the full path to the program:
$ /bin/true
Try type -a [ and then type -a [[. Are you surprised by any of the output?
Another useful switch for type is -P, which will look for a system command for the given name, and print out the path to it if found:
bash$ type -P true /bin/true
Note that the /bin/true path was returned, even though true is also the name of a shell builtin.
There is a reason we put the type command first in this list. After help, it is the most useful Bash command for understanding the language, and clearing up the biggest source of confusion about the language: When I run this command, what is actually running?
The echo builtin command just repeats the arguments you provide it onto the standard output:
$ echo Hello Hello
This makes it a simple way to emit content to the terminal, including variables:
$ echo 'Hello, '"$USER"\! Hello, bashuser!
The echo command in Bash has switches that allow you to control the output, such as excluding the final newline, or expanding sequences such as \t to tab characters. However, we caution against using echo in scripts, because for historical reasons it has broken design and portability problems that makes it confusing or error-prone to use, especially when trying to use it with switches. We suggest you always use printf in scripts instead, as its behavior is more predictable, especially when printing variables or control characters such as newlines.
The printf command works like echo, except the first argument you provide to it is a format string:
$ printf '%s\n' 'Hello!' Hello!
Notice that we had to put the format string in single quotes, to prevent the backslash from having special meaning to the shell. Notice also that we didn't have to use double quotes to get the newline from \n; the printf command did that for us.
You can use printf in much the same way you would use a printf() function in other languages, such as C. It supports most of the same format specifications as the printf(1) system command; you can type man 1 printf to see a list.
It's easier to print tricky strings with printf, where echo might struggle:
$ printf '%s\n' -n -n $ string=-n $ printf '%s\n' "$string" -n
You should always choose printf over echo in scripts, even though it's a little more typing.
Be careful with what you put into a format string; a variable with a value provided by the user can be a security hole! It's best to use only fixed format strings, or carefully build them yourself.
printf also has a useful property where it will repeat the format string as necessary for each argument you provide it. This is a convenient way to print a list of arguments on individual lines:
$ printf '%s\n' foo bar baz foo bar baz
Note that we got three instances of the string-newline pattern from one format string.
Finally, Bash's printf has a %q pattern that can be used to quote special characters in a string with backslashes, so it can be reused safely in the shell. If you follow good quoting practices, you are unlikely to need this a lot in Bash, but it's useful to know it's there:
bash$ printf '%q\n' 'Watch out for thi$ $tring; it \has\ nasty character$!' Watch\ out\ for\ thi\$\ \$tring\;\ it\ \\has\\\ nasty\ character\$\!
The pwd Bash builtin prints the current working directory f...