Shell#

Linux shell have a lot of features inportant to know. This section considers different behaviour patterns

Manage input/ouput#

There is a number of tools that are commonly used to work with the terminal.

Tool

Description

| pipe

Passes the result of one command to another command.

grep

Searches for patterns in the output of a command.

<command> > <file_name>

Redirects the command output to a file.

<command> >> <file_name>

Adds the output to a file.

tee

Simultaneously redirects the output to both the standard output and a file.

Heredoc << syntax

Allows you to write multi-line instructions directly in the terminal.

<command> &

You can run a command detached using the &.

Check more details in the special page.

Environment#

The Linux environment is actually is a set of variables that define the behavor of different Linux utilities. The environment can sometimes can seriously change the behavior of the shell. This section discusses options for setting up and monitoring shell behavior. There are few important aspects of the environment:

  • The export command adds a specified variable to the current environment.

  • The source command executes the script and applies all of its definitions to the current shell.

  • There are a few really important variables that define the general behavior of the bash that are worth to know:

Variable

Description

SHELL

Path to the current user’s shell (usually /bin/bash).

BASH

Full path to the Bash binary in use.

BASH_VERSION

Version of Bash being executed.

BASHOPTS

List of enabled Bash shell options (set via shopt).

BASHPID

Process ID of the current Bash process.

BASH_ENV

File that Bash reads and executes before running a script (for non-interactive shells).

PROMPT_COMMAND

Command executed before each Bash prompt is displayed.

PS1

Primary command prompt definition (what you see before you type commands).

PS2

Secondary prompt (displayed when a command spans multiple lines).

HISTFILE

File where command history is stored (usually ~/.bash_history).

HISTSIZE

Number of commands to remember in memory.

HISTFILESIZE

Maximum number of lines to store in the history file.

PATH

Colon-separated list of directories Bash searches for executables.

HOME

Path to the user’s home directory.

PWD

Current working directory.

OLDPWD

Previous working directory (used by cd -).

USER / LOGNAME

Username of the current user.

UID

Numeric user ID of the current user.

EUID

Effective user ID (important for setuid scripts).

IFS

Internal Field Separator — defines word splitting (default: space, tab, newline).

LANG / LC_ALL

Define locale settings for language, sorting, and formatting.

TERM

Type of terminal used (affects output formatting).

MAIL

Path to the user’s mailbox (used for mail notifications).

EDITOR / VISUAL

Default text editor (used by many CLI tools).

ENV

File sourced at shell startup for POSIX shells (used by non-interactive shells).

SHLVL

Indicates how many nested shell levels are active.

SECONDS

Number of seconds since the shell was started.

RANDOM

Returns a random integer between 0 and 32767.

LINENO

Current line number in the executing script.

Check more details in the Environment page.

Commands#

Consider how the shell runs different commands. Linux tries to find and execute anything you type into terminal. Some commands are built into shell (for example cd). However, the most of them are the binaries or scripts somewhere in the system. There are important details to know:

  • Simply specifying the path of the file will cause it to be attempted to be executed.

  • To run a file from relative path, you must specify the relative path explicitly.

  • If the command that cannot be interpreted as a file path, the system will look in the directories specified in PATH environment variable.

  • You can specify the interpreter for interpretable scripts using the pattern #/path/to/the/interpreter.

  • Don’t confuse the executing and sourcing.

For more details check the Commands


For example, the bash command is just a binary file located somewhere in the system. The following cell shows the path to actual file:

which bash 
/usr/bin/bash

The following cell shows a piece of content.

cat $(which bash) | head -n 10 | cut -c1-10
ELF6NL
�0�I���u�
�0@A
��@
 �AA�%�
�!
�Xq�@�
BdH�(0

There is nothing special about this file except that it can be executed. For example, the following cell defines a bash script and grants it the necessary permissions:

cat << EOF > /tmp/script.sh
echo "hello script"
EOF

chmod +x /tmp/script.sh

The script can be run as as regular binary.

/tmp/script.sh
hello script

Exit status#

When your program exits, it returns a number that describes the circumstances under which the program finished. This output is stored in the $? variable, allowing you to check the state of the command.

Code

Description

0

Success: The program or command completed successfully.

1

General error: A generic error occurred.

2

Misuse of shell builtins: Incorrect usage of a shell command or builtin.

126

Command invoked cannot execute: Found but not executable.

127

Command not found: Command not found in system PATH or misspelled.

128

Invalid exit argument: Program returned a value outside the valid exit range.

130

Terminated by Ctrl+C: Process killed by SIGINT signal.

137

Killed by SIGKILL: Process terminated by kill -9.

139

Segmentation fault: Process terminated by SIGSEGV.

128+N

Termination by signal (N): Exit code represents signal (N).

10

(Custom) Missing configuration file.

20

(Custom) Resource unavailable.


The following cells shows examples of invoking ? varable in different cases.

The basic case is when a program finishes successfully, resulting in 0:

echo "hello world"
echo $?
hello world
0

In cases where a command is passed a parameter it cannot handle, such as with the ls command, it returns a status code of 2.

ls -w
echo $?
ls: option requires an argument -- 'w'
Try 'ls --help' for more information.
2

An example of invoking a Command not found exception.

this_command_doesnt_exist
echo $?
this_command_doesnt_exist: command not found
127

Bash#

Bash is a shell commonly used in Linux-based operating systems. Mastering Bash allows you to combine results from Linux utilities and create your own, which is a straightforward way to optimize tasks. Find out more on the specific page or in the official manual.


The following example shows how to extract raw JSON using the curl command, format it nicely with the jp tool, and transform it to YAML format using the yp tool. To perform all this, we use just two Bash command operators: | and $.

docker run -itd --name temp_http --rm -p 80:80 kennethreitz/httpbin

json_output=$(curl -s localhost:80/json)
echo $json_output | jq
echo "============================================================"
echo "$json_output" | jq '.' | yq -P

docker stop temp_http
5d54c061747cf404cb1b6623515f3836d562367470208a9e008c4f7c7f0c2b75
{
  "slideshow": {
    "author": "Yours Truly",
    "date": "date of publication",
    "slides": [
      {
        "title": "Wake up to WonderWidgets!",
        "type": "all"
      },
      {
        "items": [
          "Why <em>WonderWidgets</em> are great",
          "Who <em>buys</em> WonderWidgets"
        ],
        "title": "Overview",
        "type": "all"
      }
    ],
    "title": "Sample Slide Show"
  }
}
============================================================
slideshow:
  author: Yours Truly
  date: date of publication
  slides:
    - title: Wake up to WonderWidgets!
      type: all
    - items:
        - Why <em>WonderWidgets</em> are great
        - Who <em>buys</em> WonderWidgets
      title: Overview
      type: all
  title: Sample Slide Show
temp_http

Users & groups#

There are tools to organize users of the system:

  • /etc/passwd file: contains information about all users in the system.

  • useradd command: adds a new user to the system.

  • userdel command: deletes a specified user from the system.

  • To determine the current user, you can use the whoami command or simply retrieve the value of the $USER variable (echo $USER).

Find out more in the corresponding page.


The following cell uses the useradd command to add users to the system:

useradd fedor

Now by running cat on /etc/passwd you can check the available users in the system:

cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
polkitd:x:996:996:polkit:/nonexistent:/usr/sbin/nologin
fedor:x:1001:1001::/home/fedor:/bin/sh

There is a user we just created. Try the userdel command to delete fedor from the system. The following cell deletes the user and lists available users:

userdel fedor
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
polkitd:x:996:996:polkit:/nonexistent:/usr/sbin/nologin