===== Introduction ===== ==== A bit of history ==== Terminal and console were a piece of hardware that let you interface with a computer. * [[https://www.merriam-webster.com/dictionary/terminal|terminal]]: a combination of a keyboard and output device (such as a video display unit) by which data can be entered into or output from a computer or electronic communications system * [[https://www.merriam-webster.com/dictionary/console|console]]: a combination of readouts or displays and an input device (such as a keyboard or switches) by which an operator can monitor and interact with a system (such as a computer or dubber) https://thevaluable.dev/guide-terminal-shell-console/ 'Terminal' and 'console' are nowadays used to name any (way of accessing a) text interface (of the operating system). ==== Unix-like operating systems ==== https://en.wikipedia.org/wiki/Unix-like POSIX - a standard (published by IEEE and The Open Group) for operating system interface and environment, predominantly built to unify Unix-like systems GNU/Linux * [[https://www.gnu.org/gnu/gnu.html|GNU]] is a collection of free software that altogether forms an operating system supplied with a broad choice of user applications [[https://www.gnu.org/manual/blurbs.html]] * the kernel of GNU, [[https://www.gnu.org/software/hurd/|Hurd]], has never been fit enough for the task * therefore GNU software is usually run on top of Linux kernel * most Linux distributions, apart form GNU software, has also a multitude of other software (not necessarely free or open source) ==== Shell and vital utilities ==== Shell is a program that provides a (text) interface to an operating system. There is a bunch of such programs https://en.wikipedia.org/wiki/Comparison_of_command_shells [[https://wiki.archlinux.org/title/Command-line_shell|[1]]] Shells for Unix-like systems include at least ''sh'', ''csh'', ''tcsh'', ''ksh'', ''bash'', ''zsh'', ''dash'', ''busybox'', ''fish'' \\ Windows provides ''cmd.exe'' and ''PowerShell'' shells. A shell reads commands from input and executes them. An example of a command is a program name followed by a list of arguments (separated by space). \\ Apart from a shell, to control the operating system, one needs also a set of programs that realize basic tasks. Such programs are sometimes called utilities. As well as there are multiple implementations of a shell, so there are multiple implementations of the basic utilities. * GNU/Linux systems usually use [[https://en.wikipedia.org/wiki/GNU_Core_Utilities|GNU core utilities]] and [[https://en.wikipedia.org/wiki/Util-linux|Linux utilities]] * .*BSD systems ship with their own implementations: [[https://cvsweb.openbsd.org/src/bin/|OpenBSD]], [[https://svnweb.freebsd.org/base/head/bin/|FreeBSD]] * Apple operating systems (e.g. MacOS) ship with modified BSD tools [[https://opensource.apple.com/releases/|[1]]] [[https://github.com/apple-oss-distributions/file_cmds|[2]]] [[https://github.com/apple-oss-distributions/text_cmds|[3]]] * Embedded / resource restrained systems often use [[https://www.busybox.net/downloads/BusyBox.html|BusyBox]] * Android uses [[https://www.landley.net/toybox/|toybox]] [[https://​cs.android.com/​android/​platform/​superproject/main/+/main:​external/​toybox/toys/posix/|[4]]] * For more, see [[https://wiki.archlinux.org/title/core_utilities]] POSIX standarizes both the [[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html|shell]] and its vital [[https://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html|utilities]]. ==== Accessing the shell ==== === Locally === When one uses a graphical user interface, to access a shell one can run a [[https://en.wikipedia.org/wiki/Terminal_emulator|terminal emulator]]. There are numerous terminal emulators (consult a [[https://en.wikipedia.org/wiki/List_of_terminal_emulators|list]] on Wikipedia). A choice of terminal emulators: * a widespread legacy [[https://en.wikipedia.org/wiki/Xterm|xterm]] * terminals bundled with some Linux desktop environment: [[https://docs.xfce.org/apps/terminal/start|xfce4-terminal]], [[https://en.wikipedia.org/wiki/GNOME_Terminal|GNOME Terminal]], [[https://konsole.kde.org/|konsole]] * default MacOS [[https://en.wikipedia.org/wiki/Terminal_(macOS)|Terminal]] * drop-down terminals: [[https://apps.kde.org/yakuake/|yakuake]] / [[http://guake-project.org/|guake]](([[https://​web.archive.org/​web/​20230709030453/​http://​guake-project.org/​|Project homepage archived by archive.org]],​ [[https://​github.com/​Guake/​guake/​|github]])) / [[https://github.com/lanoxx/tilda|tilda]] Linux typically starts a [[https://en.wikipedia.org/wiki/Getty_(Unix)|program]] that enables logging into shell in several [[https://en.wikipedia.org/wiki/Virtual_console|virtual consoles]] alongside a graphical interface. \\ To switch to a virtual console one may use //Ctrl+Alt+Fn// shortcut, where //Fn// is a function key (//F1//÷//F12//). \\ Typically numbers 1÷6 are text terminals, 7 stands for first graphical console, and some systems are configured to output system log messages to virtual console 12 === Remotely === A standard way to work with remote UNIX-like systems is to log into a shell of the system using a SSH (Secure SHell) client. \\ The basic command to log into a shell on a remote system is: \\ **''ssh //user//@//host//''** \\ where ''user'' is the user name and ''host'' is the name or address of the target device. \\ For instance, if used ''john'' would like to log into a computer named ''polluks.cs.put.poznan.pl'', he would have to input \\ ''ssh john@polluks.cs.put.poznan.pl''. Currently all major operating systems (including Windows) provide ''ssh'' command by default. Secure SHell encrypts all traffic. Its predecessor – telnet – sends all data (including passwords) in plaintext. Upon password authentication, the client must send the password to the server. \\ It is vital for security to confirm the authenticity of the server – the client must verify that it does not contact a rogue server that can learn the password ([[https://​docs.ssh-mitm.at/​user_guide/​authentication.html#id2|ready-to-go tool]]) and/or hijacks the session. \\ [[https://en.wikipedia.org/wiki/Public-key_cryptography|Asymmetric cryptography]] is used to this end: the server has a (secret) private key, and upon each connection it sends the public key to the client, and the client verifies whether the public key pairs with the private. \\ Hence, upon the first connection to a new server the SSH client program requests the user to verify the authenticity of the public key and stores the key (in OpenSSH in ''​~/​.ssh/​known_hosts'') to verify it automatically upon subsequent connections. ~~Exercise.#~~ Run a terminal emulator. Execute command ''date'' and ''echo $SHELL'' within. ~~Exercise.#~~ Execute command ''​sleep 1h''​ and interrupt it by pressing //Ctrl + c//. ~~Exercise.#~~ Switch to second virtual console and log in. Execute ''pwgen''. Return to graphical console. ~~Exercise.#~~ Use SSH to access ''polluks.cs.put.poznan.pl''. ===== Getting help ===== ==== System manual and 'help' switch ==== Most commands will display help when run with **''--help''** argument. Some commands also use ''-h'' for this. ~~Exercise.#~~ Display help for ''cat'' and ''bat'' commands by running them with help option. (NB: ''bat'' is installed by default only in some Linux distros.) Usually together with a program comes with a set of system manual pages. The pages can be displayed using the **''man //pagename//''** command. To leave the manual, type ''q''. ~~Exercise.#~~ Display manual page for ''timeout'' command. Manual pages are organized into sections. Use ''man man'' to learn about the standard sections. \\ Page names are unique within a section, but there may be pages with the same name in different sections. \\ You may use the **''whatis //pagename//''** command to learn which sections contain given page name and display the full page title. ~~Exercise.#~~ List all pages that are named ''time''. To select a page from a given section, one has to use ''man //section// //pagename//'' syntax. ~~Exercise.#~~ The ''man'' itself is described on two manual pages. Display both. What information is contained in each one? ''man'' uses another tool, called ''less'', to actually display the manual pages. ''less'' will be discussed in details later.\\ To search for text in ''less'', one can type **''/''** followed by the search term and //Enter//. Next / previous occurrence of the search term can be found by typing **''n''** / ''N''. To jump to the beginning of the document press ''g''. ''h'' displays a summary of ''less'' commands. ~~Exercise.#~~ Display manual page for ''bash'' and search for ''printf'' there. Then, search for explanation of ''dirs'' command. For searching within manual there is also the ''apropos //what//'' command that searches within page names and titles. Apart from ''man'', there is an alternative (and less popular) documentation system called ''info''. To see an Info page, type ''info //name//''. Some programs ship with a more detailed Info document than manual page. ==== Command syntax notation ==== Manuals, documentation and examples for commands traditionally use a set of square and curly brackets to indicate (respectively) optional parts and choice of one of alternatives. Sometimes arbitrary brackets are used to list alternatives: this is the case if they contain tokens separated by a ''|'' character. Angle brackets are sometimes used to name elements. \\ * ''wait [pid]'' means that both ''wait'' and ''wait 1234'' is a correct command (provided 1234 is a pid) * ''grep --color[=WHEN]'' means that both ''grep --color'' and ''grep --color=always'' are correct * ''tar {c|x}'' means that one must write either ''tar c'' or ''tar x'' Ellipsis is used to indicate that a part of command may repeat, e.g. ''cat [FILE]...'' says that ''cat'' accepts multiple filenames. Many programs accept //options// (called also //switches//) in the argument list. \\ The options are often written as short options in form ''-o'' where ''o'' is a single character and long options ''--option'' where ''option'' is the option name. \\ Some programs use only long options preceded with single dash (e.g., ''find'', ''convert'', ''ffmpeg''). \\ Short options can usually be combined in the following way: ''ls -color'' is identical to ''ls -c -o -l -o -r'' (and different than ''ls --color'') Options may require an argument or may accept an optional argument. Apart form command name, options (and keywords, if any) all other text is a placeholder for concrete values. \\ For instance, in ''find -amin N'' and ''find -anewer FILE'' the ''N'' and ''FILE'' are such placeholders: ''N'' must be replaced by number of minutes, and ''FILE'' must be replaced by a name of a file. ~~Exercise.#~~ Run: \\ ''man zip'' and review the SYNOPSIS, \\ ''findmnt --help'' and explain its syntax \\ ''taskset -h'' and explain its syntax ==== Autocompletion ==== Almost any shell supports autocompletion. It is invoked by pressing **//TAB//** key.\\ Autocompletion is supposed to type the rest of a word for you, and does so if only one possibility is found.\\ If autocompletion recognizes multiple possibilities, it does nothing. If one presses //TAB// key again, most autocompletion procedures display all possibilities. Autocompletion implementation differs across shells. Many shells support context-aware helpers. ~~Exercise.#~~ Type ''vu'' and press //TAB//. Type ''ba'' and press //TAB// twice. ~~Exercise.#~~ Type ''man --'' and press //TAB// twice. Type ''man fs'' and press //TAB// twice. ===== Browsing the filesystem ===== ==== File tree ==== In Unix-like systems all files and directories are organized in a tree, i.e., any two files share the same top-level directory called [[https://en.wikipedia.org/wiki/Root_directory|root directory]]. The path to root directory is **''/''**. \\ Filesystems other than the root one (e.g., other partitions, compact disks, flash drives), are //mounted// inside a selected directory located within ''/'' (rather than being a separate file hierarchy). A path is a chain of names separated by ''/''. \\ **''.''** stands for current directory and **''..''** stands for parent directory. \\ A path that starts with ''/'' is called absolute. A path that is not absolute is called relative. In Unix-like system each process has its working directory. Relative paths are resolved relative to the working directory. Each user has a [[https://en.wikipedia.org/wiki/Home_directory|home directory]]. Shell (and some other programs) replaces the word **''~''** with home directory of the current user. ''~user'' stands for home directory of ''user'', so ''~/x/a.txt'' is within home directory of current user, and ''~x/b.txt'' is within home directory of user ''x''. ==== Listing directory contents ==== The command **''ls [//dir//]''** lists file in directory ''dir''. When run with no arguments, it lists the current working directory. \\ By default ''ls'' does not list hidden files. The **''-a''** and ''--all'' switch changes this behaviour. \\ Switch **''-l''** / ''--list'' prints list of files with details such as file owner, size, modification date, etc. ~~Exercise.#~~ List files in ''/usr/share/zoneinfo/'' and ''../../../../../bin''. ~~Exercise.#~~ List all files in your home directory. ~~Exercise.#~~ Test the following switches with ''ls'' command: ''-A''   ''-d''   ''-s''   ''-h''   ''-t''   ''-1'' Apart from ''ls'' command, there are standard ''dir'' and ''vdir'' commands that list files. \\ Shell is often configured to use colors in ''ls'' by default and understand ''ll'' as ''ls -l'', and ''la'' as ''ls -l -a''. The ''tree'' command outputs recursively contents of the directory in a tree form. ==== Changing working directory ==== To print the working directory one can execute the **''pwd''** command. ~~Exercise.#~~ Check in which directory you end up upon logging into the system. To change directory the command **''cd [//target//]''** is used. If no target is provided, ''cd'' changes current directory to the home directory. \\ If ''-'' is uses as the target, the directory is changed to the previously visited. ~~Exercise.#~~ Enter ''.config'' directory (located in your home directory) and list files within. ~~Exercise.#~~ Navigate to ''/var/log''. What is stored there? ~~Exercise.#~~ Go back to where you've been before with ''cd -'' To change directory and save the previous one can use ''pushd //dir//'' command. \\ ''pushd //dir//'' pushes the previous directory on a directory stack. The directory stack can be displayed with ''dirs'' command. \\ To change back one can either execute ''popd'' (that removes a directory from the stack and enters it) or ''pushd'' (that swaps current directory with the directory on the stack). ''pushd'' and ''popd'' accept arguments ''+n''/''-n'' that select directory on the stack. ==== Wildcard, regex, … ==== In computer science patterns/expressions that describe the expected data can be expressed and used to match against some data, usually to find fitting data or check if the data matches the description. \\ For instance, //lines beginning with a word followed by an equals sign// might be written as a regular expression ''​^\w+=''​. There are countless syntaxes and implementations of such patterns/expressions. In the shell, [[https://en.wikipedia.org/wiki/Wildcard_character|wildcards]] and [[https://​en.wikipedia.org/​wiki/​Regular_expression|regular expressions]] are commonplace. Syntax and implementation of both wildcards and regexes is language/application specific. \\ The shell uses syntax summarized e.g., in ''​[[https://​man7.org/​linux/​man-pages/​man7/​glob.7.html|man 7 glob]]'' and ''​[[https://​man7.org/​linux/​man-pages/​man7/​regex.7.html|man 7 regex]]''​ ==== Glob names and wildcards ==== Upon parsing the user input, the shell attempts to replace with filenames any word containing wildcard characters **''*''**, **''?''** and expressions in square brackets **''[…]''**. A word that contains such wildcards is called [[https://en.wikipedia.org/wiki/Glob_(programming)|glob]]. ''*'' expands to any text\\ ''?'' expand to single character\\ ''[ace]'' expands to either ''a'', or ''c'', or ''e'' \\ ''[f-h]'' expands to either ''f'', or ''g'', or ''h'' If there is at least one file that matches the glob, the shell replaces the glob with all filenames that match. If no file matches, then the glob is left unaltered. ~~Exercise.#~~ Change directory to ''/usr/bin/'' directory. List all files that end with ''cat''. ~~Exercise.#~~ List all files that end with ''cat'' in ''/usr/bin/'' while being in your home directory. ~~Exercise.#~~ List all files that are in the ''/usr/bin/'' directory that have names consisting of two chatacters. ~~Exercise.#~~ List contents of ''/usr/share/zoneinfo/'' and its subdirectories using a single command. ~~Exercise.#~~ List all files named ''UTC'' that are in any subdirectory of ''/usr/share/zoneinfo/''. ~~Exercise.#~~ List all files starting with ''L'' that are in any subdirectory of ''/usr/share/zoneinfo/''. ~~Exercise.#~~ List all files starting with ''F'' or ''H'' that are in any subdirectory of ''/usr/share/zoneinfo/''. Use a single glob. ~~Exercise.#~~ Navigate to ''/usr/bin'' and attempt to execute ''ls*''. What has happened? ~~META: language = en ~~