The first step for the beginners would be getting familiar with file system basics by using file manager. We could give you comprehensive shell commands crash course, but how many folks would lie on the ground sobbing after that? That's not our goal. We don't want you to have computer science degree before you write your first program. Our goal is to create programs with fun. But before we do that, we'll give you a list of essential commands you don't need to remember (make a bookmark and you'll probably get to this page later, may be even in a year or two).
Make a set of nested directories: directory `one` will contain directory `two`, and directory `two` will contain directory `three` (still F7 in Far Manager, flag `-p` stands for "path"):
```
$ mkdir -p one/two/three
```
Print file contents in your terminal (`file.txt` is a file name):
```
$ cat file.txt
```
Trick: there is alternative to `cat` called `bat` -- "A cat with wings", improvement over the `cat`. You need to [install bat](https://github.com/sharkdp/bat), and it gives you color formatting, line numbers, and some other improvements.
Imagine that `file.txt` is very large and you don't want to have the entire file contents on the screen, but only _first_ 10 lines. You can do it with `head`:
```
$ head -10 file.txt
```
Show last 10 lines of `file.txt`:
```
$ tail -10 file.txt
```
If there is a huge log file, and some program is constantly writing to this file, you may want to see the recent additions to the file, without restarting `tail` command every time. You can do it with `-f` (follow) flag:
```
$ tail -f file.txt
```
Press standard combination of Ctrl+C to quit from the command above.
Use `mv` (move) command to rename files (F6 in Far Manager). Technically, renaming and moving a file is the same thing for a computer. The point is that file system has file allocation table and actual file contents. Allocation table contains only meta information about the file, like name, modification date, and the _pointer_ to the actual physical location of file data.
So when you rename a file, in fact you update only file name in this table, without moving the file data. So renaming (or "moving") takes only few milliseconds if this operation is performed on the same disk (even for very large files). However, if you move (or "rename") the file _from one disk to another_, operating system will:
1. Update file allocation table on both disks
2. _Copy_ the actual contents of a file
3. Unlink (remove) the file from origin location.
That's why it can take up to several minutes or even hours when file is large.
```
$ mv file1.txt file2.txt # rename one file to another
$ mv file.txt .. # move file one level up
$ mv file.txt ../.. # move file two levels up
$ mv file.txt ~ # move file to home directory
$ mv file.txt /Volumes/MyUSB # move file to USB flash drive (MacOS)
$ mv file.txt /mnt/MyUSB # move file to USB flash drive (Linux)
```
Note that `MyUSB` above is the name of your flash drive and can be different on your computer.
X> Open up your terminal. List all files (`ls -lah`). Create directory with the name `my_directory`. List all files again, make sure directory exists now. Pick any file from current directory and copy this file to directory you just created. Use file manager to ensure you did the right job.
Here comes command some experienced programmers aren't familiar with: copy multiple files to directory:
```
$ cp {file1.txt,file2.txt} my_directory
```
To copy multiple files in Far Manager you will need to select them first. It can be done with Insert (Ins) key. However, some laptop keyboards do not have this key. In this case use combination of "Shift+Up" or "Shift+Down" to select files on the panel. Selected files will be highlighted in yellow. When files have been selected, press F5 to open copy dialog.
If you had already installed [Oh My Zsh](https://ohmyz.sh/) instead of default "Bash" shell, you can click Tab any time you want to avoid typing the full file name. For example, type `cp {f` and press Tab to see the list of available files you can include in your copy command. Same trick works for `cp`, `mv` and some other shell commands.
Find all files in current directory by name (command below will find all files with `rb` extension):
```
$ find . -name '*.rb'
```
Find all files in current directory that have `bla` as a part of the name:
```
$ find . -name '*bla*'
```
Find files without directories with `rb` extension:
E> Often people do mistake and provide two hyphens `--` instead of one `-` to `find` command. For example, parameter with two hyphens like `--name` or `--type f` is incorrect. You must use **one** hyphen with `find`. However, some other Linux commands accept two hyphens. Don't get confused!
As you can see, there are many ways of finding files in _current directory_. Current directory is indicated by dot right after `find` command (separated by space). Directory of one level up is indicated by two dots. Directory of two levels up is indicated by `../..` (two dots, slash, two dots). Here is the short list of directory shortcuts with examples of `find` command:
* `.` - current directory. Example (find all files with `log` extension):
* `~` - home directory (directory of current user). Example:
$ find ~ -name '*.log'
* `/` - root (top level) directory. Example:
$ find / -name '*.log'
X> ## Exercise
X> Try to find all log files in your root directory.
Far Manager has built-in dialog (which is quite friendly) for searching files. You can search files by using Alt+F7 combination. By default search file mask is `*.*` (all files). You can also specify a substring you want to be present in these files.
Here is how you can search for "something" substring in all Ruby files in current directory:
The first part should be already familiar to you. The part after pipe operator `|` accepts lines and executes the `grep` command for each line passing incoming line as parameter at the end of this command, for example `grep something file1.rb`. Don't worry if this syntax looks too complex for you at the moment. Eventually you will remember this command or another command. Searching through the files in current directory is one of essential things every programmer does many times a day.
How would you create empty file right in your terminal? There is useful `touch command`:
```
$ touch file.txt
```
This command will update date and time of the file it already exists. If you want to create a file and put some data in it, use `cat` the following way:
```
$ cat > file.txt
```
Then type your data, for example `foo bar`, and press Ctrl+D (sometimes you need to press Ctrl+D twice). If
X> ## Exercise
X> Create a text file and put your name to this file. Use `ls -lah` command to make sure file has been already created. Use `cat file.txt` to see the contents of the file.
E> ## Be Careful
E>
E> `cat > file.txt` will overwrite contents of the file without any warnings.
Add data to the end of file, the following command will _not_ overwrite existing file. If file is not present, it will be created:
```
$ cat >> file.txt
```
Few notes about file system. You know that root directory is referred to as `/`, and home directory as `~`. Home directory is the directory of current user. You can find out the name of current user by typing `whoami` ("Who Am I?") command:
```
$ whoami
ninja
```
Interesting fact that there is `whereami` command in Ruby debugger [Pry](https://github.com/deivid-rodriguez/pry-byebug) (will be described later), it shows the place where are you currently at while debugging a program.
Print working directory (current directory):
```
$ pwd
/home/ninja
```
Show home directory path:
```
$ echo ~
/home/ninja
```
Tilde `~` can be used as a part of path:
```
$ mkdir ~/tmp # Create tmp directory inside of your home directory
$ cp file.txt ~/tmp # Copy file.txt to newly created directory
```
By the way, create `~/tmp` directory now for your temporary files. Existing directory located `/tmp` is intended for system files and gets wiped out on computer restart.
Remove file. **Be careful, this command will not ask for confirmation**:
It's worth mentioning, that `-r` (recursive flag) is also used for some other shell commands. It tells hat we want to perform operation recursively with this or another directory.
E> There are some bad jokes on programming websites, mentioning `rm -rf /` command. This single command will remove everything on your computer and will make your operating system unusable in seconds. Moreover, flag `-f` stands for "force". So you won't be asked for any confirmations.
Copy `cp` command mentioned above has its alternative called `scp` - SSH Copy. `cp` command works for local files, but with `scp` you can copy a file from one computer to another. We are not going to provide examples, but keep that in mind if you need to copy a file from one computer to another. For example, there is a log file on the server and you want to download this log file for error investigation.
We're done with essential shell commands and ninja training. As you can see, there are numerous for basic file operations, but as a first step we highly recommend using file manager, switching back to your terminal time to time.