Not all characters are equal in Bash. Some of them carry out special functions, tweak commands, and help us manipulate data. That’s why we’ve compiled the following list with the most important Bash special characters. Read on to find out how to use them and how they can make your daily Bash life easier.
Folder Path Separator (/)
In Bash, the forward-slash (/
)separates the parts of a path, the subfolders-within-folders. To visit the folder named “pictures” inside your home folder, you’ll have to use the command cd
as:
cd /home/USERNAME/Pictures
Everything after a forward slash in the above example resides within what precedes the slash.
Home Directory (~)
Instead of typing the full name of your home folder in your Bash terminal, you can use the tilde character (~
). For example, to go to your home folder, use:
You can also incorporate it into more complex paths. For example, to edit a file named “mydata.txt” inside the “Personal” folder in your Home directory, use:
nano ~/Personal/mydata.txt
Current / Above Folder (.)
You can use a single (.
) or double dot (..
)to define whether an action should be performed inside the current directory or the one above, respectively. A single dot (.) maps to the current folder while a double dot (..) maps to the folder above it.
Let’s say you’re in the folder “/home/USERNAME/Pictures” and want to execute the script called “transform_images.sh” within the same directory. In this case, type:
If, after executing the script, you want to return to the folder above the one you’re currently in, type:
That would return you from the folder “/home/USERNAME/Pictures” to “/home/USERNAME.”
The hash symbol (#
) is more useful when writing Bash scripts since it allows you to add comments to them for future reference. Bash ignores everything following a hash symbol.
In the following script, the first line defines it’s a Bash script, the second is a comment that’s ignored, and the third is a typical copy command:
#!/bin/bash # This is a comment - you can type anything you want here cp file1.txt /home/USERNAME/scripts/file2.txt
Hashes are useful even if you’re not writing a script since they allow you to cancel parts of a command. To see that in action, try the following straightforward command:
Then, try the following instead:
You’ll only see “I am” returned in the second version because the hash will have canceled everything that followed after.
Ranges ([])
You can define character ranges by enclosing them in brackets ([]
). To see that in action, let’s say you want to look for folder names that start with either D or M. Type:
Perhaps you’re in a folder filled with subfolders named after each year instead. To copy the folders for the previous five years into “/home/USERNAME/backup,” use:
cp -r 201[56789] /home/USERNAME/backup
You can even simplify them further with a dash (-):
cp 201[5-9] /home/USERNAME/backup
Bash will iterate from 5 to 9 to include the numbers between them.
Redirection (<>)
Using angle brackets (<>
), you can redirect a command’s input or output. For example, the following command:
will redirect the output of ls
and save it to the “list.txt” file.
Note that a double right-angle bracket (>>
) appends a command’s output to a file. If you re-run the same command, it will append its output to the end of the existing content. To replace its content with new results, use a single right-angle brackets (>
):
Pipes (|)
You can combine different commands into a larger whole to achieve more complex results by using pipes (|
). They’re somewhat similar to redirection (more on their similarities and differences here).
Suppose you have a huge file with thousands of entries and want to locate your name in it. Instead of searching for it in a text editor, do the following:
cat entries.txt | grep 'YourName'
In this case, the output of “entries.txt” will be piped to the grep
command.
Tip: Learn more about pipes, data streams and redirection by using sed in Linux.
Command Separator (;)
Bash allows you to issue multiple commands in one go by separating them with semicolons (;
). For example, to copy two folders to two different destinations with one command:
cp -r folder1 destination1; cp -r folder2 destination2
The semicolon separates the two commands and tells Bash to execute them sequentially. Note that you can use more than two commands if you wish.
Wildcards (*)
You’ve probably already used the asterisk (*
) in some commands. It matches any sequence of characters and allows actions like copying all JPG files from one folder to another:
cp /home/USERNAME/folder1/*.jpg /home/USERNAME/folder2/
The question mark (?
) is also a wildcard in Bash but only matches a single character. For example:
cp /home/USERNAME/201?/*.jpg /home/USERNAME/folder2/
The above command will copy all jpg files in folders that begin with “201.” Since the wildcard translates to any alphanumeric character, not only numbers, the above command would also copy any folder that might be named “201A” or “201z.”
Launch in Background (&)
You can run commands as background processes just by appending the command with an ampersand symbol (&
):
cp /home/USERNAME/Downloads/huge_file.zip /home/USERNAME/backups &
The above will start copying the file huge_file.zip and immediately move to the background, letting you keep using the terminal. The command will automatically exit when it completes. If you want to bring it forward again, you can do so by typing fg
followed by Enter.
Variables ($)
The dollar sign ($
) allows you to set up variables for use in your commands. To see them in action, try entering the following in your terminal:
myname=YOUR_NAME myage=YOUR_AGE echo "I'm $myname"
Note that there’s no dollar sign when assigning values to variables.
FYI: Bash variables can do more than just store static data. Learn how to create arrays and subshells inside shell variables.
Escapes (\) and Quotes (”)
If you want to use any of the special characters as it is in a command, you’ll have to escape it. You can do that by preceding the special character with a backslash (\
). For example, if you have a file with a name that includes an exclamation mark, you’d have to type \!
instead for Bash to interpret it as an exclamation mark and not as a special character.
Another way would be using either single (''
) or double-quotes (""
). By enclosing a string in quotes, any special character in it will be treated as the actual character. There is a difference between single and double quotes, too. Single quotes will evaluate the enclosed string as text while double quotes allow you to use variables ($
) within the enclosed string.
Input (<) and Error (2>) Redirection
Aside from redirecting the output of programs, it is also possible to control where a program’s input comes from. The less-than (<
) operator allows you to “pull” data out of files instead of “pushing” into them. For example, the following will remove all duplicate lines in the file “sort.txt” and sort them alphabetically:
You can also force Bash to redirect any error messages from a program. The following code will redirect the output of the sort
command on “out.txt” and the errors on “err.txt:”
sort ./invalid.file > out.txt 2> err.txt
Further, you can also use the ampersand (&
) operator to combine the output of your program alongside any errors:
sort ./invalid.file &> out.txt
Control Characters
A control character is an operator that allows you to include non-typeable characters inside your script. For example, the following will move the prompt one space down and one tab to the right:
Control characters can support features such as Unicode formatting. It does this by using the \x
operator to interpret each byte value as a segment of a Unicode glyph.
The following code will print a null sign along with a delta character:
printf "\xe2\x88\x85 \xe2\x88\x86\n"
Note: You can find the hex value of your Unicode glyph by piping it to the xxd
utility:
Arithmetic Expansion Character
The Arithmetic Expansion character is an operator that can do mathematical equations without any external programs. It works by treating anything inside the expansion as arguments for an integer calculation.
For example, the following line will add two numbers and print the result on the screen:
Further, you can also use variables inside any arithmetic expansion. The following code, for example, uses this as basis for a simple multiplication program:
#!/bin/bash # Get the first ten multiples of a number. for (( i = 1; i <= 10; i++ )); do echo $(( $1 * $i )); done
Evaluation Character
The Evaluation character is a logical operator that helps you create test conditions inside your scripts. It contains the ability to detect files as well as variable inequalities:
#!/bin/bash string1='Hello' string2='World' if [[ $string1 != $string2 ]]; then echo "The strings are not equal."; fi
The following example also uses the evaluation character as a way to test whether the current directory contains a “maketecheasier” file:
#!/bin/bash if [[ -e "maketecheasier" ]]; then echo "There is a file with the name maketecheasier"; fi
AND (&&) and OR (||) Characters
One of the downsides of the evaluation character is that it can only do a single test condition at any moment. To fix this, Bash provides two additional operators which extend the features of the evaluation character.
The AND character allows you to test two conditions and only return a value when both are true. For example, you can use it to make sure that a function will only run if it is in the right directory with the right file:
#!/bin/bash target="/home/ramces/maketecheasier" if [[ $target == $(pwd) && -e "maketecheasier.txt" ]]; then echo "Both conditions are true!" fi
Similar to AND, the OR character also allows you to test two conditions in a single evaluation. However, it will return a value even if only one of the conditions is true. The following example uses this to check for two similar directories:
#!/bin/bash if [[ -d "directory1" || -d "directory2" ]]; then echo "A suitable directory exists!" fi
Subshell Execution and Grouping
A subshell is an independent shell process that you can run from inside the current session. Unlike a regular shell, a subshell will only open when you call it and it will close as soon as it resolves.
This approach prevents subshells from passing information between other shells. For example, the cat
program in the following code will not find “test.txt” even if the subshell goes to the right directory:
( mkdir sample && cd sample && echo "Hello, MakeTechEasier" > test.txt ; ) && cat test.txt
Despite that, you can still “group” commands without creating a subshell. This can be helpful if you want to run commands under the current process:
{ mkdir sample && cd sample && echo "Hello, MakeTechEasier" > test.txt ; } && cat test.txt
Good to know: Modify your shell using your new Bash skills by customizing your .bashrc file.
Frequently Asked Questions
Is it possible to make a multi-line command in Bash?
Yes. You can do this by adding an escape character at the end of your command. This will move your cursor to the next line without running your program.
Can you get an earlier background program back to the foreground?
Yes. To do this, you need to run the jobs
command and find the job number of the process that you want. Next, run fg
followed by the number of your command to return it to the front.
Can you use an input and output redirection character in one command?
Yes. To do this, you need to provide your input redirection before your output. For example, running sed 2q < ./long-file > ./short-file
will tell sed to read the “long-file” then output to the “short-file.”
Image credit: Xavier Cee via Unsplash. All alterations and screenshots by Ramces Red.
Subscribe to our newsletter!
Our latest tutorials delivered straight to your inbox