# Commands

Bash 4.3 comes with 58 embeded commands:

```
 bash  defines  the  following built-in commands: :, ., [, alias, bg, bind, break, builtin,
       case, cd, command, compgen, complete, continue, declare, dirs, disown, echo, enable, eval,
       exec,  exit,  export,  fc,  fg,  getopts, hash, help, history, if, jobs, kill, let, local,
       logout, popd, printf, pushd, pwd, read,  readonly,  return,  set,  shift,  shopt,  source,
       suspend,  test,  times,  trap,  type, typeset, ulimit, umask, unalias, unset, until, wait,
       while.
```

They are built-in for performance reasons.  
There are many more commands available on your machine. Unix machines have several hundreds of different commands.
A good place to look at them is ([http://ss64.com/mac](http://ss64.com/mac) or [http://ss64.com/bash](http://ss64.com/bash).

**No worries! As most of people we only need to use a very small subset of those commands.**


## How commands works

```bash
command [ -option ] [ arguments ]
```

  * [ ] means this is optional (e.g. `ls` vs `ls -l`)
  * **Option** only modify the behavior of the command. It starts with `-` (or `--` for long option)
  * **Argument** controls the output of the command. It specifies a target for the command.

It is possible to save the output of a command in a variable:  

```bash
var=$(command)
```

## String Commands Together

It is possible to execute several commands in one line using `;` in between commands:  

```bash
command1 ; command2
```

It is possible to send the output (STDOUT) of a command as input (STDIN) of another using `|` :  

```bash
command1 | command2
```


## Input/Output of commmands

Commands can take different arguments:

### Nothing 
```bash
ls
```

### String
```bash
echo hello world
```

### File
```bash
cat file_input
```

### A stream

In Bash, a stream is a flow of data used for input and output operations. Streams allow data to be read from or written to files, commands, or devices.  
Streams are essential for scripting, allowing flexible input/output handling and error management.

Here an example:  
```bash
echo "Papa" | tr Pp Mm
```

Bash primarily deals with three standard streams:

#### Standard Input (stdin) – File Descriptor 0

It is used to take input (e.g., from the keyboard or a file).

To read user input from keyboard:  
```bash
read var
```

To read input from a file:  
```bash
command < input.txt
```

#### Standard Output (stdout) – File Descriptor 1

It is used to display _normal_ command output.  
When you do `echo "Hello"` the ouput is written to stdout.  
Stdout can be redirected to a file using `>` or another command using `|`.

```bash
command > output.txt # redirection to a file
command1 | command2 # redirection to the next command
```

#### Standard Error (stderr) – File Descriptor 2

It is used for error messages and diagnostics.

```bash
ls nonexistentfile
```

By default, the terminal (stdout) displays both file descriptor 1 (stdout) and file descriptor 2 (stderr).  
You can redirect specificaly `stderr` in a dedicated file using the file descriptor 2:

```bash
# test1
ls nonexistentfile 2> error.log
# test2
ls . nonexistentfile 2> error.log
# test3
ls . nonexistentfile > output.txt 2> error.txt
```

###  Commands specificities

/!\\ commmands that take an input either from a **file** of from **STDIN**: grep, sed, cat, head, sort, wc, etc.  
/!\\ commmands that **never read STDIN**: ls, cp, mv, date, who, pwd, echo, cd, etc.  
/!\\ commmands that **read only STDIN**: tr

## Saving output

It is possible to save/send the output of a command in a file:  
```bash
# overwrite file if already exists
command > file
# append file if already exists
command >> file
```

!!! Success "Quick recap"
    In this section we've learned:

    - how commands work
    - how to string commands together
    - how to deal with input/output of commands
    - the different file descriptors (stdout, stdin, stderr)