Linux workshop

Úvod

Linux je soubor operačních systémů založených na open-source jádře, které v roce 1991 vytvořil Linus Torvalds

Nejrozšířenějšími Linuxovými distribucemi jsou:

V různých distribucích se často liší:

Instalátory distribucí pomáhají s

Na serverových systémech se často používají distribuce bez desktopového prostředí, protože desktopové prostředí zabírá zbytečně mnoho výpočetních zdrojů a snižuje bezpečnostní úroveň systému

Příprava playgroundu

Na Coderových instaních dostáváte přístup do Ubuntu serveru, který je předinstalován a přednastaven pomocí nástroje cloud-init

Nemusíte se tedy starat o instalaci operačního systému, ale můžete se okamžitě pustit do práce

Nastartuje si nový ubuntu workspace přes Coder

Do domovského adresáře si nakopírujeme několik souborů, se kterými budeme pracovat

cp /etc/hosts .
cp /etc/hostname .
sudo cp /var/log/dmesg .

Představení základních příkazů

ls

manuálová stránka

ls je základní příkaz pro výpis obsahu adresáře

Vyzkoušejte si vypsat obsah aktuálního adresáře

ls

Pokud jste se pouze přihlásili do systému, měli byste vidět několik souborů a adresářů ve vašem domovském adresáři

Všechny úkoly v tomto worshopu vypracujte pouze za pomocí manuálových stránek

Jak zobrazit skryté soubory?

Řešení
ls -a

Jak zobrazit obsah adresáře s podrobnými informacemi?

Řešení
ls -l

Jak zobrazit obsah adresáře s podrobnými informacemi a skrytými soubory?

Řešení
ls -la

Jak zobrazit obsah adresáře s podrobnými informacemi a skrytými soubory, seřazený podle data vytvoření?

Řešení
ls -lat

Jak zobrazit obsah adresáře s podrobnými informacemi a skrytými soubory, seřazený podle velikosti souborů sesestupně (největší soubory nahoře)?

Řešení
ls -lS

Jak zobrazit obsah adresáře s podrobnými informacemi a skrytými soubory, seřazený podle velikosti souborů vzestupně (nejmenší soubory nahoře)?

Řešení
ls -lSr

Jak zobazit velikost souborů v MB, případně v GB - v lidsky čitelné formě?

Řešení
ls -lh

Jak zobrazit místo uživatele a skupiny, UID a GID vlastníka souboru?

Řešení
ls -ln

cd

manuálová stránka

cd je základní příkaz pro změnu aktuálního adresáře (change directory)

V shellech existují některé speciální adresáře:

Vyzkoušejte si změnit aktuální adresář na /etc

cd /etc

A vylistujte obsah tohoto adresáře

ls

Jak se dostanete zpět do domovského adresáře?

Řešení
cd

nebo

cd ~

Předpokládejme, že si nepamatujete cestu do adersáře, kde jste před chvílí byli, jak se tam dostanete?

Řešení
cd -

Jak se dostanete do adresáře .ssh v domovském adresáři?

Řešení
cd ~/.ssh

Jak se dostanete do nadřazeného adresáře?

Řešení
cd ..

Předpokládejme, že jste v domovském adresáři

V jakém adresáři se budete nacházet po spuštění následujícího příkazu?

cd .ssh/../.config/../
Řešení

Stále v domovském adresáři

pwd

manuálová stránka

pwd je základní příkaz pro vypsání aktuálního adresáře (print working directory)

Jděte do domovského adresáře a vypište aktuální adresář

cd
pwd

Jaký je výstup příkazu pwd?

Řešení
/home/<username>

mkdir

manuálová stránka

mkdir je základní příkaz pro vytvoření adresáře (make directory)

Vytvořte si adresář workshop v domovském adresáři

cd
mkdir workshop

Jak zjistíte, že adresář byl vytvořen?

Řešení
ls

Jak vytvoříte adresář ~/workshop/my/very/nested/directory?

Řešení
mkdir -p ~/workshop/my/very/nested/directory

rmdir

manuálová stránka

rmdir je bezpečnější verze příkazu rm, který slouží k odstranění prázdného adresáře (remove directory)

Pokud adresář není prázdný, rmdir skončí chybou, proto je považován za bezpečnější než klasický rm příkaz

Odstraňte adresář ~/workshop/my/very/nested/directory

rmdir ~/workshop/my/very/nested/directory

Jak zjistíte, že adresář byl odstraněn?

Řešení
ls ~/workshop/my/very/nested/directory

Výsledek by měl vypada takto

ls: cannot access '/home/<username>/workshop/my/very/nested/directory': No such file or directory

rm

manuálová stránka

rm je základní příkaz pro odstranění souboru nebo adresáře (remove)

Než ale začneme odstraňovat, musíme si něco vytvořit

mkdir -p ~/workshop/my/very/nested/directory
touch ~/workshop/my/very/nested/directory/file.txt
touch ~/workshop/my/very/file{1..5}.txt
sudo touch ~/workshop/my/very/file6.txt

Prázdné soubory lze vytvořit pomocí příkazu touch

Pomocí {1..5} jsme vytvořili soubory file1.txt, file2.txt, file3.txt, file4.txt, file5.txt

Více o shellových expanzích bude níže

Pokud nyní zkusíme odstranit adresář ~/workshop/my/very/nested/directory pomocí rmdir, skončíme chybou

rmdir ~/workshop/my/very/nested/directory
rmdir: failed to remove '/home/<username>/workshop/my/very/nested/directory': Directory not empty

Pokud použijeme rm na odstranění adresáře, dostanema ale jinou chybu

rm ~/workshop/my/very/nested/directory
rm: cannot remove '/home/<username>/workshop/my/very/nested/directory': Is a directory

rm slouží primárně pouze k odstranění souborů, nikoliv adresářů

Jak odstraníte adresář ~/workshop/my/very/nested/directory, společně s jeho obsahem?

Řešení
rm -r ~/workshop/my/very/nested/directory

Jak odstraníte všechny soubory v ~/workshop/my/very/ a také samotný adresář?

Řešení
rm -r ~/workshop/my/very

Minulý příkaz se nás zeptal na potvrzení, zdali chceme smazait i soubor file6.txt, jelikož je vlastněný uživatelem root

rm: remove write-protected regular empty file '/home/<username>/workshop/my/very/file6.txt'?

Vytvořme soubor znovu

mkdir -p ~/workshop/my/very
sudo touch ~/workshop/my/very/file6.txt

Jak odstraníte všechny soubory v ~/workshop/my/very/ a také samotný adresář, aniž by se vás systém ptal na potvrzení?

Řešení
rm -rf ~/workshop/my/very

cp

manuálová stránka

cp je základní příkaz pro kopírování souborů a adresářů (copy)

Vytvořte si kopii souboru /etc/passwd do domovského adresáře

Řešení
cp /etc/passwd ~

Jak zjistíte, že soubor byl úspěšně zkopírován?

Řešení
ls ~

Případně můžete porovnat velikost souborů nebo provést kontrolní součet

Jak zkopírujete obsah adresáře (i podadresářů) /var/log/ do adresáře ~/logs?

Řešení
cp -r /var/log ~/logs

Na některé soubory a adresáře nebudete mít dostatečná práva, ale pro naše účely to nevadí

mv

manuálová stránka

mv je základní příkaz pro přesunutí souborů a adresářů (move)

Velmi podobný příkazu cp, ale na rozdíl od něj neprovádí kopii, ale pouze přesun a tedy nezanechává původní soubor.

Používá se také na přejmenování souborů a adresářů

Jak přejmenujete soubor ~/logs/dpkg.log na ~/logs/dpkg.log.old?

Řešení
mv ~/logs/dpkg.log ~/logs/dpkg.log.old

Jak přejmenujete adresář ~/logs na ~/log?

Řešení
mv ~/logs ~/log

cat

manuálová stránka

cat je základní příkaz pro výpis obsahu souborů (concatenate)

Vyzkoušejte si vypsat obsah souboru /etc/passwd

cat /etc/passwd

Hlavním účelem cat je přečtění několika souborů a jejich spojení do jednoho výstupu

Jak zobrazíte obsah souborů /etc/passwd a /etc/hostname dohromady?

Řešení
cat /etc/passwd /etc/hostname

Nicméně v praxi se často setkáte z tím, že se cat používá pouze na přečtení obsahu jednoho souboru a následně se s tímto obsahem pracuje pomocí jiných příkazů

less a more

manuálová stránka less

manuálová stránka more

less a more jsou základní příkazy pro postupné a interaktivní čtení obsahu souborů v terminálu

less je modernější a nabízí více funkcí než more, ale oba příkazy jsou velmi podobné

Vyzkoušejte si vypsat obsah souboru /etc/passwd pomocí less

less /etc/passwd

Jak se pohybujete v less?

Řešení

šipkami, nebo pomocí kláves

head a tail

manuálová stránka head

manuálová stránka tail

head a tail jsou základní příkazy pro výpis prvních nebo posledních řádků souboru

Bez speciálních přepínačů vypisují prvních nebo posledních 10 řádků souboru

Vyzkoušejte si vypsat prvních 10 řádků souboru /etc/passwd

head /etc/passwd

Jak zobrazíte posledních 10 řádků souboru /etc/passwd?

Řešení
tail /etc/passwd

Jak zobrazíte posledních 20 řádků souboru /etc/passwd?

Řešení
tail -n 20 /etc/passwd

Jak pomocí head zobrazíte všechny řádky souboru /etc/passwd kromě posledních 5?

Řešení
head -n -5 /etc/passwd

Jak pomocí tail zobrazíte všechny řádky souboru /etc/passwd kromě prvních 5?

Řešení
tail -n +6 /etc/passwd

Tail má i jeden velmi užitečný přepínač -f, který sleduje změny v souboru v reálném čase

Otevřete si 2 okna terminálu ve stejné složce, v jednom spusťte následující příkaz

tail -f my-output.txt

V druhém okně terminálu vytvořte soubor my-output.txt a zapište do něj nějaký text

echo "Hello World" > my-output.txt

Postupně sledujte první okno a u toho zapisujte další řádky

echo "Hello World" >> my-output.txt

Tento příkaz je velmi užitečný pro sledování nových záznamů v logovacích souborech

grep

manuálová stránka

grep je základní příkaz pro vyhledávání řetězců v textu (global regular expression search and print)

Vyzkoušejte si vyhledat řádky v souboru /etc/passwd, které obsahují řetězec root

grep root /etc/passwd

Jak zobrazíte pouze řádky, které obsahují řetězec bash?

Řešení
grep bash /etc/passwd

První argument příkazu grep je regulární výraz, což znamená, že můžete použít speciální znaky pro vyhledávání

Jak zobrazíte pouze řádky, které obsahují řetězec sh na konci řádku?

Tedy nechceme ve výsledku například uživate sshd apod.

Řešení
grep 'sh$' /etc/passwd

Jak zobrazíte pouze řádky, které začínají na písmeno t?

Řešení
grep '^t' /etc/passwd

Příkaz grep je velmi mocný, příkladem je například vyhledání a nálsedný výpis kontextu

Jak zobrazíte řádky, které obsahují řetězec sshd a 2 řádky před a 2 řádky po?

Řešení
grep -B 2 -A 2 sshd /etc/passwd

find

manuálová stránka

find je základní příkaz pro hledání souborů a adresářů v souborovém systému

Vyzkoušejte si najít všechny soubory ve vašem domovském adresáři

find ~

Všimněte si, že find vypisuje i skryté soubory a také v základu vyhledává rekurzivně i v podadresářích

Find také v základu hledá i adresáře

Jak najdete všechny soubory ve vašem domovském adresáři, které začínají na písmeno d?

Řešení
find ~ -type f -name 'd*'

Jak najdete všechny soubory ve vašem domovském adresáři, které končí na .log?

Řešení
find ~ -type f -name '*.log'

Jak najdete všechny adresáře ve vašem domovském adresáři, které obsahují slovo server?

Řešení
find ~ -type d -name '*server*'

Jak najdete všechny soubory ve vašem domovském adresáři, které byly změněny v posledních 7 dnech?

Řešení
find ~ -type f -mtime -7

Jak najdete všechny soubory ve vašem domovském adresáři, které obsahují písmena rc nebo conf?

Řešení
find ~ -type f -name '*rc*' -o -name '*conf*'

wc

manuálová stránka

wc je základní příkaz pro počítání znaků, slov a řádků v textu (word count)

Vyzkoušejte si spočítat počet řádků, slov a znaků v souboru /etc/passwd

wc /etc/passwd

Jak zobrazíte pouze počet řádků v souboru /etc/passwd?

Řešení
wc -l /etc/passwd

Jak zobrazíte pouze počet slov v souboru /etc/passwd?

Řešení
wc -w /etc/passwd

Jak zobrazíte pouze počet znaků v souboru /etc/passwd?

Řešení
wc -c /etc/passwd

cut

manuálová stránka

cut je základní příkaz pro výběr a výřezu částí textu (cut out)

Vyzkoušejte si vypsat první sloupec souboru /etc/passwd

cut -d: -f1 /etc/passwd

-d určuje oddělovač, ve kterém je soubor zapsán, v tomto případě :

-f určuje, který sloupec (po rozdělení oddělovačem) chceme vypsat (první sloupec má index 1)

Jak zobrazíte třetí sloupec souboru /etc/passwd?

Řešení
cut -d: -f3 /etc/passwd

Jak zobrazíte jméno uživatele a jeho domovský adresář ze souboru /etc/passwd?

Řešení
cut -d: -f1,6 /etc/passwd

sed

manuálová stránka

sed je základní příkaz pro editaci textu (stream editor)

Vyzkoušejte si nahradit všechny dvojtečky ve souboru /etc/passwd za mezery

sed 's/:/ /g' /etc/passwd

's/:/ /g' je regulární výraz pro nahrazení všech výskytů : za mezeru

Formát je s/<pattern>/<replacement>/<flags> kde

Jak zamaskujete uživatelské jména ve souboru /etc/passwd za <masked>?

Řešení
sed 's/^[^:]*:/<masked>:/g' /etc/passwd

tar

manuálová stránka

tar je základní příkaz pro archivaci souborů a adresářů (tape archive)

Vytvořte si archiv workshop.tar ze souborů ve vašem domovském adresáři

tar -cf workshop.tar ~

Jak zobrazíte obsah archivu workshop.tar?

Řešení
tar -tf workshop.tar

Jak rozbalíte archiv workshop.tar do adresáře ~/workshop?

Řešení
tar -xf workshop.tar -C ~

Jak vyextrahujete pouze soubor .bash_history z archivu workshop.tar?

Řešení
tar -xf workshop.tar -C / home/<username>/.bash_history

Jak jste si možná všimli, tar balí i celé cesty k souborům, což může být nežádoucí

Komplikuje nám to například rozbalování archivu, jelikož jsme museli specifikovat

  1. root adresář / jako cíl rozbalení
  2. kompletní cestu k souboru .bash_history

Jak vytvoříte archiv workshop2.tar, ve kterém soubory nebudou obsahovat prefix home/<username>?

Řešení
tar -cf workshop2.tar -C ~ .

Zobrazte si obsah archivu workshop2.tar

Řešení
tar -tf workshop2.tar

Nyní můžeme jednoduše extrahovat soubor .bash_history do domovského adresáře

tar -xf workshop2.tar ./.bash_history

Odstranění prefixu je velmi užitečné, pokud chceme archivovat soubory z jednoho adresáře a následně je rozbalit do jiného adresáře

Prefix ./ lze dodatečně odstranit pomocí argumentu --transform='s/^\.\///'

date

manuálová stránka

date je základní příkaz pro zobrazení aktuálního data a času

Vyzkoušejte si zobrazit aktuální datum a čas

date

Jak zobrazíte pouze aktuální datum?

Řešení
date '+%Y-%m-%d'

Jak zobrazíte pouze aktuální čas?

Řešení
date '+%H:%M:%S'

Jak zobrazíte aktuální datum a čas ve formátu YYYY-MM-DD HH:MM:SS?

Řešení
date '+%Y-%m-%d %H:%M:%S'

Jak zobrazíte aktuální datum a čas ve formátu YYYY-MM-DD_HH-MM-SS?

Řešení
date '+%Y-%m-%d_%H-%M-%S'

Jak zobrazíte datum, které bylo před 5 dny?

Řešení
date -d '5 days ago' '+%Y-%m-%d'

Jak zobrazíte datum, které bude za 5 dnů?

Řešení
date -d '5 days' '+%Y-%m-%d'

Příkazy a expanze

Expanze

manuálová stránka

Shellové expanze je jeden z kroků při zpracovávní shellových příkazů a zaměřuje se na speciální znaky

Vyzkoušejte si vypsat všechny skryté soubory ve vašem domovském adresáři

ls ~/.*

Shell tyto znaky expanduje před spuštěním samotného příkazu nahradí skutečnými soubory

ls tedy nemusí umět pracovat s těmito znaky, ale shell mu je předá již expandoané

Podívejte se například na to, jak jednoduchý echo příkaz pracuje s expanzí

echo ~/.*

Jak zobrazíte řetězce hello1, hello2, ... , hello849, hello850?

Řešení
echo hello{1..850}

Podobný styl expanze provádí i pro proměnné prostředí

echo $SHELL

Nastavte si do proměnné MY_VAR hodnotu hello

MY_VAR=hello

Jak zobrazíte řetezec MY_VAR is set to hello?

Řešení
echo "MY_VAR is set to $MY_VAR"

Shell neexpanduje proměnné v jednoduchých uvozovkách

echo 'This variable will not be expanded: $MY_VAR'

Skripty

Shellové příkazy mohou být skládány do skriptů, které mohou být spouštěny jako celek

Vytvořte si skript hello.sh, který vypíše řetězec Hello, world!

#!/bin/bash

echo 'Hello, world!'

Skripům je vhodné nastavit práva pro spuštění

chmod +x hello.sh

Následně můžete skript spustit

./hello.sh

Vytvořte si skript greet.sh, který vypíše řetězec Hello, $1!

$1 je první argument, který je předán skriptu

Skript budeme chtít volat s argumentem, například world

./greet.sh world

Jak vytvoříte skript greet.sh?

Řešení
#!/bin/bash

echo "Hello, $1!"
chmod +x greet.sh

for

for je základní příkaz pro iteraci přes seznam prvků

Vytvořte si skript hello.sh, který vypíše řetězec Hello, world! 5x

#!/bin/bash

for i in {1..5}
do
    echo "Hello, world!"
done

Jak vytvoříte skript greet.sh, který vypíše řetězec předaný řetezec X-krát?

Volání bude vypada takto

./greet.sh 10 "Hello, world!"
Řešení
#!/bin/bash

for i in $(seq 1 $1)
do
    echo "$2"
done

if

if je základní příkaz pro podmíněné vykonání příkazů

Vytvořte si skript greet.sh, který vypíše

Volání bude vypadat takto

./greet.sh bar

./greet.sh qux
Řešení
#!/bin/bash

if [ "$1" == "bar" ]
then
    echo "foo"
elif [ "$1" == "qux" ]
then
    echo "baz"
fi

case

case je základní příkaz pro podmíněné vykonání příkazů, který je vhodný pro porovnání s více hodnotami

Jedná se o alternativu k více známému switch příkazu v jiných programovacích jazycích

Vytvořte si skript greet.sh, který vypíše

default vypíše unknown

Řešení
#!/bin/bash

case "$1" in
    bar)
        echo "foo"
        ;;
    qux)
        echo "baz"
        ;;
    *)
        echo "unknown"
        ;;
esac

subshell

Ve skriptech je někdy potřeba spustit příkazy v novém shellu, který je oddělený od rodičovského shellu

Toho lze docílit pomocí subshellu

Vytvořte si skript subshell.sh, který si do proměnné MY_VAR uloží výstup příkazu ls -la a následně tento výstup vypíše

Řešení
#!/bin/bash

MY_VAR=$(ls -la)

echo "$MY_VAR"

Samostatné úkoly na skripty

Úkol 1

Vytvořte skript, který podle prvního argumentu vypíše, zdali uživatel s tímto jménem existuje

V případě, že uživatel existuje, vypíše User exists, jinak vypíše na standardní chybový výstup User does not exist a skončí se stavovým kódem 1

Použijte pouze příkazy, které jsme si doposud probrali

./user_exists.sh root
Řešení
#!/bin/bash

if grep -q "^$1:" /etc/passwd
then
    echo "User exists"
else
    echo "User does not exist" >&2
    exit 1
fi

Modifikujte skript tak, aby vypsal i uživatelské id, domovský adresář a shell ve formátu

Řešení
#!/bin/bash

if grep -q "^$1:" /etc/passwd
then
    UID=$(grep "^$1:" /etc/passwd | cut -d: -f3)
    HOME=$(grep "^$1:" /etc/passwd | cut -d: -f6)
    SHELL=$(grep "^$1:" /etc/passwd | cut -d: -f7)
    
    echo "uid: $UID"
    echo "home: $HOME"
    echo "shell: $SHELL"
else
    echo "User does not exist" >&2
    exit 1
fi

Úkol 2

Vytvořte zálohou skript, který zazálohuje vaši složku ~/.ssh do adresáře ~/backup

Zálhování bude provedeno pomocí tar archivu a bude provádět rotaci záloh

Použijte pouze příkazy, které jsme si doposud probrali

./backup.sh
Řešení
#!/bin/bash

BACKUP_DIR=~/backup
SSH_DIR=~/.ssh

# vytvoření adresáře pro zálohy
mkdir -p $BACKUP_DIR

# vytvoření nové zálohy
tar -cf $BACKUP_DIR/backup-$(date +%s).tar -C $SSH_DIR .

# smazání nejstarších záloh
OLD=$(ls -t $BACKUP_DIR | tail -n +6)
rm -f $BACKUP_DIR/$OLD

Řetězení příkazů

V shellu můžete řetězit příkazy pomocí ;, && a ||

Vyzkoušejte si řetězení příkazů

echo "Hello, world!" ; echo "Goodbye, world!"
echo "Hello, world!" && echo "Goodbye, world!"
echo "Hello, world!" || echo "Goodbye, world!"

Jaký bude výstup následujícího příkazu?

echo "Hello, world!" && false || echo "Goodbye, world!"
Řešení

false vrací stavový kód 1, tedy se spustí i poslední příkaz

Hello, world!
Goodbye, world!

Jaký bude výstup následujícího příkazu?

exit 1 && echo "Hello, world!"

A jaký bude výstup následujícího příkazu?

exit 1 || echo "Hello, world!"

pipelining

Pipelining je základní technika pro přesměrování výstupu jednoho příkazu na vstup druhého

Vyzkoušejte si pipelining

ls ~ | grep 'log'

Jaký bude výstup následujícího příkazu?

ls ~ | grep 'log' | wc -l

Zkuste zkombinovat find a grep tak, aby vypsaly všechny soubory ve vašem domovském adresáři, které obsahují slovo log

Řešení
find ~ | grep 'log'

Modifikujte předchozí příkaz tak, aby místo /home/<username> vypisoval pouze ~

Řešení
find ~ | grep 'log' | sed "s|/home/.*/|~/|"

Přesměrování

Výstup příkazů lze přesměrovat do souborů, pípes a jiných procesů

Vyzkoušejte si přesměrování výstupu

echo "Hello, world!" > hello.txt

Jaký bude obsah souboru hello.txt?

Uložte si výstup příkazu ls -la do souboru ls.txt

ls -la > ls.txt

Velká část programů podporuje čtění vstupu ze standardního vstupu, již jsme viděli například grep

xargs

manuálová stránka

Dalším zajímavým a velmi užitečným programem je xargs, který umožňuje zpracovávat vstupní řádky a spouštět s nimi příkazy

Vyzkoušejte si například modifikaci výstupu příkazu ls pomocí xargs

ls | xargs -I {} echo "File: {}"

Pokud tedy na vstupu dostáváme seznam souborů, můžeme s nimi spouštět různé příkazy a ukladát je například do specální složky

Jak zkopírujete všechny soubory ve vašem domovském adresáři do složky ~/backup, ale se jménem ve formátu <filename>.bak?

Řešení
ls ~ | xargs -I {} cp {} ~/backup/{}.bak

tee

manuálová stránka

tee je základní program, který zapisuje vstup na standardní výstup a zároveň do souboru

Jedná se o tzv. T-příkaz, který zapisuje vstup na dvě místa

Využívá se například při logování

Vyzkoušejte si zápis výstupu příkazu ls do souboru ls.txt a zároveň na standardní výstup

ls -la | tee lsla.txt

Lze nahlédnout, že tee vypisuje výstup na standardní našeho terminálu, ale zároveň zapisal výstup příkazu ls do souboru lsla.txt

Programy mohou zapisovat do tzn. file-descriptorů, které jsou číslovány

Pokud některý program zapisuje to stderr, lze tento výstup přesměrovat do stdout pomocí 2>&1

Ale zajímavější je často odfiltrovat klasický stdout výstup a ponechat pouze stderr

<program> >/dev/null

Tímto jsme shellu řekli, že má filedescriptor 1 (defaultní) (stdout) přesměrovat do /dev/null, což je speciální soubor, který všechno co se do něj zapíše, okamžitě zahodí

Stejným postupem můžeme odfiltrovat chybový výstup

<program> 2>/dev/null

Tímto jsme shellu řekli, že má filedescriptor 2 (stderr) přesměrovat do /dev/null, což je speciální soubor, který všechno co se do něj zapíše, okamžitě zahodí

Filtrovat stderr je někdy vhodné, pokud například spouštíme find na celém systémovém disku a jelikož do některých adresářů nemáme přístup, chybový výstup může být velmi dlouhý

sudo, su a uživatelská oprávnění

Základní uživatelská oprávnění v Linuxu jsou založena na třech oprávněních

Linux poté umožňuje nastavovat tyto práva na soubory a adresáře pro tři skupiny uživatelů

Vyzkoušejte si zobrazit uživatelská oprávnění souboru /etc/passwd

ls -la /etc/passwd

Výsupt by měl vypadat nějak takto

-rw-r--r-- 1 root root

První znak určuje typ souboru

Vlastník souboru je root a hlavní skupina u tohoto souboru je stejnojmenná skupina root

Následující tři skupiny po třech znacích určují práva pro vlastníka, skupinu a ostatní uživatele

V tomto případě tedy přečteme, že

Práva lze jednoduš zakódovat pomocí binární soustavy do tří bitů

Exisutje tedy 8 kombinací těchto tří bitů, které lze zakódovat do čísel 0 - 7

Často se setkáte s tím, že se práva učují například jako 775, kde po přepisu do binárního tvaru dostaneme

Vytvořte si soubor permissions.txt

touch permissions.txt

Základní práva jsou nastavena na většine linuxu následovně

-rw-r--r--

základní nastavení práv pro nové soubory řídí umask, který odebírá práva od 666.

Na většině systémů je umask nastaven na 022, což znamená, že se odeberou práva 2 (write) pro skupinu a ostatní uživatele

manuálová stránka

chmod

Na změnu práv k souborům a adresářům slouží příkaz chmod

manuálová stránka

Vyzkoušejte si změnit práva souboru permissions.txt na plná prává, tzn čtení, zápis i spouštění pro všechny uživatele

Řešení
chmod 777 permissions.txt

nebo více čitelná alternativa

chmod u+rwx,g+rwx,o+rwx permissions.txt

Jak změníte práva souboru permissions.txt na čtení a zápis jenom pro vlastníka souboru?

Řešení
chmod 600 permissions.txt

nebo více čitelná alternativa

chmod u+rw,g-rwx,o-rwx permissions.txt

sudo

manuálová stránka

sudo je základní příkaz pro spuštění příkazů s oprávněními jiného uživatele, primárně s oprávněními superuživatele (root)

Pomocí normálního uživatele například nemůžete měnit soubory ve složce /etc, vyzkou3ejte si

touch /etc/cant-create-file
touch: cannot touch '/etc/cant-create-file': Permission denied

Nicméně pokud použijeme prozatím magický příkaz sudo před naším příkazem, vlastně tím systému říkáme

sudo touch /etc/can-create-file

Pokud se podíváme na práva k souboru, zjistíme, že soubor doopravdy existuje a vlastní ho root

ls -la /etc/can-create-file
-rw-r--r-- 1 root root 0 Mar 13 11:38 /etc/can-create-file

To, že nás uživatel může používat sudo a spouštět takto příkazy jako root je definované v souboru /etc/sudoers

sudo cat /etc/sudoers
...

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

...

Tento řádek konfiguruje sudo příkaz, aby povolil uživatelům ve skupině sudo

Formát je následující

<user/group> <host>=(<runas>) <command>

Pokud chceme přidat uživatele do skupiny sudo, můžeme použít příkaz usermod

sudo usermod -aG sudo <username>

Takto nastavené sudo avšak uživatele nejdříve požádá o heslo, na Coder instancích je přímo pro vašeho uživatele nastavené speciální pravidlo v souboru /etc/sudoers.d/90-cloud-init-users

sudo cat /etc/sudoers.d/90-cloud-init-users
<username> ALL=(ALL) NOPASSWD:ALL

Toto pravidlo říká, že uživatel <username> může používat sudo bez hesla

su

manuálová stránka

su je základní příkaz pro změnu uživatele (switch user)

Umožňuje nám přepnout se dočasně na jiného uživatele, pokud máme dostatečná oprávnění a provádět příkazy jako tento uživatel

Nejdříve si musíme nějakého uživatele vytvořit a nastavit mu heslo

sudo useradd demo
sudo passwd demo

Následně se můžeme přepnout na tohoto uživatele

su demo

Po takto jednoduchém přepnutí se nám zobrazí nový shell, který běží jako uživatel demo, ale zůstáváme stále v původním adresáři

pwd
/home/<username>

Jelikož jsme jiný uživatel, nemáme práva na soubory ve složce /home/<username>

ls -la
ls: cannot open directory '.': Permission denied

Tento uživatel nemá ani práva na používání sudo

sudo ls -la
demo is not in the sudoers file.

Pokud chceme zase přepnout zpět na původního uživatele, můžeme použít příkaz exit

exit

Pomocí visudo nebo pomocí editace souborů v /etc/sudoers.d/ můžeme nastavit, kteří uživatelé mohou používat sudo a jaké mají mít práva

Jak přidáte práva uživateli demo k používání sudo, ale pouze na příka ls?

Řešení
echo "demo ALL=(ALL) NOPASSWD:/bin/ls" | sudo tee /etc/sudoers.d/demo

Zkuste se znovu přepnout na uživatele demo a zkusit spustit příkaz ls pomocí sudo

su demo
sudo ls

Tentokát by se vám již mělo podařit spustit příkaz ls pomocí sudo a vypsat soubory v domovském adresáři jiného uživatele.