This commit is contained in:
Miloslav Ciz 2025-03-04 21:04:02 +01:00
parent 638265b6fe
commit 07603f7b64
14 changed files with 1975 additions and 1933 deletions

65
unix.md
View file

@ -33,11 +33,13 @@ UNDER CONSTRUCTION
*Note: here by "Unix" we will more or less assume a system conforming to some version of the POSIX standard.*
This section will help complete noobs kickstart their journey with a Unix-like system such as [GNU](gnu.md)/[Linux](linux.md) or [BSD](bsd.md). Please be aware that each system has its additional specifics, for example [package managers](package_manager.md), init systems and so on -- these you must learn about elsewhere as here we may only cover the core parts those systems inherited from the original Unix. Having learned this though you should be able to somewhat fly any Unix like system. Obviously we'll be making some simplifications here too.
This should help complete noobs kickstart their journey with a Unix-like system such as [GNU](gnu.md)/[Linux](linux.md) or [BSD](bsd.md). Please be aware that each system has its additional specifics, for example [package managers](package_manager.md), init systems, [GUI](gui.md) and so on -- these you must learn about elsewhere as here we may only cover the core parts those systems inherited from the original Unix. Having learned this though you should be able to somewhat fly any Unix like system. Obviously we'll be making some simplifications here too, don't be too pedantic if you're a pro Unix guru please.
Learning to use Unix practically means **learning the [command line](cli.md)** plus a few extra things (such as various concepts, philosophies, conventions, file system structure etc.). Your system will have a way for you to enter the command line where you can interact with it only through textual commands (i.e. without [GUI](gui.md)). Sometimes the system boots up to command line, sometimes you must click some icon (usually called *terminal*, *term*, *shell*, *command line* etc.), sometimes you can switch [TTY](tty.md)s with *CTRL+ALT+Fkeys* etc. To command line virgins this will seem a little intimidating but it's absolutely required to know at least the basics, on Unices the command line is extremely powerful, efficient and much can only ever be achieved through command line.
Also a NOTE: terms such as *command line*, *terminal* or *shell* have different meanings, but for simplicity we'll be treating them more or less as synonyms here.
**The gist**: unsurprisingly in command line you write commands -- many of these are actually tiny programs called **Unix utilities** (or just "utils"). These are tools for you to do whatever you want (including stuff that on normie systems are usually done by clicking with a [mouse](mouse.md)). For example `ls` is a program that writes out list of files in the working directory, `cd` is a program that changes working directory etc. There are many more such programs and you must learn at least the most commonly used ones. Good news is that these programs are more or less the same on every Unix system so you just learn this once. There also exist other kinds of commands -- those defined by the shell language ([shell](shell.md) is basically a fancy word for the textual interface), which allow us to combine the utilities together and even [program](programming.md) the shell (we call this [scripting](script.md)). First learn the utils (see the list below).
Learning to use Unix in practical terms firstly means **learning the [command line](cli.md)** and then a few extra things (various concepts, philosophies, conventions, file system structure etc.). Your system will have a way for you to enter the command line that allows you to interact with it only through textual commands (i.e. without [GUI](gui.md)). Sometimes the system boots up to command line, other time you must click an icon somewhere (called *terminal*, *term*, *shell*, *command line* etc.), sometimes you can switch [TTY](tty.md)s with *CTRL+ALT+Fkeys* etc. To command line virgins this will seem a little intimidating but it's absolutely necessary to know at least the basics, on Unices the command line is extremely powerful, efficient and much can only ever be achieved through the command line.
**The gist**: unsurprisingly in command line you write commands -- many of these are actually tiny programs called **Unix utilities** (or just "utils"). These are installed by default and, they're tools for you to do whatever you want (including stuff that on normie systems you usually do by clicking with a [mouse](mouse.md)). For example `ls` is a program that writes out list of files in the working directory, `cd` is a program that changes working directory etc. There are many more such programs and you must learn at least the most commonly used ones. Good news is that the programs are more or less the same on every Unix system so you just learn this once. There also exist other kinds of commands -- those defined by the shell language ([shell](shell.md) is basically a fancy word for the textual interface), which allow us to combine the utilities together and even [program](programming.md) the shell (we call this [scripting](script.md)). First learn the utils (see the list below).
PRO TIP: convenient features are often implemented, most useful ones include going through the history of previously typed commands with UP/DOWN keys and completing commands with the TAB key, which you'll find yourself using very frequently. Try it. It's enough to type just first few letters and then press tab, the command will be completed (at least as much as can be guessed).
@ -51,17 +53,13 @@ To **run a program** that's present in the current directory as a file you can't
Now to the very basic stuff: **browsing directories, moving and deleting files etc.** This is done with the following utils: `ls` (prints files in current directory), `pwd` (prints path to current directory), `cd` (travels to given directory, `cd ..` travels back), `cat` (outputs content of given file), `mkdir` (creates directory), `rm` (removes given file; to remove a directory `-rf` flag must be present), `cp` (copies file), `mv` (moves file, including directory -- note that moving also serves for renaming). As an exercise try these out (careful with `rm -rf`) and read manual pages of the commands (you'll find that `ls` can also tell you for example the file sizes and so on).
**Files and file system**: On Unices the whole filesystem hierarchy starts with a directory called just `/` (the root directory), i.e. every absolute (full) path will always start with slash. For example pictures belonging to the user *john* may live under `/home/john/pictures`. It's also possible to use relative paths, i.e. ones that are considered to start in the current (working) directory. A dot (`.`) stands for current directory and two dots (`..`) for the directory "above" the current one. I.e. if our current directory is `/home/john`, we can list the pictures with `ls pictures` as well as `ls /home/john/pictures` or `ls ./pictures`. Absolute and relative paths are distinguished by the fact the absolute one always starts with `/` while relative don't. There are several **types of files**, most importantly *regular files* (the "normal" files) and *directories* (there are more such *symbolic links*, *sockets*, *block special files* etc., but for now we'll be ignoring these). Unix has a [paradigm](paradigm.md) stating that **everything's a [file](file.md)**, so notably accessing e.g. hardware devices is done by accessing special device files (placed in `/dev`).
**Files and file system**: On Unices the whole filesystem hierarchy starts with a directory called just `/` (the root directory), i.e. every absolute (full) path will always start with slash (don't confuse `/` with `\`). For example pictures belonging to the user *john* may live under `/home/john/pictures`. It's also possible to use relative paths, i.e. ones that are considered to start in the current (working) directory. A dot (`.`) stands for current directory and two dots (`..`) for the directory "above" the current one. I.e. if our current directory is `/home/john`, we can list the pictures with `ls pictures` as well as `ls /home/john/pictures` or `ls ./pictures`. Absolute and relative paths are distinguished by the fact the absolute one always starts with `/` while relative don't. There are several **types of files**, most importantly *regular files* (the "normal" files) and *directories* (there are more such *symbolic links*, *sockets*, *block special files* etc., but for now we'll be ignoring these). Unix has a [paradigm](paradigm.md) stating that **everything's a [file](file.md)**, so notably accessing e.g. hardware devices is done by accessing special device files (placed in `/dev`). Just remember this concept, you'll hear about it often.
NOTE: On Unices files often don't have extensions as it's often relied on so called [magic number](magic_numbers.md) (first few bytes in the file) to decide what kind of file we're dealing with. You will see files with extension (`.sh`, `.txt`, ...) but notably for example compiled programs typically don't have any (unlike for example on [Windows](windows.md)).
Files additionally have attributes, importantly so called **permissions** -- unfortunately these are a bit complicated, but as a mere user working with your own files you won't have to deal too much with them, only remember if you encounter issues with accessing files, it's likely due to this. In short: each file has an owner and then also a set of permissions that say who's allowed to do what with the file. There are three kind of permissions: *read* (`r`), *write* (`w`) and *execute* (`x`), and ALL THREE are defined for the file's owner, for the file's group and for everyone else, plus there is a magical value suid/sgid/sticky we won't delve into. All of this is then usually written either as a 4 digit [octal](octal.md) number (each digit expresses the three permission [bits](bit.md)) or as a 12 character string (containing the `r`/`w`/`x`/`-` characters). Well, let's not dig much deeper now.
TODO: more more more
PRO TIP: there is a very useful feature called **wildcard characters** that help us handle many files at once. Most commonly used are `*` and `?` wildcards -- if we use these in a program argument, the arguments will be expanded so that we get a list of files matching certain pattern. This sounds complicated but let's see an example. If we write let's say `rm *.jpg`, we are going to remove all files in current directory whose name ends with `.jpg`. This is because `*` is a wildcard character that matches any string and when we execute the command, the shell actually replaces our argument with all files that match our pattern, so the command may actually internally look like `rm picture1.jpg picture2.jpg picture3.jpg`. `?` character is similar but matches exactly one character (whatever it is), so to list for example all files whose name is exactly three characters we can write `ls ???`.
Here is a quick cheatsheet of the most common Unix utilities:
@ -100,11 +98,11 @@ Here is a quick cheatsheet of the most common Unix utilities:
| [vi](vi.md) | advanced text editor | |
| wc | word count (count characters or lines in file, can tell exact file size) | -c (character), -l (lines), file |
NOTES on the utilities:
NOTES on the above table:
- Typically there are two ways of feeding input data to a utility: either by specifying a file to read from or by feeding the input on to the utility's standard input. This also applies to the output. Using standard input/output is a more "Unix" way as it allows us to chain the utlities with pipes, make one program feed its output to another an input.
- Typically there are two ways of feeding input data to a utility: either by specifying a file to read from or by feeding the input on to the utility's standard input. This also applies to the output. Using standard input/output is a more "Unix" way as it allows us to chain the utlities with pipes, make one program feed its output to another as input.
- Utilities try to follow common conventions so that it's easier to guess and remember what flags mean etc., for example `-h` is commonly a flag for getting help, `-o` is one for specifying output file etc.
- Specific Unix systems will normally have more feature rich utilities, supporting additional flags and even adding new utilities. Check out manual pages on your system. You'll have to learn about common utils that aren't part of POSIX, e.g. [wget](wget.md), [ssh](ssh.md), [curl](curl.md), [sudo](sudo.md), [apt](apt.md) and more.
- Specific Unix systems will normally have more feature rich utilities, supporting additional flags and even adding new utilities. Check out manual pages on your system. You'll probably have to learn about common utils that aren't part of POSIX, e.g. *[wget](wget.md)*, *history*, *[ssh](ssh.md)*, *[curl](curl.md)*, *[sudo](sudo.md)*, *[apt](apt.md)* and more. And of course there are thousands and thousands of additional utilities/programs you can download, program or otherwise install on your system.
Now on to a key feature of Unix: **pipelines and redirects**. [Processes](process.md) (running programs) on Unix have so called **standard input** (*stdin*) and **standard output** (*stdout*) -- these are streams of data (often textual but also binary) that the process takes on input and output respectively. There may also exist more streams (notably e.g. *standard error output*) but again, we'll ignore this now. When you run a program (utility etc.) in the command line, standard input will normally come from your keyboard and standard output will be connected to the terminal (i.e. you'll see it being written out in the command line). However sometimes you may want the program to take input from a file and/or to write its output to a file (imagine e.g. keeping [logs](logging.md)), or you may even want one program to feed its output as an input to another program! This is very powerful as you may combine the many small utilities into more powerful units. See also [Unix philosophy](unix_philosophy.md).
@ -112,14 +110,45 @@ Most commonly used redirections are done like this:
- `command > file`: redirects output of *command* to file *file* (rewriting its content if there is any).
- `command < file`: redirects input of *command* to come from *file*.
- `command >> file`: output of *command* will be appended (added to the end) to *file*.
- `command >> file`: output of *command* will be appended to *file* (i.e. added at its end).
Pipelines are similar: they are chains of several programs separated by a "pipe" character: `|`. This makes a program feed its output to the input of the next program. For example `ls | grep \.html` will run the `ls` command and pass its output (list of files in current directory) to `grep`, which will only filter out those that contain the ".html" string.
Several commands can also be written on a single line, they just have to be separated with `;`.
**Example**:
**Example** of doing stuff in a Unix terminal (`#` character starts a [comment](comment.md) -- these are here only to describe what's happening in the example):
TODO: stdin/out/err, utils, shell, sh (running programs, ...), usual "workflows" (man pages, history, arrows, tab-completion, ...), often used commands, examples, permissions, variables and exit codes, wildcards
```
> pwd
/home/drummyfish
> ls
Pictures Documents Downloads
git Videos
> cd Downloads
> ls
free_software_song.midi hentai_porn.mp4
lrs_wiki.txt
> rm hentai_porn.mp4 # oh noes, quickly delete this
> cd ../git; ls
Anarch comun Licar
raycastlib small3dlib
> cd Anarch
> wc -l *.h *.c | tail -n 1 # count lines of code in .h and .c files
14711 total
> cat *.h *.c | grep "TODO" # show all TODOs in code
(SFG_game.backgroundScaleMap[(pixel->position.y // ^ TODO: get rid of mod?
RCL_Unit direction; // TODO: rename to "angle" to keep consistency
TODO: maybe array functions should be replaced by defines of funtion names
/* FIXME/TODO: The adjusted (=orthogonal, camera-space) distance could
RCL_Unit limit1, // TODO: int16_t?
RCL_Unit depth = 0; /* TODO: this is for clamping depth to 0 so that we don't
increment == -1 ? i >= limit : i <= limit; /* TODO: is efficient? */\
RCL_Unit limit1, // TODO: int16_t?
increment == -1 ? i >= limit : i <= limit; // TODO: is efficient?
// TODO: probably doesn't work
#if 1 // TODO: add other options for input handling (SDL, xinput, ...)
> echo "Remember to fix the TODOs in code!" >> TODO.txt # add note to TODO file
```
## See Also