Shell Redirections, I/O, and special characters.

Shell Redirections, I/O, and special characters.

·

6 min read

Special characters.

The characters typed onto the terminal can have special meanings. One of these is the * which means to match any characters. These special characters can be challenging to write when executing commands on the terminal. e.g. the echo command prints its argument to the output. However, the special character * will expand to all characters available in the directory which would print all names in the directory. What happens when the * needs to be printed. The answer is using an escape sequence. This can be done by enclosing the * in single quotes and as echo * . The escape characters and special characters, usually used in wildcards, are important to the shell and this article lists them and their meanings.

Redirections.

One of the abilities of bash that makes it powerful is the ability to redirect the output and input of commands. While the commands typically output to the standard output (screen), this need not be the case. While they typically receive input from the standard input (keyboard), this need not be the case. The > symbol will redirect output to a particular file overwriting any existing intent in that file. The >> symbol will append the output of a command to a specified file. e.g. ls > tree.txt or ls >> tree.txt . To redirect input, the < command is used. For example, sort < tree.txt The commands can be used together so that: sort < tree.txt > sorted_tree.txt .

Piping Commands

Piping is a form of redirection using the | operator. This operator feeds the output of one command into another. In this example, the output of ls -al is fed to the grep command. ls -al | grep tree. This ability gives the GNU/LINUX system and bash a lot of power allowing a few lines of script to do a lot. You can read more on piping here. Let's look at some examples of applying these concepts.

Examples

  • Printing to the standard output (stdout)

    echo "Hello, World"

  • To display a confused smiley "(Ôo)'

    In this case, the double quote has to be escaped when using the echo command. It then becomes echo "\"(Ôo)'" . The escape character \ tells bash to treat the " as a normal character.

  • To display the contents of a file, e.g. /etc/passwd The cat command is used:

    cat /etc/passwd

  • To display the contents of two files, use cat to display the contents of one then the other:

    cat /etc/passwd /etc/hosts

  • To display the last lines of a file, the tail command is used. To display a particular number of lines, use the -n option with the tail. e.g. to display the last 10 lines of a file: tail -n 10 file.

  • The head command displays the first lines and works similarly to the tail command.

  • Using these commands, it is thus easy to display a particular line in a file. To display the fifth line, use the head command to get the first 5 then pipe it to the tail to get the last line of that output.

    head -n 5 file | tail -n 1.

  • To create file named exactly \*\'"Best School"\'\*$\?\*\*\*\*\*:) containing the text Best School ending by a new line; simply redirect the output of echo into that file. Now the name of the file is tricky since it contains a lot of special characters and escape sequences. The single quotes make every single character inside them have a literal (non-special) meaning. However, to escape the single quote. One way to write the text is to put the parts before single quotes in single quotes, then print the single quote using double quotes "'" then repeat the process. Of course, there are other ways that you can try out as an exercise.

      #!/bin/bash
      echo "Best School" > '*\'"'"'"Best School"'"'"'\*$?*****:)'
    
  • To write a script that writes into the file ls_cwd_content the result of the command ls -la. If the file ls_cwd_content already exists, it should be overwritten. If the file ls_cwd_content does not exist, create it. ls -la > ls_cwd_content .

  • To delete all regular files(and only files, not directories) with a .js extension in the current folder and all its subfolders find . -type f -name '*.js' -delete . The find command searches in the directory hierarchy, the -type f specifies that only files should be gotten and the name gives the names with the -delete asking for them to be deleted.

  • The find command can be used to manipulate the various files in a directory hierarchy and the output piped to other commands. man find to learn all about its options. Write a script that counts the number of directories and sub-directories in the current directory. The current and parent directories should not be taken into account and hidden directories should be counted. Manipulate it as find -mindepth 1 -type d | wc -l The -mindepth shows that the level from where the search starts can be changed.

  • To display the newest files, use the ls -t option to organize them by modification time, then pipe it to the head or tail to find the latest (or earliest) files.

  • To Create a script that takes a list of words as input and prints only words that appear exactly once, with;

    Input format: One line, one word.

    Output format: One line, one word.

    Words should be sorted: pipe the output of sort to uniq: sort | uniq -u. The sorted output is fed to uniq. Run man uniq to learn more about it.

  • To find a single word from a given file use the grep command. To display lines containing the word root from /etc/passwd simply grep -E 'root' /etc/passwd . In this case, grep searches for 'root' in '/etc/passwd'. To count the number of lines that will be output, use the -c option. To display a word and some lines after it, use the -A number option.

  • grep with the -v option hides the lines that contain a given word. e.g. to display lines that do not contain "root" in /etc/passwd: grep -Ev 'root' /etc/passwd .

  • Grep also uses wildcards in its input in the shell.e.g. to display all lines starting with a letter: egrep ^[[:alpha:]] .

  • The 'tr' command replaces a given letter(s) with others. e.g. To replace all characters A and c from input to Z and e respectively:

    tr 'Ac' 'Ze' . Run man tr to learn more.

  • When used with -d tr deletes given characters. e.g. To remove all letters c and C from the input; tr -d Cc.

  • The rev command reverses its input.

  • These commands are used such that they manipulate their inputs and feed their outputs to other commands. To display all users and their home directories, sorted by users in the /etc/passwd file:

    First, we'll need to remove sections from the file lines using the cut command. We'd then select our fields using the -f option, and select our delimiters with the -d option. The output of this is then fed to the sort command for our output. e.g. cut -f 1,6 -d ':' /etc/passwd | sort .

  • To find empty files within a given directory, the find command is used with the -empty option. Therefore, to find all empty files and directories in the current directory and all sub-directories, printing their names followed by a new line and ending with a new line:

    find . -empty -printf "%f\n" .

    These examples and commands would form good practice on redirections in the shell.