rubyisforfun/manuscript/015.txt
Roman Pushkin 5473381930 Save
2018-12-22 22:56:25 -08:00

134 lines
No EOL
5.8 KiB
Text

## Console ninja, shell survival guide
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).
Create directory ("**M**a**k**e **Dir**ectory") with a name `one` (F7 in Far Manager):
```
$ mkdir one
```
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.
Copy file:
```
$ cp file1.txt file2.txt
```
Copy file to directory:
```
$ cp file1.txt my_directory
```
X> ## Exercise
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.
Copy file one level up:
```
$ cp file1.txt ..
```
Copy file two levels up:
```
$ cp file1.txt ../..
```
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:
```
$ find . -name '*.rb' -type f
```
E> ## Keep this in mind
E>
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):
$ find . -name '*.log'
* `..` - directory of one level up. Example (find all files with `log` extension in directory of one level up):
$ find .. -name '*.log'