Table of parts: https://docs.google.com/document/d/1IIOkivkS0lV9QIL16b_OjT480BxZHQfKswvvS-CVZlw/view

Intro

Why command line?

Why Linux?

What user interfaces can be?

Example: text editing

GUI

Graphical user interface - Графический интерфейс

gui.png

Console

Text interface, CLI, command line, командная строка, текстовый, терминал

You type text, computer shows text, line by line.

cli.png

Pseudo-graphical

Псевдографический

pg.png

Teletype (TTY)

Dumb terminal - примитивный терминал

non-dumb terminal

Command line in a GUI

Эмулятор терминала

gt.png

gt2.png

gt3.png

Copy and paste

Копирование и вставка

The text in a terminal emulator can be selected by mouse. Selection implies copying.

Middle (sometimes right) mouse button inserts the text at cursor position. Usually you can’t set cursor position by mouse.

Текст в эмуляторе терминала можно выделять мышкой. Выделение текста автоматически копирует его в буфер обмена. Средняя (иногда правая) кнопка мыши вставляет текст там, где курсор. Курсор обычно нельзя двигать мышкой.

Shell and REPL

Оболочка командной строки

get_preview

Shell is the thing that reads your commands and executes them. In interactive mode it operates in REPL mode.

More detailed and complicated diagram:

Examples of events handlers with GUI terminal

This section describes where the final handling of events lans:

Terminal special codes and modes

Main thing that flows through the tty is text. But there are additional things:

tty can also have multiple modes:

Readline - a library which uses interactive mode of terminal and allows better line editing, history, etc.

REPL

Each command line program (including the shell) have input and output. Bytes flow into the program from input and flows out of the program into output. The shell reads commands from whatever it’s input is connected to. Usually it is terminal emulator.

У каждой программы для командной строки есть ввод и вывод. Байты поступают на вход и “текут” в программу, или из программы на выход. Оболочка читает команды оттуда, к чему подключен её ввод. Обычно от подключен к эмулятору терминала.

What happens if one types a command into bash?

Useful link: https://www.explainshell.com/explain.


Compiling simple C programs from console

$ gcc -Wall -ggdb myprogram.c -o myprogram

myprogram.c:1:1: warning: You have chosen the wrong job [-Wbadcode]

$ ./myprogram

Hello, world

Commands

Commands are things that get executed when you type some text into the shell and press Enter.

They can be:

Command arguments

“echo” command outputs it’s arguments separated by space

$ echo qqq www "eee rrr"

qqq www eee rrr

Command name and arguments is an array of strings that is passed to the program.

Имя команды и аргументы - это массив строк, передаваемый в программу.

$ some_program -flq --long-option=dsafdsaf file1 file2

Physical arguments:

Logical arguments:

-f, -l and -q are also called “flags”, as they don’t accept any argument here.

Terminology in Russian: которкая опция, флаг, длинная опция, аргумент, позиционный аргумент.

After "--" all arguments become positional:ende

$ other_program -r file1 -- file2 --looks-like-option -b -ut file3

Exercise 1:

Construct a command line for the following case:

Getopt demo program

#include <time.h> // for random

#include <stdio.h>

#include <stdlib.h>

#include <getopt.h>

extern int optind;

extern char* optarg;

struct Opts {

    int q;

    int e;

    int tool;

    int adj;

};

void showadj(int adj, int capt) {

    switch(adj) {

        case 0: break;

        case 1: if (!capt) printf("жёстко "      ); else printf("Жёстко "      ); break;

        case 2: if (!capt) printf("неистово "    ); else printf("Неистово "    ); break;

        case 3: if (!capt) printf("стремительно "); else printf("Стремительно "); break;

    }

}

void showtool(int tool) {

    switch(tool) {

        case 0: break;

        case 1: printf(" шваброй"); break;

        case 2: printf(" щёткой"); break;

        case 3: printf(" тряпкой"); break;

    }

}

void show(struct Opts *opts, char** argv) {

    if (!opts->q) {

        printf("Мама ");

        showadj(opts->adj, 0);

        printf("мыла ");

    } else {

        if (!opts->adj) {

            printf("Мыла ли мама ");

        } else {

            showadj(opts->adj, 1);

            printf("ли мыла мама ");

        }

    }

    if (!*argv) {

        printf("раму");

    } else {

        while(*argv) {

            char* next = *(argv+1);

            printf("%s", *argv);

            if (next) {

                char* nextnext = *(argv+2);

                if (nextnext) {

                    printf(", ");

                } else {

                    printf(" и ");

                }

            }

            ++argv;

        }

    }

    showtool(opts->tool);

    switch (opts->q * 2 + opts->e) {

        case  0: printf(".\n"); break;

        case  1: printf("!\n"); break;

        case  2: printf("?\n"); break;

        case  3: printf("?!\n"); break;

    }

}

void help() {

    printf("getoptdemo - Demonstrate typical getopt_long(3)-based command-line argument parsing.\n");

    printf("Usage: getoptdemo [options] [objects...]\n");

    printf("Options and flags:\n");

    printf("   -h, --help             Show this message\n");

    printf("   -Q, --question         Make a question\n");

    printf("   -E, --exclamation      Finish with an exclamation sign\n");

    printf("   -t, --tool=<number>    Set 'tool' attribute\n");

    printf("   -a, --adj[=<number>]   Add an adjective\n");

    exit(0);

}

static struct option long_options[] = {

    {"help",        no_argument,       0,  0 },

    {"question",    no_argument,       0,  0 },

    {"exclamation", no_argument,       0,  0 },

    {"tool",        required_argument, 0,  0 },

    {"adj",         optional_argument, 0,  0 },

    {0,         0,                 0,  0 }

};

int main(int argc, char* argv[]) {

    int i;

    for(i=0; i<argc; i+=1) {

        fprintf(stderr, "\"Physical\" command-line argument #%d: `%s`\n", i, argv[i]);

    }

    struct Opts opts = {0,0,0,0};

    for(;;) {

        int c;

        int option_index;

        c = getopt_long(argc, argv, "hQEt:a::", long_options, &option_index);

        if (c == -1) break;

        if (c == '?') return 1;

        switch (c) {

            case 0: break;

            case 'h': option_index=0; break;

            case 'Q': option_index=1; break;

            case 'E': option_index=2; break;

            case 't': option_index=3; break;

            case 'a': option_index=4; break;

        }

        fprintf(stderr, "Option `%s`", long_options[option_index].name);

        if (optarg) {

            fprintf(stderr, " with value `%s`", optarg);

        }

        fprintf(stderr, "\n");

        switch (option_index) {

            case 0: // --help

                help();

                break;

            case 1: // --question

                opts.q = 1;

                break;

            case 2: // --exclamation

                opts.e = 1;

                break;

            case 3: // --tool

                opts.tool = atoi(optarg);

                if (opts.tool < 1 || opts.tool > 3) {

                    fprintf(stderr, "Error: tool number is out of range [1,3]\n");

                    exit(1);

                }

                break;

            case 4: // --adj

                if (optarg) {

                    opts.adj = atoi(optarg);

                    if (opts.adj < 1 || opts.adj > 3) {

                        fprintf(stderr, "Error: adjective number is out of range [1,3]\n");

                        exit(1);

                    }

                } else {

                    srand(time(NULL));

                    opts.adj = 1 + (rand() % 3);

                }

                break;

        }

    }

    for(i=optind; i<argc; i+=1) {

        fprintf(stderr, "Positional argument #%d: `%s`\n", i-optind+1, argv[i]);

    }

    show(&opts, argv+optind);

    return 0;

}

Command lines to try

Bash

Bash is a popular command line shell (and a programming language) in Linux.

Some keyboard shortcuts: bash

Some keyboard shortcuts: terminal

Some keyboard shortcuts: terminal emulator

A programming language

I=0;

while [ $I -lt 10 ]; do

   echo $I

   I=$((I+1))

done

Bash is also a programming language (also called “shell” or “shell script”). There are branching and looping. Strings are interpolated (means various characters trigger special things).

Note: online bash https://www.tutorialspoint.com/unix_terminal_online.php.

Whitespace is important

I=0;

while [ $I -lt 10 ]; do

   echo $I

   I=$((I+1))

done

Conditionals and chaining

test -e myfile.txt; echo $?

test -e myfile.txt && echo Yes

test -e myfile.txt && test 5 -gt 4 && echo Both yes

if test -e myfile.txt && test 5 -gt 4; then echo Both yes; fi

if [ -e myfile.txt ] && [ 5 -gt 4 ]; then echo Both yes; fi

if [[ -e myfile.txt && 5 -gt 4 ]]; then echo Both yes; fi

test -e myfile.txt && echo Yes || echo No

if [ -e myfile.txt ]; then echo Yes; else echo No; fi

set -e

set -x

Some important Bash’s string interpolations

Variables

$ T=qwer

$ echo rrr $T hhh "qqq $T"

rrr qwer hhh qqq qwer

Starting other commands

$ date

Fri Mar 20 19:43:35 FET 2015

$ echo qqq `date` www $(date)

qqq Fri Mar 20 19:43:35 FET 2015 www Fri Mar 20 19:43:35 FET 2015

Arithmetics

$ echo "2*2+2 = $((2*2+2))"

2*2+2 = 6

Mask

rm *.txt

It gets "unwrapped" to sub-array, not just to single value.

Splitting string to array

You input a string. But command line arguments is an array of strings. Therefore shell needs to split your string into array.

Example:

$ args arg1 arg2\ arg3 arg4\" arg5 "arg6 arg7\ arg8"\ arg9 arg10 ""

[1]=arg1

[2]=arg2 arg3

[3]=arg4"

[4]=arg5

[5]=arg6 arg7\ arg8 arg9

[6]=arg10

[7]=

Exercise 1:

Split this to array like Bash do:

dsfs m s Kqq dsf" "qwe' 'qwe\ q1 "' 123 ''" ''"" 11\'\"

Exercise 2:

Implement "args" program that behaves like the one above (outputs all command line arguments, one on each line, with a line numbers).

Реализуйте программу "args" которая работает как та, что выше (выводит все аргументы командной строки, по одному на строку, с нумерацией строк).

Exercise 3:

Construct a command line that splits to the following parts:

Virtual and real file systems

VFS - виртуальная файловая система.

VFS is what the programs in Linux work with.

get_preview

Basic file operations

File descriptor - like HANDLE on Windows. A process-specific number pointing to some object in Linux kernel.

Basic directory operations

File types

File locations

Some important customary locations

Домашний каталог пользователя

Home directory

Paths

Exercise 1

Normalize the path: /1/2/3/.././../4/../..///a/b/c/././.

/1/2/3

Current directory

Текущий каталог

Each process has current directory. There is no current drive like in Windows although.

Shell prompt typically shows the current directory.

File descriptors

Файловый дескриптор

File descriptor is an identifier of opened file (or something special instead of a file) in the given process. For example, the connection between shell and terminal emulator is also handled using file descriptors.

File descriptors may be pre-opened when a process starts.

Inodes

chart

The can be symbolic and hard links between files.

chart

There can be symbolic links between directories, but not hard links.

Russian: символическая ссылка, жёсткая ссылка.

Text files

Array of lines. Line is array of characters ending in \n.

More bash

Navigating file system, handling files

"concatenate"

Redirections

Redirection of standard output into a file

Перенаправление стандартного вывода в файл

Redirection of standard input from a file

Перенаправление стандартного ввода из файла

chart

Let's see what happens in detail:

chart

q.png

q.png

q.png

Exersice 1

Try drawing the similar diagram set for "cat > file.txt" case.

Pipelines

Конвейеры

A pipeline of "echo qqq" and "cat".

Конвейер из "echo qqq" и "cat".

Example: cat file.txt | tr a b | cat > output.txt

q.png

Some easy text processing programs, for exercises:

Exercise 1

Output 9 last lines of the source code of "args" program, reversing each line

Exercise 2

Output in the reverse order the lines of the source code of "args" containing opening parenthesis "(" , changing the "m" character into double quote ", also changing the semicolon ; into the space character.

Выведите в обратном порядке строки исходного кода программы "args", содержащие открывающую скобку "(", заменяя символ "m" на двойную кавычку ", также заменяя точку с запятой ; на пробел.

File management

Exercise 1

Exchange two files.

Exercise 2

Exchange two files using "ln" and "rm" commands.

Environment variables

Переменные окружения

Setting envvars in bash:

export ENVVAR=value

export Q = 4 # wrong

ENVVAR=value

export ENVVAR

PATH=$PATH:$HOME/bin

PATH=$HOME/bin:$PATH

A=b some_program

Exit code

Статус возврата команды

$ cp dsf sadfdsaf

cp: cannot stat `dsf': No such file or directory

$ echo $?

1

if cp i_want_this_file.txt output.txt ; then

   echo Allright

elif

   echo Copying failed

fi

------------

while ! cp i_want_this_file.txt output.txt ; do

   echo Cannot copy, do something

   bash

   echo Checking again...

done

echo Success

----------

cp first_variant.txt output.txt || cp second_variant output.txt

cp a.txt b.txt && cp b.txt c.txt

[ "3" == "4" ] && echo Do the impossible

Exercise 1

Save the "while ! cp" fragment to new file, start it as Bash program, test it.

Сохраните фрагмент "while ! cp" в файл, запустите его как программу на Bash, протестируйте.

Job control

Exercise 1

Go to your home directory. Create a file named qwe.txt with content Noooooo'o"ooo!.

Copy this file into ewq.txt.

Go to root directory.

Start program "cat" without arguments. Type the line "hello" into it.

Suspend the currently running program to background.

Output content of the file you have created.

List jobs.

Why this time "cat" finished and returned to shell, but previous "cat" was blocking the input?

Resume the backgrounded program and type "goodbye" into it.

Terminate the running program and return to shell.

Supplementary things (in Russian):

https://docs.google.com/document/d/1nZavuVuayZH_n-7yf_0jLDPFlasIurFVXAnlbJ-qlsI/edit?usp=sharing

Next parts