Books / Ruby for Beginners / Chapter 3

Intro to Shell for Beginners

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. You don’t need to have a 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 (or “make directory”) 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, 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

Exercise 1 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 the command even 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 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'
  • ../.. - directory of two levels up. Example:

            $ find ../.. -name '*.log'
  • ~ - home directory (directory of current user). Example:

            $ find ~ -name '*.log'
  • / - root (top level) directory. Example:

            $ find / -name '*.log'

Exercise 2 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:

$ find . -name '*.rb' -type f | xargs grep something 

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

The command above will update date and time of a file if it already exists.

Use “cat” when you want to create a file and put some data in it:

$ cat > file.txt

Then type in your data, for example “foo bar”, and hit Ctrl+D combination on your keyboard (if it doesn’t work, try to Ctrl+D twice). “Ctrl+D” stands for “end of input” in POSIX systems, and your terminal should understand it.

Exercise 3 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

Interesting fact that there is whereami command in Ruby debugger Pry (will be described later), it shows the place where are you currently at while debugging a program.

Print working directory (current directory):

$ pwd

Show home directory path:

$ echo ~

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 at /tmp is intended for system files and gets wiped out on computer restart.

Remove file. Be careful, this command will not ask for confirmation:

$ rm file.txt

Remove entire directory:

$ rm -r my_directory

It’s worth mentioning, that -r (recursive flag) is also used for some other shell commands. It tells that we want to perform operation recursively with this or another directory.

Copy command mentioned above has alternative: scp (SSH, “secured shell” copy). cp command works for local files, but with scp one can copy a file from one computer to another. For example, this command can be useful when 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 Linux ninja training. As you can see, there are numerous basic file operations you will need to remember eventually, but as a first step we highly recommend using file manager, and switching back to your terminal time to time.

Licenses and Attributions

Speak Your Mind