Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revisionLast revisionBoth sides next revision | ||
pandoc:linux-wochen-wien:linux-101:linux-101 [2018/01/31 11:11] – Pandoc Auto-commit pandoc | pandoc:linux-wochen-wien:linux-101:linux-101 [2020/10/20 08:09] – Pandoc Auto-commit pandoc | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== History ====== | ||
+ | |||
+ | ==== Unix — Linux’ predecessor ==== | ||
+ | |||
+ | > Unix is from the ’70s: | ||
+ | |||
+ | |||
+ | * terminals are monochrome | ||
+ | * computers are big and expensive | ||
+ | * many people use the same computer | ||
+ | * networking becomes important | ||
+ | |||
+ | > Unix is free to modify: | ||
+ | |||
+ | |||
+ | * universities and companies have modified unix | ||
+ | * released as BSD/ | ||
+ | * fertile environment | ||
+ | * rise of similar, non-collaborating features | ||
+ | |||
+ | |||
+ | > Unix becomes the GCD of computing. | ||
+ | |||
+ | |||
+ | ==== Hacker culture ==== | ||
+ | |||
+ | > Freedom at stake: | ||
+ | |||
+ | |||
+ | * the way of sharing programs is changing | ||
+ | * best case: bsd-style license | ||
+ | * usually: corporate licenses | ||
+ | * exclude freedom of sharing code with anyone | ||
+ | |||
+ | > Sharing is caring: | ||
+ | |||
+ | |||
+ | * write code | ||
+ | * give away/sell product | ||
+ | * include **sourcecode** | ||
+ | * include the freedom/ | ||
+ | |||
+ | |||
+ | > People want to save their idea of moral responsibility by formalising it as a licenses | ||
+ | |||
+ | |||
+ | ==== GNU ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | > In 1984 RMS starts the **GNU** project, with the goal to provide a **free Unix**-compatible OS | ||
+ | |||
+ | > Steps to success: | ||
+ | |||
+ | |||
+ | |||
+ | * Write a license (GPL) | ||
+ | * respect the freedom of the users | ||
+ | * endorse ‘sharing is caring’ | ||
+ | * make the license transitive | ||
+ | * Write an Editor (emacs) | ||
+ | * Write a Compiler (gcc) | ||
+ | * Write common utilities (coreutils) | ||
+ | * Write everything else | ||
+ | * Write a kernel (hurd) | ||
+ | * Rewrite the kernel (hurd) | ||
+ | * One more time (hurd) | ||
+ | |||
+ | |||
+ | > Even though this project gets mocked for hurd, it is essential for Linux’ success! | ||
+ | |||
+ | |||
+ | ==== Linux ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | > In 1992 Linus Torvalds writes his own little **terminal emulator**, to be able to remotely access his university account. | ||
+ | |||
+ | > Later this code evolves into the **Linux kernel**, that together with many **GNU utilities** becomes **GNU/ | ||
+ | |||
+ | |||
+ | ^Segment | ||
+ | |Desktop | ||
+ | |Smartphone / Tablet| | ||
+ | |Server | ||
+ | |**Supercomputer** | ||
+ | |Mainframe | ||
+ | |Embedded | ||
+ | |||
+ | |||
+ | ==== Linux on Supercomputers ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ====== Prerequisites ====== | ||
+ | |||
+ | ==== Assumptions ==== | ||
+ | |||
+ | > You are familiar with either: | ||
+ | |||
+ | |||
+ | * **computers** in general | ||
+ | * **Windows** | ||
+ | * **macOS** | ||
+ | |||
+ | > When something breaks, you: | ||
+ | |||
+ | |||
+ | * ask for **assistance** //or// | ||
+ | * **read** up on the subject and **fix it** //and// | ||
+ | * **don’t** go on **using** it until it’s completly **dead** | ||
+ | |||
+ | |||
+ | ==== What do you know about Linux? ==== | ||
+ | |||
+ | > by a show of hands: | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | |||
+ | * Nothing | ||
+ | * I know my way around when it comes to: | ||
+ | * files and directories | ||
+ | * the shell basics | ||
+ | * most core utilities | ||
+ | * variables | ||
+ | * scripts | ||
+ | * streams | ||
+ | * All of the above and I want to take over | ||
+ | |||
+ | ====== Filesystems ====== | ||
+ | |||
+ | ==== Filesystem 101 ==== | ||
+ | |||
+ | |||
+ | - Everything starts at the root | ||
+ | * the root is a directory | ||
+ | * '' | ||
+ | - the filesystem has different kinds of objects | ||
+ | - files | ||
+ | - directories | ||
+ | * containers for multiple objects | ||
+ | - links to objects, which either | ||
+ | * add a second name for the same object | ||
+ | * point to a position in the filesystem | ||
+ | - objects can be referenced by their path | ||
+ | * absolute: '' | ||
+ | * relative: '' | ||
+ | - special objects in directories: | ||
+ | * '' | ||
+ | * '' | ||
+ | - the system may consist of multiple filesystems | ||
+ | * filesystems may be mounted at any (empty) directory | ||
+ | |||
+ | |||
+ | ==== The Filesystem represented as an ADT ==== | ||
+ | |||
+ | > These are the helper types: | ||
+ | |||
+ | < | ||
+ | type Name = String | ||
+ | type Children = [FSObject] | ||
+ | type Path = [FSObject] | ||
+ | data LinkType = Soft | Hard | ||
+ | </ | ||
+ | |||
+ | > This is the code describing a trivial Linux-ish filesystem in a mathematical notation: | ||
+ | |||
+ | < | ||
+ | data FSObject = File Name | ||
+ | | Dir Name Children | ||
+ | | Link Name Path LinkType | ||
+ | </ | ||
+ | |||
+ | |||
+ | > Missing: | ||
+ | |||
+ | * Special files | ||
+ | * device | ||
+ | * fifo pipe | ||
+ | * socket | ||
+ | * Attributes | ||
+ | * Advanced FS features | ||
+ | * data integrity | ||
+ | * device managment | ||
+ | * subvolume support | ||
+ | |||
+ | |||
+ | |||
+ | ==== FHS intro ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== FHS ==== | ||
+ | |||
+ | > The **Filesystem Hierarchy Standard** is a guideline for the structuring of local filesystems. | ||
+ | |||
+ | It aims for better **interoperability** between different Systems, by making it easy to figure out the **location** of any **kind of file**. | ||
+ | |||
+ | ^Directory | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/boot/** |files for boot support | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/home/** |users’ home direcories are located here | | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/proc/** |system-internals accessable as files | | ||
+ | |**/root/** |home directory of root | | ||
+ | |**/ | ||
+ | |**/sbin/** |like '' | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |**/ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Corner cases of FHS ==== | ||
+ | |||
+ | > Some systems don’t comply with the FHS, for various reasons. | ||
+ | |||
+ | === VSC3 === | ||
+ | |||
+ | * As the OS is basically a CentOS, the '' | ||
+ | |||
+ | === Distributions bringing new ideas to the table === | ||
+ | |||
+ | > [[http:// | ||
+ | |||
+ | * installed software packages get their own directory | ||
+ | * filesystem itself is a package store | ||
+ | |||
+ | > [[http:// | ||
+ | |||
+ | * solves the problem of user installable packages | ||
+ | * dependency management extended in a way, that aims to make trust a non-issue | ||
+ | |||
+ | |||
+ | ====== Shell ====== | ||
+ | |||
+ | ==== Login ==== | ||
+ | |||
+ | > The default login screen on most distributions looks something like this: | ||
+ | |||
+ | < | ||
+ | <<< | ||
+ | |||
+ | ${MACHINE_NAME} login: | ||
+ | password: | ||
+ | </ | ||
+ | < | ||
+ | |||
+ | |||
+ | username | ||
+ | <blank while typing> | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | <div class=" | ||
+ | <div> | ||
+ | <hr style=" | ||
+ | </ | ||
+ | > remote login looks similar: | ||
+ | |||
+ | <code bash> | ||
+ | $ ssh username@remote | ||
+ | password: | ||
+ | </ | ||
+ | < | ||
+ | </ | ||
+ | <div> | ||
+ | <hr style=" | ||
+ | </ | ||
+ | {{..: | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | > If the login was not successful, just try again. | ||
+ | |||
+ | > Beware, that systems may be configured to lock your account if too many attempts were made. | ||
+ | |||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | ==== Prompt ==== | ||
+ | |||
+ | > This is how the prompt looks by default: | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | <code bash> | ||
+ | [myname@l3_ ~]$ | ||
+ | </ | ||
+ | |||
+ | |||
+ | * tells you: | ||
+ | * who you are | ||
+ | * which computer you’re on | ||
+ | * which directory you’re in | ||
+ | * can be configured | ||
+ | * variable '' | ||
+ | * default: '' | ||
+ | |||
+ | > Ways to get help when you’re stuck: | ||
+ | |||
+ | |||
+ | * '' | ||
+ | * manual for specified topic | ||
+ | * find man-pages: '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * most commands support a '' | ||
+ | * colleagues are often helpful | ||
+ | * the internet is often helpful | ||
+ | |||
+ | |||
+ | ==== Execution ==== | ||
+ | |||
+ | To execute a program, we call it: | ||
+ | |||
+ | <code python> | ||
+ | nano file.txt | ||
+ | ./a.out -flag=value | ||
+ | gcc -I/ | ||
+ | module load non-existent-module | ||
+ | </ | ||
+ | |||
+ | |||
+ | * Every command that is executed will provide a return-value on exit. | ||
+ | * {{..: | ||
+ | * {{..: | ||
+ | |||
+ | |||
+ | === Program Arguments === | ||
+ | |||
+ | > The default way to apply arguments to a program is to write a space separated list of arguments after the program when calling it. | ||
+ | |||
+ | > Patterns and expansions are defining multiple arguments with little overhead: | ||
+ | |||
+ | |||
+ | |||
+ | * the most important patterns are: | ||
+ | * **?** — matches one character | ||
+ | * ***** — matches any character sequence | ||
+ | * the most important expansions are: | ||
+ | * **A{1,9}Z** — expands to A1Z A9Z | ||
+ | * **A{1..9}Z** — expands to A1Z A2Z … A9Z | ||
+ | |||
+ | |||
+ | ==== Control Flow ==== | ||
+ | |||
+ | === Chaining Commands === | ||
+ | |||
+ | <code bash> | ||
+ | false ; echo " | ||
+ | false && echo " | ||
+ | false || echo " | ||
+ | </ | ||
+ | <code bash> | ||
+ | Should I be Printed? | ||
+ | |||
+ | Should I be Printed? | ||
+ | </ | ||
+ | |||
+ | === Loops === | ||
+ | |||
+ | <code bash> | ||
+ | for i in * | ||
+ | do | ||
+ | mv $i{,.bak} | ||
+ | done | ||
+ | </ | ||
+ | <code bash> | ||
+ | while true | ||
+ | do | ||
+ | echo " | ||
+ | sleep 3 | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | > Or as one-liners: | ||
+ | |||
+ | <code bash> | ||
+ | for i in *; do mv $i{,.bak}; done | ||
+ | while true; do echo " | ||
+ | </ | ||
+ | |||
+ | ==== Aliases ==== | ||
+ | |||
+ | Whenever you have a command, which you: | ||
+ | |||
+ | |||
+ | - run often and it | ||
+ | * has a long list of parameters you always use | ||
+ | * is dangerous | ||
+ | - which is an aggregate of many other commands | ||
+ | * but you don’t want to write a script | ||
+ | |||
+ | you can define an alias for it: | ||
+ | |||
+ | <code bash> | ||
+ | alias ll='ls -alh' | ||
+ | alias myProject=' | ||
+ | </ | ||
+ | |||
+ | ==== History ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | > Your shell keeps a log of all the commands you executed. | ||
+ | |||
+ | |||
+ | * the '' | ||
+ | * for fast reuse of commands try the '' | ||
+ | |||
+ | ==== Streams ==== | ||
+ | |||
+ | === Redirects === | ||
+ | |||
+ | > Write **output** to a **file** or **file-descriptor** | ||
+ | |||
+ | ^Command^Redirect | ||
+ | |program|'' | ||
+ | |program|'' | ||
+ | |program|'' | ||
+ | |||
+ | |||
+ | === Pipes === | ||
+ | |||
+ | > Write **output** into the **input**-stream of another process | ||
+ | |||
+ | ^Command^Pipe | ||
+ | |program|'' | ||
+ | |program|'' | ||
+ | |program|'' | ||
+ | |||
+ | |||
+ | ====== Environment Variables ====== | ||
+ | |||
+ | ==== Setting, getting and unsetting ==== | ||
+ | |||
+ | === Set === | ||
+ | |||
+ | <code python> | ||
+ | LANG=de_AT.UTF-8 firefox | ||
+ | env LANG=de_AT.UTF-8 firefox | ||
+ | </ | ||
+ | <code python> | ||
+ | export LANG=de_AT.UTF-8 | ||
+ | </ | ||
+ | |||
+ | === Get === | ||
+ | |||
+ | <code python> | ||
+ | env | ||
+ | echo ${LANG} | ||
+ | </ | ||
+ | |||
+ | === Unset === | ||
+ | |||
+ | <code python> | ||
+ | unset LANG | ||
+ | env -u LANG | ||
+ | </ | ||
+ | |||
+ | ==== Use cases ==== | ||
+ | |||
+ | > Some variables that could affect you are: | ||
+ | |||
+ | <code python> | ||
+ | $EDITOR | ||
+ | $PAGER | ||
+ | $PATH # program paths, in priority order | ||
+ | </ | ||
+ | > if you’re aiming for programming, | ||
+ | |||
+ | <code python> | ||
+ | $LIBRARY_PATH | ||
+ | $LD_LIBRARY_PATH | ||
+ | $CC # sometimes used to set default C compiler | ||
+ | $CFLAGS | ||
+ | </ | ||
+ | |||
+ | ====== Core Utilities ====== | ||
+ | |||
+ | ==== Looking around ==== | ||
+ | |||
+ | > **looking around** is done by the **'' | ||
+ | |||
+ | < | ||
+ | $ ls # shows files and directories | ||
+ | |||
+ | $ ls -a # includes hidden ones | ||
+ | |||
+ | $ ls -l # detailed view | ||
+ | | ||
+ | </ | ||
+ | < | ||
+ | testdir | ||
+ | |||
+ | . .. testdir | ||
+ | |||
+ | drwxr-xr-x 1 myuser p12345 0 Apr 13 11:55 testdir | ||
+ | -rw-r--r-- 1 myuser p12345 4 Apr 13 11:55 test | ||
+ | </ | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ^command | ||
+ | |**'' | ||
+ | |**'' | ||
+ | |||
+ | |||
+ | ==== Moving around ==== | ||
+ | |||
+ | > **moving around** is done by the **'' | ||
+ | |||
+ | > **finding** the current **position** in the filesystem is done by the **'' | ||
+ | |||
+ | |||
+ | < | ||
+ | $ cd /bin # go to an absolute directory | ||
+ | |||
+ | $ cd [~] # go home | ||
+ | |||
+ | $ cd - # go to previous directory | ||
+ | </ | ||
+ | < | ||
+ | $ pwd # /bin | ||
+ | |||
+ | $ pwd # /home/user1 | ||
+ | |||
+ | $ pwd # /bin | ||
+ | </ | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Copying & moving files around ==== | ||
+ | |||
+ | > **moving files around** is done by the **'' | ||
+ | |||
+ | > **copying** is done by the **'' | ||
+ | |||
+ | |||
+ | < | ||
+ | $ mv old | ||
+ | |||
+ | $ mv old | ||
+ | |||
+ | $ mv file1 file2 # overwrite file2 with file1 | ||
+ | # (BEWARE) | ||
+ | </ | ||
+ | < | ||
+ | $ cp -i input input.bak | ||
+ | |||
+ | $ cp -i input backup/ | ||
+ | |||
+ | $ cp -a dir1/ dir2 # exact copy of dir1 | ||
+ | | ||
+ | </ | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Finding stuff ==== | ||
+ | |||
+ | > To look at everything | ||
+ | |||
+ | |||
+ | - in your home directory | ||
+ | - and nested up to three levels deep inside it | ||
+ | - that ends in '' | ||
+ | - or starts with '' | ||
+ | - and is an ordinary file | ||
+ | - concatenated as one stream: | ||
+ | |||
+ | <code bash> | ||
+ | find \ | ||
+ | ~ \ | ||
+ | -maxdepth 3 \ | ||
+ | -iname " | ||
+ | -or -iname " | ||
+ | -type f \ | ||
+ | -exec cat ' | ||
+ | </ | ||
+ | <code bash> | ||
+ | find \ | ||
+ | ~ \ | ||
+ | -maxdepth 3 \ | ||
+ | -iname " | ||
+ | -or -iname " | ||
+ | -type f \ | ||
+ | -exec cat ' | ||
+ | </ | ||
+ | |||
+ | ==== Creating and deleting ==== | ||
+ | |||
+ | === directories === | ||
+ | |||
+ | > **creating directories** is done by the **'' | ||
+ | |||
+ | > **deleting directories** is done by the **'' | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | $ mkdir newdir | ||
+ | |||
+ | $ mkdir -p new/ | ||
+ | </ | ||
+ | < | ||
+ | $ rmdir emptydir | ||
+ | |||
+ | $ rmdir -v emptydir | ||
+ | </ | ||
+ | |||
+ | === files === | ||
+ | |||
+ | > **creating files** is done by the **'' | ||
+ | |||
+ | > **deleting files** is done by the **'' | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | $ touch file # create empty file | ||
+ | |||
+ | $ echo " | ||
+ | </ | ||
+ | < | ||
+ | $ rm file # removes file | ||
+ | |||
+ | $ rm -ri dir # removes dir recursively | ||
+ | </ | ||
+ | |||
+ | ==== Contents of files ==== | ||
+ | |||
+ | > **viewing** is done by the **'' | ||
+ | |||
+ | > **concatenating** is done by the **'' | ||
+ | |||
+ | |||
+ | < | ||
+ | $ less file.txt | ||
+ | |||
+ | $ less -R file.txt | ||
+ | |||
+ | $ cat file1 file2 | less | ||
+ | </ | ||
+ | < | ||
+ | $ cat file | ||
+ | |||
+ | $ cat -A printable | ||
+ | |||
+ | $ cat -n numbered | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | $ echo "VSC is great" > file | ||
+ | $ cat file | ||
+ | VSC is great | ||
+ | </ | ||
+ | < | ||
+ | $ echo "VSC is awesome" | ||
+ | $ cat file | ||
+ | VSC is great | ||
+ | VSC is awesome | ||
+ | </ | ||
+ | < | ||
+ | $ cat file | grep awesome | ||
+ | VSC is awesome | ||
+ | </ | ||
+ | < | ||
+ | $ grep awesome file | ||
+ | VSC is awesome | ||
+ | </ | ||
+ | |||
+ | ==== Space accounting ==== | ||
+ | |||
+ | > viewing **used space** is done by the **'' | ||
+ | |||
+ | > viewing **free space** is done by the **'' | ||
+ | |||
+ | |||
+ | < | ||
+ | $ du -h file1 file2 # human readable output | ||
+ | |||
+ | $ du -s dir # summarize | ||
+ | </ | ||
+ | < | ||
+ | $ df -h # human readable output | ||
+ | |||
+ | $ df -t nfs # only list filesystems of a type | ||
+ | </ | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Recap ==== | ||
+ | |||
+ | < | ||
+ | $ mv space.log space.log.bak | ||
+ | </ | ||
+ | < | ||
+ | $ df -h | grep " | ||
+ | </ | ||
+ | < | ||
+ | $ cat space.log | ||
+ | </ | ||
+ | < | ||
+ | nfs05.ib.cluster:/ | ||
+ | nfs04.ib.cluster:/ | ||
+ | </ | ||
+ | > we do this often, let’s wrap it up! | ||
+ | |||
+ | |||
+ | ==== Recap++ ==== | ||
+ | |||
+ | < | ||
+ | $ mv space.log space.log.bak | ||
+ | </ | ||
+ | < | ||
+ | $ df -h | grep " | ||
+ | </ | ||
+ | < | ||
+ | $ cat space.log | ||
+ | </ | ||
+ | < | ||
+ | nfs05.ib.cluster:/ | ||
+ | nfs04.ib.cluster:/ | ||
+ | </ | ||
+ | > we do this often, let’s wrap it up! | ||
+ | |||
+ | |||
+ | < | ||
+ | $ echo '# | ||
+ | |||
+ | $ echo 'mv space.log space.log.bak' | ||
+ | |||
+ | $ echo 'df -h | grep " | ||
+ | |||
+ | $ echo 'cat space.log' | ||
+ | </ | ||
+ | < | ||
+ | $ chmod +x spacelog.sh | ||
+ | </ | ||
+ | < | ||
+ | $ ./ | ||
+ | </ | ||
+ | |||
+ | ==== Sed and awk ==== | ||
+ | |||
+ | > **sed** (stream editor) and **awk** are powerful tools when working with the command line | ||
+ | |||
+ | < | ||
+ | $ mycommand | sed " | ||
+ | </ | ||
+ | < | ||
+ | $ mycommand | awk ' | ||
+ | </ | ||
+ | |||
+ | > Using sed and awk in action | ||
+ | |||
+ | ^program | ||
+ | |sed | '' | ||
+ | |sed | '' | ||
+ | |awk | '' | ||
+ | |||
+ | Example script: | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | |||
+ | mv space.log space.log.bak | ||
+ | df -h | grep " | ||
+ | cat space.log | ||
+ | |||
+ | | ||
+ | </ | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | |||
+ | mv space.log space.log.bak | ||
+ | df -h | grep " | ||
+ | cat space.log | sed " | ||
+ | | awk ' | ||
+ | | column -t | ||
+ | </ | ||
+ | |||
+ | ====== Scripting ====== | ||
+ | |||
+ | ==== Ownership and Permissions ==== | ||
+ | |||
+ | > Just to ensure, that you are able to run your scripts | ||
+ | |||
+ | === chown === | ||
+ | |||
+ | > Change the owner of files and directories by: | ||
+ | |||
+ | <code bash> | ||
+ | chown -R user:group dirs files | ||
+ | </ | ||
+ | === chmod === | ||
+ | |||
+ | > Change the mode of files and directories by: | ||
+ | |||
+ | <code bash> | ||
+ | chmod -R u=rw, | ||
+ | chmod -R 644 dirs files | ||
+ | </ | ||
+ | ==== Shebang ==== | ||
+ | |||
+ | A little test program, which we mark as executable and hand it over to the corresponding interpreter: | ||
+ | |||
+ | <code bash> | ||
+ | cat << EOF > test.sh | ||
+ | |||
+ | echo " | ||
+ | echo " | ||
+ | EOF | ||
+ | </ | ||
+ | <code bash> | ||
+ | chmod +x test.sh | ||
+ | </ | ||
+ | <code bash> | ||
+ | bash test.sh | ||
+ | </ | ||
+ | |||
+ | > Don’t we have an OS, capable of executing everything it recognises as a executable? | ||
+ | |||
+ | > Yes, we do! | ||
+ | |||
+ | <code bash> | ||
+ | cat << EOF > test.sh | ||
+ | #!/bin/bash | ||
+ | echo " | ||
+ | echo " | ||
+ | EOF | ||
+ | </ | ||
+ | <code bash> | ||
+ | chmod +x test.sh | ||
+ | </ | ||
+ | <code bash> | ||
+ | ./test.sh | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Functions (more like Procedures) ==== | ||
+ | |||
+ | Programming in bash would be cumbersome without functions, so here we go: | ||
+ | |||
+ | <code bash> | ||
+ | printAllNumbers () { | ||
+ | echo "1 2 3" | ||
+ | echo " | ||
+ | } | ||
+ | </ | ||
+ | === Arguments === | ||
+ | |||
+ | > This isn’t good, as were only getting a fixed amount of numbers. let’s try a recursive approach | ||
+ | |||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | |||
+ | printAllNumbersFrom () { | ||
+ | num=$1 | ||
+ | echo " | ||
+ | printAllNumbersFrom " | ||
+ | } | ||
+ | |||
+ | printAllNumbersFrom $2 | ||
+ | </ | ||
+ | |||
+ | ====== Editors ====== | ||
+ | |||
+ | ==== General ==== | ||
+ | |||
+ | |||
+ | * Many different editors | ||
+ | * Unique (dis-)advantages | ||
+ | * Different look and feel | ||
+ | * Editors should provide us with | ||
+ | - Simple text editing | ||
+ | - Copy and paste | ||
+ | - Search and replace | ||
+ | - Saving changes | ||
+ | - Wide availability | ||
+ | |||
+ | === Two editors that satisfy our needs: === | ||
+ | |||
+ | |||
+ | * nano | ||
+ | * vim | ||
+ | |||
+ | === Common starting point === | ||
+ | |||
+ | <code bash> | ||
+ | nano filename | ||
+ | </ | ||
+ | <code bash> | ||
+ | vim filename | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Nano ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Nano explained ==== | ||
+ | |||
+ | > This editor is focused on being easy to use, but still providing every feature a user might need. | ||
+ | |||
+ | === Interface === | ||
+ | |||
+ | > The interface consists of four parts, namely from top to bottom: | ||
+ | |||
+ | |||
+ | * Title bar | ||
+ | * Text area | ||
+ | * Command line | ||
+ | * Key bindings | ||
+ | |||
+ | === Usage === | ||
+ | |||
+ | > Nothing special, key-bindings visible while editing | ||
+ | |||
+ | ^Feature | ||
+ | |Navigation | ||
+ | |Actual editing| | ||
+ | |Cut/Paste line| '' | ||
+ | |… | ||
+ | |||
+ | |||
+ | |||
+ | === Short === | ||
+ | |||
+ | > Use this editor if you are new to the command line.\\ | ||
+ | > It is straight forward, but can be extended on the way. | ||
+ | |||
+ | * Auto-indentation | ||
+ | * Syntax highlighting | ||
+ | * Multi-buffer | ||
+ | |||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Vi(m) ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Vi(m) explained ==== | ||
+ | |||
+ | > This editor is focused on productivity and efficiency, providing everything a user might need. | ||
+ | |||
+ | === Interface === | ||
+ | |||
+ | > The simple interface consists of two parts: | ||
+ | |||
+ | |||
+ | |||
+ | * Text area | ||
+ | * Command line | ||
+ | |||
+ | > Since this editor is very easy to extend, after setting up a few plugins, it will probably look quite different! | ||
+ | |||
+ | |||
+ | === Usage === | ||
+ | |||
+ | > This is a multimode editor, you’ll have to switch modes whenever you change what you want to do. | ||
+ | |||
+ | ^Feature | ||
+ | |Navigation| | ||
+ | |Writing | ||
+ | |Commands | ||
+ | |… | ||
+ | |||
+ | |||
+ | |||
+ | === Short === | ||
+ | |||
+ | > Use this editor if you like a challenge.\\ | ||
+ | > It is fast and very nice — but you’ll sometimes get hurt on the way. | ||
+ | |||
+ | * Auto-indentation, | ||
+ | * File/ | ||
+ | * Use a plugin manager | ||
+ | |||
+ | |||
+ | {{..: | ||
+ | |||
+ | ==== Vi(m) modes and keys ==== | ||
+ | |||
+ | * any mode: | ||
+ | * back to the **default mode**: **'' | ||
+ | * command mode (followed by '' | ||
+ | * **save** current file: **'' | ||
+ | * **quit** the editor | ||
+ | * after saving: **'' | ||
+ | * without confirmation: | ||
+ | * **help**: **'' | ||
+ | * **search and replace**: **'' | ||
+ | * //default mode//: | ||
+ | * enter **input mode**: **'' | ||
+ | * enter **command mode**: **'' | ||
+ | * **mark** | ||
+ | * **character**-wise: | ||
+ | * **line**-wise: | ||
+ | * **delete** | ||
+ | * **character**-wise: | ||
+ | * **line**-wise: | ||
+ | * **marked content**: **'' | ||
+ | * **search**: **'' | ||
+ | |||
+ | |||
+ | ====== QED ====== | ||
+ | |||
+ | ==== Fin ==== | ||
+ | |||
+ | {{..: | ||
+ | |||
+ | |||
+ | * Questions? | ||
+ | * Need help installing Linux? | ||
+ | * Contact: < | ||
+ | |||
+ | < | ||
+ | <!-- | ||
+ | |||
+ | > Public domain: | ||
+ | |||
+ | - [Ubuntu Tango Icons](https:// | ||
+ | |||
+ | > Mixed (CC, public domain, ...) | ||
+ | |||
+ | - [Wikipedia Tango Icons](https:// | ||
+ | |||
+ | |||
+ | # Timers | ||
+ | ## Systemd Units | ||
+ | ## Systemd Timers | ||
+ | ## Putting it together | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ## Background | ||
+ | ### What is GNU/Linux {.incremental} | ||
+ | |||
+ | ![](pictures/ | ||
+ | <div class=" | ||
+ | > - It's a collection of Software, including: | ||
+ | > - **Linux** itself, as the `kernel` | ||
+ | > - basic tools, mostly from the **GNU** project | ||
+ | > - additional, specialised software for most tasks | ||
+ | > - the **OS** that powers the internet, the mobile world and more | ||
+ | > - **opensource** and **free software** effort to retain essential freedoms of the user | ||
+ | </ | ||
+ | |||
+ | ### Reasons for Linux {.incremental} | ||
+ | |||
+ | ![](pictures/ | ||
+ | <div class=" | ||
+ | > - Wide Adoption | ||
+ | > - Stable platform | ||
+ | > - Anyone can try and use Linux | ||
+ | > - Easy adaption to custom environments | ||
+ | </ | ||
+ | |||
+ | ### Basic Usage {.incremental} | ||
+ | |||
+ | ![](https:// | ||
+ | <div class=" | ||
+ | > - using and understanding the shell | ||
+ | > - moving through the directory structure | ||
+ | > - moving files and directories | ||
+ | > - editing files | ||
+ | > - writing and executing scripts | ||
+ | > - environment and variables | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ## CLI Basics | ||
+ | <div class=" | ||
+ | ### Shell | ||
+ | |||
+ | > The shell used on the VSC is called **bash**. It's the most common shell today, preinstalled by most Linux and macOS versions. | ||
+ | |||
+ | > - It's behaviour is controlled by the file **.bashrc** | ||
+ | > - loaded at login | ||
+ | > - can be customized | ||
+ | > - is a shell script | ||
+ | > - Has some usability features | ||
+ | > - most of the time commands can be auto-completed by pressing `TAB` | ||
+ | > - can recall history with `CTRL-R` or `history` | ||
+ | > - Provides a full programming language/ | ||
+ | > - can do native processing of Strings, Integers and Arrays | ||
+ | > - can execute any program | ||
+ | > - is turing-complete, | ||
+ | |||
+ | ### Environment | ||
+ | |||
+ | > The shell and some default tools are configured through **variables**. | ||
+ | |||
+ | > - list variables with `env` | ||
+ | > - modify them with `export X=Y` | ||
+ | > - get the content by prepending it with a dollar sign `$A` | ||
+ | > - useful in scripts | ||
+ | |||
+ | <div class=" | ||
+ | Some variables that could affect you are: | ||
+ | |||
+ | ``` | ||
+ | $EDITOR # the default editor for the CLI | ||
+ | $PAGER | ||
+ | $PATH # program paths, in priority order | ||
+ | ``` | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ## Executing Commands | ||
+ | |||
+ | <div class=" | ||
+ | <div class=" | ||
+ | To execute a program, we call it: | ||
+ | |||
+ | ```{.bash} | ||
+ | nano file.txt | ||
+ | ./a.out -flag=value | ||
+ | gcc -I/ | ||
+ | module load non-existent-module | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | > - Every command that is executed will provide a return-value on exit. | ||
+ | > - ![](https:// | ||
+ | > - ![](https:// | ||
+ | </ | ||
+ | |||
+ | ### Program Arguments {.incremental} | ||
+ | |||
+ | <div class=" | ||
+ | > The default way to apply arguments to a program is to write a space separated list of arguments after the program when calling it. | ||
+ | |||
+ | > Patterns and expansions are defining multiple arguments with little overhead: | ||
+ | </ | ||
+ | <div class=" | ||
+ | > - the most important patterns are: | ||
+ | > - **?** --- matches one character | ||
+ | > - **\*** --- matches any character sequence | ||
+ | > - the most important expansions are: | ||
+ | > - **A{1, | ||
+ | > - **1{a..z}A** | ||
+ | </ | ||
+ | |||
+ | ### Chaining Commands {.incremental} | ||
+ | |||
+ | <div class=" | ||
+ | ``` {.bash .numberLines} | ||
+ | false ; echo " | ||
+ | false && echo " | ||
+ | false || echo " | ||
+ | ``` | ||
+ | |||
+ | ``` {.bash .numberLines} | ||
+ | Should I be Printed? | ||
+ | |||
+ | Should I be Printed? | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | <!-- | ||
+ | |||
+ | - - - | ||
+ | |||
+ | ### Using Patterns and Expansions {.incremental} | ||
+ | |||
+ | <div class=" | ||
+ | > - the most important patterns are: | ||
+ | > - **?** --- matches one character | ||
+ | > - **\*** --- matches any character sequence | ||
+ | > - the most important expansions are: | ||
+ | > - **A{1, | ||
+ | > - **1{a..z}A** | ||
+ | </ | ||
+ | --> | ||
+ | <!-- | ||
+ | ## Loops | ||
+ | |||
+ | > look like this in a shell: | ||
+ | |||
+ | <div class=" | ||
+ | ```{.bash} | ||
+ | for i in * | ||
+ | do | ||
+ | mv $i{,.bak} | ||
+ | done | ||
+ | ``` | ||
+ | |||
+ | ```{.bash} | ||
+ | while true | ||
+ | do | ||
+ | echo " | ||
+ | sleep 3 | ||
+ | done | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | #### Generating parameters in bash {.incremental} | ||
+ | |||
+ | <div class=" | ||
+ | ```{.bash} | ||
+ | i=1 | ||
+ | while [ $i -lt 10 ] | ||
+ | do | ||
+ | j=1 | ||
+ | while [ $j -le $i ] | ||
+ | do | ||
+ | echo "$i $j" # Your command comes here | ||
+ | let j+=1 | ||
+ | done | ||
+ | let i+=1 | ||
+ | done | ||
+ | unset i j | ||
+ | ``` | ||
+ | |||
+ | ```{.bash} | ||
+ | 1 1 | ||
+ | 2 1 | ||
+ | 2 2 | ||
+ | 3 1 | ||
+ | 3 2 | ||
+ | 3 3 | ||
+ | ... | ||
+ | 9 6 | ||
+ | 9 7 | ||
+ | 9 8 | ||
+ | 9 9 | ||
+ | ``` | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ## Getting familiar with the CLI | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | > This is how the prompt looks by default: | ||
+ | |||
+ | ``` {.bash} | ||
+ | [myname@l3_ ~]$ | ||
+ | ``` | ||
+ | |||
+ | ![](src/ | ||
+ | ![](src/ | ||
+ | ![](src/ | ||
+ | </ | ||
+ | |||
+ | <div style=" | ||
+ | |||
+ | #### Prompt {.incremental} | ||
+ | |||
+ | > - it's " | ||
+ | > - tells you: | ||
+ | > - who you are | ||
+ | > - which computer you're on | ||
+ | > - which directory you're in | ||
+ | > - can be configured to show more information | ||
+ | > - setting is in a variable called `PS1` | ||
+ | > - default value of `$PS1`: `[\u@\h \w]\$` | ||
+ | > - can add date, time and the output of custom commands | ||
+ | > - see `man bash` for details about your shell | ||
+ | |||
+ | </ | ||
+ | |||
+ | <div style=" | ||
+ | #### In case of confusion | ||
+ | |||
+ | > there are many ways of getting further: | ||
+ | |||
+ | > - the `man` command | ||
+ | > - opens the manual for a specified topic | ||
+ | > - especially nice to find man-pages: `apropos` | ||
+ | > - the `whatis` command | ||
+ | > - the `info` command | ||
+ | > - is more complex and more like a browser | ||
+ | > - most commands support a `-h`/ | ||
+ | > - colleagues are often helpful | ||
+ | > - the internet is often helpful | ||
+ | </ | ||
+ | |||
+ | <div style=" | ||
+ | ![`apropos help`](src/ | ||
+ | </ | ||
+ | |||
+ | ## Shell - More than a prompt | ||
+ | |||
+ | ### Simple Input/ | ||
+ | |||
+ | <div class=" | ||
+ | Any program running in the shell can by default read from the keyboard and write to the screen. | ||
+ | |||
+ | We try this with the `cat` command, which is short for concatenate. | ||
+ | |||
+ | ```{.bash} | ||
+ | cat | ||
+ | some text # Input | ||
+ | some text # Output | ||
+ | < | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | ### Piping Input/ | ||
+ | |||
+ | <div class=" | ||
+ | Since echoing input back to the user isn't particularly useful, we'll be echoing back filtered output. | ||
+ | |||
+ | We add a pipe, which redirects the output of the command before it to the command following it, and filter for any line containing `VSC`. | ||
+ | |||
+ | ```{.bash} | ||
+ | cat | grep VSC | ||
+ | 1 2 3 # Input, no Output | ||
+ | 1 VSC 3 # Input | ||
+ | 1 VSC 3 # Output | ||
+ | < | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | ### Redirecting Input/ | ||
+ | |||
+ | <div class=" | ||
+ | Now we can write the resulting stream into a file called VSC.txt. | ||
+ | |||
+ | This is done by adding a greater-sign between the end of the command and the filename of the resulting document. | ||
+ | |||
+ | ```{.bash} | ||
+ | cat | grep VSC > VSC.txt | ||
+ | 1 2 3 # Will not be in VSC.txt | ||
+ | 1 VSC 3 # Will be in VSC.txt | ||
+ | < | ||
+ | ``` | ||
+ | <!-- | ||
+ | ```{.bash} | ||
+ | cat VSC.txt | ||
+ | 1 VSC 3 | ||
+ | ``` | ||
+ | --> | ||
+ | <!-- | ||
+ | </ | ||
+ | |||
+ | ## Cool Tools | ||
+ | |||
+ | ### Less is More | ||
+ | |||
+ | <div class=" | ||
+ | Since piping output is awesome we want to have a program, that can handle all the output of the other programs and present it in screen-sized parts. | ||
+ | |||
+ | Hence the program `less`, which is just `more`. | ||
+ | |||
+ | ```{.bash} | ||
+ | find ~ -iname " | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | ### Permissions | ||
+ | |||
+ | <div class=" | ||
+ | If some file can't be accessed/ | ||
+ | |||
+ | For these cases there is the tool `chmod`, which changes the mode of a file. | ||
+ | |||
+ | ```{.bash} | ||
+ | chmod a=w file | ||
+ | chmod u+x file | ||
+ | chmod g-w file | ||
+ | chmod o=r file | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | ### Aliasing commands | ||
+ | |||
+ | <div class=" | ||
+ | you should define an `alias`, whenever there is a command which: | ||
+ | |||
+ | - is run with parameters which don't change between runs | ||
+ | - has some hard to remember name | ||
+ | - needs a non-default safeguard | ||
+ | |||
+ | ```{.bash} | ||
+ | alias f=' | ||
+ | alias rm='rm -i' | ||
+ | alias def-env=' | ||
+ | | ||
+ | | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | ## Filesystem 101 | ||
+ | |||
+ | <div class=" | ||
+ | > 1. Everything starts at the root | ||
+ | > - the root is a directory | ||
+ | > - `/` denotes the root directory | ||
+ | > 2. the filesystem has different kinds of objects | ||
+ | > 1. files | ||
+ | > 2. directories | ||
+ | > - containers for multiple objects | ||
+ | > 3. links to objects, which either | ||
+ | > - add a second name for the same object | ||
+ | > - point to a position in the filesystem | ||
+ | > 3. objects can be referenced by their path | ||
+ | > - absolute: `/ | ||
+ | > - relative: `dir2/ | ||
+ | > 4. special objects in directories: | ||
+ | > - `.` --- is a reference to the directory itself | ||
+ | > - `..` --- is a reference to the parent directory | ||
+ | </ | ||
+ | |||
+ | ##### The Filesystem represented as an ADT {.incremental} | ||
+ | <div class=" | ||
+ | |||
+ | > These are the helper types: | ||
+ | |||
+ | ```{.haskell} | ||
+ | type Name = String | ||
+ | type Children = [FSObject] | ||
+ | type Path = [FSObject] | ||
+ | data LinkType = Soft | Hard | ||
+ | ``` | ||
+ | |||
+ | > This is the code describing the trivial Linux-ish filesystem in a mathematical notation: | ||
+ | |||
+ | ```{.haskell} | ||
+ | data FSObject = File Name | ||
+ | | Dir Name Children | ||
+ | | Link Name Path LinkType | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | - - - | ||
+ | |||
+ | ### Getting and Manipulating our position in the FS | ||
+ | |||
+ | <div class=" | ||
+ | > - `' | ||
+ | > - `' | ||
+ | > - `' | ||
+ | > - `' | ||
+ | </ | ||
+ | |||
+ | <div class=" | ||
+ | > Example for **looking around**: | ||
+ | |||
+ | <div class=" | ||
+ | ``` | ||
+ | $ ls # shows files and directories | ||
+ | |||
+ | $ ls -a # includes hidden ones | ||
+ | |||
+ | $ ls -l # detailed view | ||
+ | ``` | ||
+ | |||
+ | ``` | ||
+ | testdir | ||
+ | |||
+ | . .. testdir | ||
+ | |||
+ | drwxr-xr-x 1 myuser p12345 0 Apr 13 11:55 testdir | ||
+ | -rw-r--r-- 1 myuser p12345 4 Apr 13 11:55 testfile | ||
+ | ``` | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <div class=" | ||
+ | > Example for **moving around**, starting at the home directory: | ||
+ | </ | ||
+ | <div class=" | ||
+ | ``` | ||
+ | $ pwd | ||
+ | |||
+ | $ cd ..; pwd | ||
+ | |||
+ | $ cd /global; pwd | ||
+ | |||
+ | $ cd; pwd | ||
+ | |||
+ | $ cd -; pwd | ||
+ | ``` | ||
+ | |||
+ | ``` | ||
+ | / | ||
+ | |||
+ | / | ||
+ | |||
+ | /global | ||
+ | |||
+ | / | ||
+ | |||
+ | /global | ||
+ | ``` | ||
+ | </ | ||
+ | |||
+ | - - - | ||
+ | |||
+ | ### Moving files and directories | ||
+ | |||
+ | <div class=" | ||
+ | > - `' | ||
+ | > - `' | ||
+ | </ | ||
+ | <div class=" | ||
+ | > Example: | ||
+ | |||
+ | <div class=" | ||
+ | ``` | ||
+ | $ cp file.orig file.copy | ||
+ | $ mv file.orig file.copy | ||
+ | |||
+ | $ cp file.orig dir | ||
+ | $ mv file.orig dir | ||
+ | |||
+ | $ cp dir1 dir2 # ERROR | ||
+ | $ cp -r dir1 dir2 # WORKS | ||
+ | $ mv dir1 dir2 # WORKS | ||
+ | ``` | ||
+ | |||
+ | > - copying or moving directories can result in unexpected behaviour: | ||
+ | > - if dir2 is an existing directory, dir1 will become a subdirectory of dir2 | ||
+ | > - if dir2 is non-existent, | ||
+ | |||
+ | </ | ||
+ | |||
+ | <div class=" | ||
+ | ##### Transfer to/from Cluster | ||
+ | |||
+ | > - `' | ||
+ | > - arguments can be either local or remote files and direcotries | ||
+ | > - `' | ||
+ | > - similar to regular `mv`/ | ||
+ | > - pedantic about trailing slashes | ||
+ | > - can merge directories | ||
+ | > - can delete/ | ||
+ | </ | ||
+ | |||
+ | `rsync` seems easy to use, but the advanced options could remove data from both sides of your transfer! It's a **syncronazation** utility, no simple move/copy tool | ||
+ | </ | ||
+ | |||
+ | <!-- | ||
+ | - - - | ||
+ | |||
+ | ##### SCP | ||
+ | |||
+ | ``` | ||
+ | $ cp file.orig file.new | ||
+ | |||
+ | $ scp user@host: | ||
+ | |||
+ | $ scp file.orig user@host: | ||
+ | ``` | ||
+ | |||
+ | - this is easy to use and preferable for little, one time transfers | ||
+ | |||
+ | |||
+ | [ID1]: src/tux.svg "Hover Text 1" {height=150px style=" | ||
+ | [ID2]: src/tux.svg "Hover Text 2" | ||
+ | |||
+ | - ![Test][ID1] | ||
+ | - ![Test](src/ | ||
+ | - [<font color=# | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | - - - | ||
+ | |||
+ | ##### RSYNC | ||
+ | |||
+ | ``` | ||
+ | $ rsync dir1 dir2 # Local copy | ||
+ | $ rsync -e ssh dir1 dir2 # Remote copy | ||
+ | |||
+ | # These two have the same result: | ||
+ | $ rsync dir1 dir2 | ||
+ | $ rsync dir1/ dir2/dir1 | ||
+ | |||
+ | # This doesn' | ||
+ | $ rsync dir1/ dir2 | ||
+ | ``` | ||
+ | |||
+ | - there are many useful options, like: | ||
+ | - `-a` $\rightarrow$ Archive mode, usually you want this | ||
+ | - `-v` $\rightarrow$ Verbose mode | ||
+ | - `-p` $\rightarrow$ Preserve permissions | ||
+ | - `...` $\rightarrow$ RTFM or don't use those options | ||
+ | - the `-e ssh` option tells rsync to connect via ssh to the remote machine | ||
+ | - in this case the remote location is written like this: | ||
+ | - user@host: | ||
+ | - trailing slashes have an effect on where your files will go | ||
+ | |||
+ | --> | ||
+ | <!-- | ||
+ | ## Copyleft | ||
+ | |||
+ | Third party content and its licensing information can be found at: | ||
+ | |||
+ | - [Levitating Gnu](https:// | ||
+ | - María del Pilar Saenz: [GFDL](https:// | ||
+ | - [Tux](https:// | ||
+ | - [CC0 Public Domain](https:// | ||
+ | - [Tux and Gnu](https:// | ||
+ | - Aurelio A. Heckert: [Free Art License](http:// | ||
+ | - Larry Ewing, Simon Budig and Anja Gerwinski: probably [CC-BY](https:// | ||
+ | - [Tango Icons](https:// | ||
+ | - Public Domain | ||
+ | |||
+ | ## Copyright | ||
+ | |||
+ | The not explicitly licensed or non freely-redistributable licensed stuff: | ||
+ | |||
+ | - [the Good, the Bad & the Ugly](http:// | ||
+ | - [Dunno]() | ||
+ | |||
+ | ## TestStuff | ||
+ | 😁 $\rightarrow$ 😄 | ||
+ | 😁 $\Rightarrow$ 😄 | ||
+ | 😁 $\longrightarrow$ 😄 | ||
+ | 😁 $\Longrightarrow$ 😄 | ||
+ | |||
+ | https:// | ||
+ | |||
+ | [//]:#(Das ist ein Kommentar, dass nirgends aufscheint) | ||
+ | |||
+ | [TuxAndGnu]: | ||
+ | [VSC]: https:// | ||
+ | |||
+ | ## ToDo | ||
+ | |||
+ | - nano/vi | ||
+ | - df -h . | ||
+ | - du -sh ./* | ||
+ | - cat | sort | uniq | tr | awk | sed | ||
+ | - example | ||
+ | |||
+ | ## table | ||
+ | |||
+ | head1 | head2 | head3 | ||
+ | : | ||
+ | p1 | e11 | e12 | ||
+ | p1 | e11 | e12e12 | ||
+ | p1 | e12e12e12e12e12 | e12 | ||
+ | |||
+ | head1 | head2 | head3 | ||
+ | : | ||
+ | p1 | e11 | e12 | ||
+ | p1 | e11 | e12e12 | ||
+ | p1 | e12e12e12e12e12 | e12 | ||
+ | |||
+ | |||
+ | |||
+ | --> | ||
+ | </ | ||