Ciele
- Spoznať možnosti presmerovania vstupu a výstupu
- Získanie informácii o súbore
- Spoznať typy súborov a ich možnosti
- Prístupové práva súborov
Postup
Krok 1: Duplikovanie, priradenie deskriptora súboru
Príprava
Stiahnite si archív k cvičeniu .
Obsah archívu.
.
└── 03
├── Makefile
├── o6-4.c
├── prepare-03.sh
├── pr1-1.c
├── pr1-2.c
├── pr1-3.c
├── pr2-2.c
├── pr4-1.c
├── remove-03.sh
├── tests
│ ├── u1-1-test.sh
│ ├── u1-2-test.sh
│ ├── u2-2-test.sh
│ ├── u3-2-test.sh
│ ├── u6-3-test.sh
│ └── u6-4-test.sh
├── u1-1.c
├── u1-2.c
├── u1-2R.c
├── u2-2.c
├── u3-2.c
├── u3-3.c
├── u5-4.c
├── u6-3.c
└── u6-4.c
Pracujte v adresári pomenovanom podľa cvičenia napr. ak pri rozbalení 03.zip
vznikne 03
, pracujte v adresári 03
.
Spustite skript prepare-03.sh
, ktorý vytvorí potrebné súbory k cvičeniu: ./prepare-03.sh
.
Poznámka
Ak súbor, s ktorým pracuje úloha nechtiac zmeníte, môžete ho nanovo vytvoriť podľa pokynov v časti //príprava
uvedenej pri úlohe alebo zmazaním celej štruktúry súborov, s ktorými cvičenie pracuje skriptom remove-02.sh
a následne spustením prepare-02.sh
Poznámka
Ak je úloha testovaná, test je možné spustiť nasledovne:
príklad: otestovanie riešenia úlohy 1.1, váš program má názov v tvare u1-1
./tests/u1-1-test.sh
Príklad - vstup programu - pr1-1
Príklad 1.1
Nasledujúci program, ktorý načítava riadok zo vstupu a vypíše ho s číslom, kým nenarazí na EOF funguje podobne ako:
echo -e "prvý riadok\ndruhý riadok\ntretí riadok" | cat -n
//pr1-1.c
#include <stdio.h>
int main(int argc, char const *argv[])
{
//maximálny počet znakov v riadku
int len = 20;
char line[len];
int number_of_line = 1;
//načíta riadok zo štandardného vstupu
while (fgets(line,len,stdin))
{
//očísluje a vypíše riadok
printf("%d %s",number_of_line, line);
number_of_line++;
}
return 0;
}
//výstup
1 prvý riadok
2 druhý riadok
3 tretí riadok
Vstup je možné zadať ručne alebo ho odniekiaľ presmerovať:
- vstupom je výstup príkazu:
echo -e "prvý riadok\ndruhý riadok\ntretí riadok" | ./pr1-1
- vstupom je súbor:
./pr1-1 < input01.txt
Poznámka
Ak je vstup zadávaný ručne, je možné ho ukončiť s CTRL + D
.
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo -e "prvý riadok\ndruhý riadok\ntretí riadok" > input01.txt
Teória - dup
Aký by bol postup, ak má byť nastavený súbor ako štandardný vstup priamo v programe? Riešením môže byť nasledujúca služba.
Služba jadra dup()
Základný princíp činnosti dup()
je, že zduplikuje deskriptor, ktorý dostane ako argument a duplikát uloží na prvú voľnú pozíciu v tabuľke deskriptorov. Hodnota deskriptora bude preto najnižšie nepoužité číslo.
#include <unistd.h>
int dup (int oldfd);
int dup2 (int oldfd, int newfd);
Parametre | Popis |
---|---|
oldfd | deskriptor otvoreného súboru |
newfd | Pri dup2() je hodnota nového deskriptora vopred určená. Ak sa deskriptor s hodnotou newfd používa pre nejaký súbor, ten bude najprv zatvorený. |
Ukončenie | Návratová hodnota |
---|---|
úspešné | nový deskriptor |
chyba | - 1 |
Príklad - dup - pr1-2 pr1-3
Všimnite si rozdiel.
Príklad 1.2
Zápis do súboru, ktorý je otvorený dvakrát.
//pr1-2.c
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int fd1;
int fd2;
//vytvorenie / otvorenie súboru
fd1 = open("file02.txt" , O_CREAT | O_WRONLY , S_IRUSR | S_IWUSR);
//druhykrat ho netreba vytvorit
fd2 = open("file02.txt" , O_WRONLY);
char text[] = "Tento text je zapisany ako prvy.";
int len = strlen(text);
write(fd1, text, len);
write(fd2,"0123456789",10);
//zatvorenie súboru
close(fd1);
close(fd2);
return 0;
}
//obsah súboru file02.txt po spustení
$ xxd file02.txt
00000000: 3031 3233 3435 3637 3839 206a 6520 7a61 0123456789 je za
00000010: 7069 7361 6e79 2061 6b6f 2070 7276 792e pisany ako prvy.
Príklad 1.3
Zápis do súboru, zduplikovanie deskriptora.
//pr1-3.c
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int fd1;
int fd2;
//vytvorenie / otvorenie súboru
fd1 = open("file03.txt" , O_CREAT | O_WRONLY , S_IRUSR | S_IWUSR);
//zduplikovanie deskriptora
fd2=dup(fd1);
char text[] = "Tento text je zapisany ako prvy.";
int len = strlen(text);
write(fd1, text, len);
write(fd2,"0123456789",10);
//zatvorený prvý deskriptor
close(fd1);
//zatvorený druhý deskriptor
close(fd2);
return 0;
}
//obsah súboru file03.txt po spustení
$ xxd file03.txt
00000000: 5465 6e74 6f20 7465 7874 206a 6520 7a61 Tento text je za
00000010: 7069 7361 6e79 2061 6b6f 2070 7276 792e pisany ako prvy.
00000020: 3031 3233 3435 3637 3839 0123456789
Zduplikovanie deskriptora neznamená, že sa znova otvorí ten istý súbor. Súbor ostane otvorený iba raz. Zostane teda iba jediný ukazovateľ na aktuálnu pozíciu v súbore.
Aktivita - dup - o1-1 o1-2 o1-3
Poznámka
Uvažujte kam sa "stratil" výpis funkcie perror()
?
Aktivita - dup - u1-1
Úloha 1.1
Zduplikujte deskriptor tak, aby hodnota nového deskriptora bola 5. Pracujte so súborom u1-1.c
.
//u1-1.c
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
int fd1;
int fd2;
fd1=open("file05.txt" , O_CREAT | O_WRONLY , S_IRUSR | S_IWUSR);
//zduplikovanie deskriptora
// DOPLNTE
fd2=
printf("fd1 = %d\n", fd1);
printf("fd2 = %d\n", fd2);
write(fd1,"abc",3);
write(fd2, "123", 3);
//zatvorenie prvy deskriptor
close(fd1);
//zatvorenie druhy deskriptor
close(fd2);
return 0;
}
//očakávaný výstup
fd1 = 3
fd2 = 5
//obsah súboru file05.txt po spustení programu
abc123
//otestovanie riešenia
./tests/u1-1-test.sh
Aktivita - dup - u1-2
Úloha 1.2
Upravte program a vyriešte problém predstavený na začiatku. Aký bude postup, ak chcete nastaviť súbor input_output.txt
ako štandardný vstup a výstup priamo v programe? Pracujte so súborom u1-2
. Upraviť potrebujete len funkciu redirect_input_output()
.
//u1-2.c
#include <stdio.h>
void redirect_input_output(){
int fd1=open("input_output.txt" , O_RDWR);
//DOPLNTE
}
int main(int argc, char const *argv[])
{
redirect_input_output();
//maximálny počet znakov v riadku
int len = 20;
char line[len];
int number_of_line = 1;
//načíta riadok zo štandardného vstupu
while (fgets(line,len,stdin))
{
//očísluje a vypíše riadok
printf("%d %s",number_of_line, line);
number_of_line++;
}
return 0;
}
//obsah input_output.txt na začiatku
$ more input_output.txt
jedno
slovo
jeden
riadok
//očakávaný obsah input_output.txt na konci
$ more input_output.txt
jedno
slovo
jeden
riadok
1 jedno
2 slovo
3 jeden
4 riadok
//otestovanie riešenia
./tests/u1-2-test.sh
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo -e "jedno\nslovo\njeden\nriadok" > input_output.txt
Krok 2: Informácie o súbore - všeobecne
Príklad - ls - pr2-1
Doterajšie kroky boli zamerané na manipuláciu s obsahom súboru. Tento krok je venovaný získaniu informácii o súbore a spoznaniu spôsobu, ako vytvoriť program, ktorého výstup bude podobný ako pri ls -l
.
Príklad 2.1
Časť z výstupu ls -l /usr/include/
drwxr-xr-x 2 root root 4096 feb 3 01:44 sound
-rw-r--r-- 1 root root 6690 apr 16 2018 spawn.h
-rw-r--r-- 1 root root 264 apr 16 2018 stab.h
-rw-r--r-- 1 root root 2363 apr 16 2018 stdc-predef.h
-rw-r--r-- 1 root root 8626 apr 16 2018 stdint.h
-rw-r--r-- 1 root root 2799 apr 16 2018 stdio_ext.h
-rw-r--r-- 1 root root 29665 apr 16 2018 stdio.h
-rw-r--r-- 1 root root 35784 apr 16 2018 stdlib.h
-rw-r--r-- 1 root root 17545 apr 16 2018 string.h
Poznámka
Pozrite si niekoľko príkladov použitia príkazu ls
.
Teória - stat
Základné pojmy
Adresár je zvláštny súbor, ktorý obsahuje zoznam s menami súborov a číslami i-uzlov. Jednoznačne tak každému súboru priraďuje i-uzol (cez i-number).
Jednotlivé i-uzly sú v systéme rozlíšené číslom. Číslo i-uzla je jednoznačné iba v rámci jedného zväzku, preto nestačí k jednoznačnej identifikácii súboru (podrobnejšie: Sofia - Adresáre).

Význam i-uzla je, že obsahuje metaúdaje o súbore napr. čas poslednej zmeny, prístupové práva a pod. Získať ich je možné napr. službou jadra stat
alebo jej podobnými.
Služba jadra stat()
Služba jadra stat()
získa informácie o súbore a vloží ich do dátovej štruktúry.
#include <sys/types.h>
#include <sys/stat.h>
int stat (const char *pathname, struct stat *buf);
int fstat (int filedes, struct stat *buf);
int lstat (const char *pathname, struct stat *buf);
Parametre | Popis |
---|---|
pathname | špecifikácia súboru - meno, cesta k súboru |
filedes | deskriptor otvoreného súboru |
buf | ukazovateľ na dátovú štruktúru, ktorú služba vyplní |
Ukončenie | Návratová hodnota |
---|---|
úspešné | 0 |
chyba | - 1 |
Príklad - stat - pr2-2 u2-1
Príklad 2.2 Získanie informácií o súbore.
struct stat {
dev_t st_dev; /* číslo zariadenia */
ino_t st_ino; /* číslo i-uzla*/
mode_t st_mode; /* typs súboru a prístupové práva */
nlink_t st_nlink; /* počet linkov (hard links) */
uid_t st_uid; /* user ID vlastník*/
gid_t st_gid; /* group ID skupina */
dev_t st_rdev; /* device ID (pre špeciálne súbory) */
off_t st_size; /* veľkosť v bajtoch */
blksize_t st_blksize; /* najlepšia veľkosť bloku pre efektívne I/O operácie */
blkcnt_t st_blocks; /* počet alokovaných blokov s veľkosťou 512B */
struct timespec st_atime; /* čas posledného prístupu */
struct timespec st_mtime; /* čas poslednej modifikácie */
struct timespec st_ctime; /* čas polednej zmeny stavu */
}
//pr2-2.c
#include <time.h> //ctime
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char const *argv[])
{
struct stat buf;
stat("file06.txt", &buf);
printf("Access time = %s\n", ctime(&buf.st_atime));
printf("Modification time = %s\n", ctime(&buf.st_mtime));
printf("Change time = %s\n", ctime(&buf.st_ctime));
return 0;
}
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo "informacie o subore" > file06.txt
Úloha 2.1
Všimnite si, ako sa menia hodnoty, ked vyskúšate zmeniť.
- obsah súboru
- otvoriť súbor a nemeniť obsah
- premenovať súbor alebo zmeniť práva.
Môžete to vyskúšať na súbore
file06.txt
.
Aktivita - stat - o2-1 o2-2 o2-3
Aktivita - stat - u2-2
Úloha 2.2
Program má vypísať číslo i-uzla súboru, ktorý bol zadaný z príkazového riadka. Kostra riešenia je v u2-2.c
.
//u2-2.c
#include <sys/stat.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
struct stat buf;
//DOPLNTE
if( /*volanie služby a zistenie, či nastala chyba*/){
perror("stat");
}
else {
//DOPLNTE
int inode = ;
printf("%s inode = %d\n", argv[1], inode);
}
return 0;
}
//spustenie
./u2-2 file06.txt
//otestovanie riešenia
./tests/u2-2-test.sh
Poznámka
Vysvetlenie typov napr. mode_t
, ino_t
si môžete pozrieť na tejto stránke
Krok 3: Adresáre
Aktivita - adresáre - u3-1 o3-1
Koncept adresárov je spôsob ako organizovať súbory (tvoria stromovú štruktúru). V skutočnosti adresár neobsahuje súbory a podadresáre, je iba postupnosťou bajtov, ktorá obsahuje informáciu o pároch i-uzol a názov súboru.
Úloha 3.1
Overte si tvrdenie "adresár je tiež len súbor". Pokúste sa otvoriť adresár u3-1-dir
v rôznych režimoch (O_RDONLY, O_WRONLY, O_RDWR
).
Aj keď je adresár typ súboru, pre jeho otvorenie a prácu s ním sú určené osobitné funkcie.
Aktivita - stat - o3-2
Zatiaľ bol predstavený spôsob, ako je možné vytvoriť program, ktorý vypíše informácie pre jeden súbor. Podobne ako: ls -li /usr/include/stdio.h
.
Teória - opendir, readdir
V prípade ak má byť vytvorený výpis s informáciami o všetkých súboroch adresára, môžu byť užitočné nasledujúce funkcie, ktoré nie sú priamo služby jadra, ale využívajú ich vo svojom tele.
Funkcie opendir() a readdir()
Funkcia opendir()
otvorí adresár a vráti deskriptor adresára.
Funkcia readdir()
vráti ukazovateľ na štruktúru dirent
nasledujúcej položky adresára.
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *pathname);
Parameter | Popis |
---|---|
pathname | názov, cesta k súboru |
Ukončenie | Návratová hodnota |
---|---|
úspešné | adresárový prúd, deskriptor adresára |
chyba | NULL , zmenená hodnota errno |
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
Parameter | Popis |
---|---|
dirp | adresárový prúd, deskriptor adresára získaný pri otvorení adresára funkciou opendir |
Ukončenie | Návratová hodnota |
---|---|
úspešné | ukazovateľ na štruktúru dirent alebo NULL ak dosiahne koniec adresára |
chyba | NULL , zmenená hodnota errno |
Štruktúra dirent obsahuje adresárové záznamy pre jednotlivé súbory.
struct dirent
{
ino_t d_ino; /* číslo i-uzla */
off_t d_off; /* offset na nasledujúci dirent */
unsigned short d_reclen; /* veľkosť záznamu v bajtoch */
unsigned char d_type; /* typ súboru */
char d_name[]; /* názov súboru */
};
Aktivita - opendir, readdir - o3-3
Aktivita - adresáre - u3-2
Úloha 3.2
Program má vykonať nasledujúce kroky:
- nastavýiť adresár
u3-2-dir
ako pracovný, - vypísať názvy položiek v pracovnom adresári,
- vytvoriť v pracovnom adresári nový adresár
dir2
, - opäť vypísať obsah adresára
u3-2-dir
.
Užitočné môžu byť funkcie: mkdir, chdir, rewinddir.
Pracujte so súborom u3-2.c
.
//u3-2.c
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>//mkdir
#include <unistd.h>//chdir
int main(int argc, char const *argv[])
{
//nastavenie pracovného adresára
//DOPLNTE
("u3-2-dir");
//výpis názvov súborov v pracovnom adresári
DIR *pracovny_adresar;
struct dirent *subor;
pracovny_adresar = //DOPLNTE
printf("Výpis položiek adresára.\n");
while(/*DOPLNTE*/){
printf("%s\n", subor->d_name);
}
//vytvorenie adresára dir2
//DOPLNTE
("dir2", 0700);
//výpis názvov súborov v pracovnom adresári
printf("\nVýpis položiek adresára po vytvorení nového adresára.\n");
while(/*DOPLNTE*/){
printf("%s\n", subor->d_name);
}
return 0;
}
//možný výstup
$ ./u3-2R
Výpis položiek adresára.
..
file1.txt
.
Výpis položiek adresára po vytvorení nového adresára.
..
dir2
file1.txt
.
//otestovanie riešenia
./tests/u3-2-test.sh
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
mkdir u3-2-dir
touch u3-2-dir/file1.txt
Teória - telldir, seekdir
Po vypísani položiek adresára je možné sa vrátiť ku konkrétnej položke. Slúži na to dvojica funkcií: telldir určuje aktuálnu pozíciu v adresárovom prúde a seekdir nastavý smerník na adresárovú položku adresárového prúdu.
#include <dirent.h>
long telldir(DIR *dirp);
void seekdir(DIR *dirp, long loc);
Parameter | Popis |
---|---|
dirp | adresárový prúd, deskriptor adresára |
loc | aktuálna pozícia v adresárovom prúde |
Ukončenie | Návratová hodnota |
---|---|
úspešné | aktuálna pozícia v adresárovom prúde |
chyba | -1 |
Aktivita - telldir, seekdir - u3-3
Úloha 3.3
Program má vykonať nasledujúce kroky:
- vypísať informácie o súboroch v adresári
u3-2-dir
, - vrátiť sa ku položke s názvom
hladany.txt
, - vypísať informácie o nasledujúcej položke.
Pracujte so súborom u3-3.c
.
//u3-3.c
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
DIR *adresar;
struct dirent *subor;
long int position;
adresar = opendir("u3-3-dir");
if(adresar != NULL){
printf("Výpis položiek adresára.\n%-20s %-7s pozícia\n", "názov", "i-uzol");
while((subor = readdir(adresar)) != NULL){
printf("%-20s %ld %ld\n", /*DOPLNTE názov*/, /*DOPLNTE i-uzol*/, /*DOPLNTE pozícia*/);
if(strcmp("hladany.txt",subor->d_name)== 0){
position=/*DOPLNTE získanie pozície*/;
}
}
//DOPLNTE vrátenie na položku
//DOPLNTE načítanie položky
printf("\n%-20s %-7s pozícia\n", "názov", "i-uzol");
printf("%-20s %ld %ld\n", /*DOPLNTE názov*/, /*DOPLNTE i-uzol*/, /*DOPLNTE pozícia*/);
}
return 0;
}
//možný výstup
$ ./u3-3R
Výpis položiek adresára.
názov i-uzol pozícia
.. 1123270 3517075659704677360
file1.txt 1356007 4786282983948090838
file2.txt 1356009 5602542653180332055
hladany.txt 1356008 7301517832763653560
. 1356006 9223372036854775807
názov i-uzol pozícia
. 1356006 9223372036854775807
Upozornenie
Ak narazíte na problém s prekladom pri spúšťaní programu, skúste použiť nasledovný postup.
gcc -std=gnu11 -Wall -Werror u3-3.c -o u3-3
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
mkdir u3-3-dir
touch u3-3-dir/file1.txt
touch u3-3-dir/hladany.txt
touch u3-3-dir/file2.txt
Krok 4: Typy súborov - všeobecne
Teória - typy súborov
Ak si všimnete výpis, ls -l
prvý stĺpec tvoria informácie o type súboru a používateľských právach.
-rw-r--r-- 1 root root 29665 apr 16 2018 stdio.h

Používatelia zvyčajne prichádzajú do kontaktu s:
-
obyčajnými súbormid
adresármil
symbolickými linkami (odkazmi na iný súbor)
Poznámka
Viac sa môžete dozvedieť o typoch súborov na tejto stránke
V položke st_mode
sú uložené informácie o type súboru a prístupových právach vo forme bitového súčtu rôznych príznakov (OR, operátor |
).
Príznaky pre typy súborov:
Popis | Príznak |
---|---|
obyčajný súbor | S_IFREG |
adresár | S_IFDIR |
symbolický link | S_IFLNK |
maska pre súbor | S_IFMT |
Upozornenie
Ak by ste chceli overiť typ súboru napr. postupom:
if((statbuf.st_mode & S_IFMT) == S_IFCHR)
narazíte na problém, že S_IFMT
a S_IFCHR
nie sú definované.
Ak vás zaujímajú konkrétne hodnoty, viac sa môžete dozvedieť na tejto stránke
Jednoduchý spôsob ako určiť typ súboru, môže byť použitie makra, ktoré otestuje či je súbor konkrétneho typu. Ak súbor nie je daného typu vráti 0.
Typ súboru | Macro |
---|---|
obyčajný súbor | S_ISREG(m) |
adresár | S_ISDIR(m) |
symbolický link | S_ISLNK(m) |
Podrobnejšie sys/stat.h
Príklad - typy súborov - pr4-1
Príklad 4.1
Program overí, či je súbor obyčajný.
//pr4-1.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
struct stat statbuf;
stat("pr4-1-dir/file07.txt", &statbuf);
if(S_ISREG(statbuf.st_mode)){
printf("Is regular\n");
}
else printf("Other type\n");
stat("pr4-1-dir", &statbuf);
if(S_ISREG(statbuf.st_mode)){
printf("Is regular\n");
}
else printf("Other type\n");
return 0;
}
//výstup
$ ./pr4-1
Is regular
Other type
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
mkdir pr4-1-dir
touch pr4-1-dir/file07.txt
Aktivita - typy súborov - o4-1 o4-2
Krok 5: Linky
Aktivita - linky - o5-1
Vo výstupe je ukázané, že na jeden fyzický súbor (t.j. na rovnaký i-node) môže odkazovať viac adresárových položiek.
Aktivita - Pevný a symbolický odkaz
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
mkdir u5-1-dir
echo "obsah suboru file08.txt" > u5-1-dir/file08.txt
ln u5-1-dir/file08.txt u5-1-dir/file08.txt-hard
ln -s u5-1-dir/file08.txt u5-1-dir/file08.txt-soft
Poznámka
Pracujte v adresári u5-1-dir
.
Úloha 5.1
V termináli zobrazte obsah súborov file08.txt
, file08.txt-sotf
a file08.txt-hard
. Pomôcť vám môže príkaz more.
Úloha 5.2
Premenujte názov súboru file08.txt
na renamed
. Môžete použiť príkaz mv
napr. mv stary_nazov novy_nazov
.
Teória - symbolický a pevný odkaz
Symbolický odkaz (symbolic link, soft link) odkazuje na iný súbor podľa názvu. Je v ňom uložená len informácia, na aký súbor odkazuje. Vo výpise ls -l
je označený inak ako obyčajný súbor.
Úloha 5.3
Zobrazte názov súboru, na ktorý odkazuje symbolický link file08.txt-soft
. Skúste použiť príkaz readlink.
Pevný odkaz (hard link) odkazuje na i-uzol, rovnako ako pôvoddný názov.
11413898 4 -rw-rw-r-- 3 sofia sofia 24 apr 17 01:02 file08.txt-hard
11413900 0 lrwxrwxrwx 1 sofia sofia 10 apr 15 02:55 file08.txt-soft -> file08.txt
11413898 4 -rw-rw-r-- 3 sofia sofia 24 apr 17 01:02 renamed

Teória - link, unlink
Pre prácu s odkazmi je možné použiť nasledujúce služby.
Služby jadra link() a unlink()
Služba jadra link()
vytvorí novú položku adresára newpath
, ktorá odkazuje na existujúcu položku existingpath
.
#include <unistd.h>
int link (const char *existingpath, const char newpath);
int unlink (const char *pathname);
Parametre | Popis |
---|---|
existingpath | existujúca položka adresára |
newpath | nová položka adresára |
pathname | položka adrasára |
Ukončenie | Návaratová hodnota |
---|---|
úspešné | 0 |
chyba | - 1 |
Aktivita - symbolický a pevný odkaz - u5-4
Úloha 5.4
Pokúste sa vytvoriť odkaz file09.txt-link
a u5-4-dir-link
na súbor file09.txt
a adresár u5-4-dir
. Doplnte program v súbore u5-4.c
a všimnite si výstup.
//u5-4.c
#include <unistd.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
//DOPLNTE VYTVORENIE ODKAZU NA SÚBOR
if( == -1)
perror("link file");
//DOPLNTE VYTVORENIE ODKAZU NA ADRESÁR
if( == -1)
perror("link dir");
return 0;
}
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo "obsah suboru file09.txt" > file09.txt
mkdir u5-4-dir
Aktivita - symbolický a pevný odkaz - o5-3 o5-4
Služba jadra unlink ()
odstráni položku adresára. Ak existujú na súbor aj iné odkazy, ostanú cez ne dáta daného súboru prístupné.
Krok 6: Prístupové práva
Teória - práva
Každý súbor má definované prístupové práva. Vo výpise ls -l
sú uvedené po informácii o type súboru. Pre jednotivé typy používateľov špecifikujú, ako môžu so súborom pracovať. Rozlišované sú tri typy používateľov:
- u (user) - vlastník súboru
- g (group) - pracovná skupina
- o (others) - ostatní
Súbory majú definovaného svojho vlastníka a skupinu.
Prístupové práva sú zaznamenané v i-uzle v bitovom tvare. Ak na danej pozícii má bit hodnotu 1
, znamená to, že právo je pridelené.

práva | súbor | adresár |
---|---|---|
r | čítanie | vypísať zoznam súborov |
w | zápis | vytvárať / mazať súbory |
x | spustenie | nastaviť adresár ako pracovný, vôjsť do aresára |
Aktivita - práva - o6-1 u6-1 u6-2
Poznámka
Pracujte v adresári u6-1-dir
.
Všimnite si prístupové práva vytvorených súborov.
drwxrwxr-x 2 sofia sofia 4096 apr 19 20:35 myDir
-rw-rw-r-- 1 sofia sofia 0 apr 19 20:36 myFile.txt
Zvyčajne je hodnota práv pri nových súboroch 664
a pri adresároch 775
.
Táto hodnota vznikne odobraním práv od prednastavenej hodnoty podľa tzv. masky práv.
Úloha 6.2
Zistite aktuálnu hodnotu masky práv. Použiť môžete príkaz umask .
Teória - umask
Prednastavená hodnota práv je pri súboroch 0666
a pri adresároch 0777
.
Maska práv definuje, ktoré práva majú byť odobrané. Zvyčajne je nastavená na 0002
.
Služba jadra umask()
Zmenu masky je možné vykonať už spomenutým príkazom umask
alebo pomocou služby jadra.
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
Parametre | Popis |
---|---|
mask | práva, ktoré majú byť odobrané |
Príklad hodnôt pre nastavenie masky práv:
mask - prístupové práva | osmičková hodnota | popis |
---|---|---|
S_IRUSR | 0400 | čítanie pre majiteľa |
S_IWGRP | 0020 | zápis pre skupinu |
S_IXOTH | 0001 | vykonávanie pre ostatných |
S_IRWXG | 0070 | čítanie, zápis a vykonávanie pre skupinu |
S_IRWXO | 0007 | čítanie, zápis a vykonávanie pre ostatných |
Ukončenie | Návratová hodnota |
---|---|
úspešné | predošlá maska |
Aktivita - umask - o6-2 u6-3
Úloha 6.3
V súbore u6-3.c
je kostra programu, ktorý má zmeniť masku práv tak, aby ponechala práva iba pre vlastníka. Novú hodnotu masky vypíšte v osmičkovom tvare. Po vytvorení súboru file11.txt
nastavte pôvodnú masku.
//u6-3.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
mode_t oldmask;
oldmask = //DOPLNTE;
printf("stará maska: //DOPLNTE \n", oldmask);
creat("file11.txt", 0777);
printf("maska použitá pri vytvorení súboru: /*DOPLNTE*/\n", /*DOPLNTE*/);
printf("nastavená pôvodná maska\n");
return 0;
}
//otestovanie riešenia
./tests/u6-3-test.sh
Príklad - chmod - pr6-1
Prístupové práva môžu byť po vytvorení zmenené. Príkaz chmod alebo rovnomenná služba môžu byť užitočné ak je cieľom napr. rozšíriť prístupové práva pre skupinu používateľov.
Príklad 6.1
Použitie príkazu chmod
.
Všimnite si aktuálne práva súboru file12.txt
.
$ ls -l file12.txt
-rw-rw-r-- 1 sofia sofia 33 apr 23 15:17 file12.txt
Príkazom chmod
je možné určiť, aká bude nová hodntoa prístupových práv.
$ chmod 777 file12.txt
$ ls -l file12.txt
-rwxrwxrwx 1 sofia sofia 33 apr 23 15:17 file12.txt
Možné je aj určiť, len ako májú byť zmenené využitím označení používateľov v tvare u, g, o
.
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo "subor, ktoreho prava budu zmenene" > file12.txt
Aktivita - chmod - o6-3
Teória - chmod
Služba jadra chmod()
Služba jadra chmod()
zmení prístupové práva súboru.
#include <sys/types.h>
#include <sys/stat.h>
int chmod (const char *pathname, mode_t mode);
Parametere | Popis |
---|---|
pathname | názov alebo cesta k súboru |
mode | prístupové práva - číselné hodnoty (777) alebo pomocou príznakov |
Ukočenie | Návratová hodnota |
---|---|
úspešné | 0 |
chyba | - 1 |
Aktivita - chmod - o6-4
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo "na zaciatku prava 664" > file14.txt
Aktivita - chmod - u6-4
Úloha 6.4
Vytvorte jednoduchý program, ktorého argument bude názov súboru. Ak je zadaný súbor adresár, zabezpečte nech doň môže vstupovať len vlastník. V prípade, že je to obyčajný súbor, zabezpečte, aby len vlastník mohol meniť jeho obsah. Ostatné práva nech sú zachované. Jeho fungovanie môžete testovať na dir05
a file13.txt
.
Pracujte so súborom u6-4.c
.
//u6-4R.c
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
struct stat buf;
stat(/*DOPLNTE - získanie informácii o súbore*/);
mode_t current_mode = buf.st_mode;
if(/*DOPLNTE - zitit ci je adresár*/){
mode_t new_mode = current_mode & ~(/*DOPLNTE*/);
new_mode = new_mode | /*DOPLNTE*/;
chmod(/*DOPLNTE*/);
}
if(/*DOPLNTE - zistit ci je obycajny subor*/){
/*DOPLNTE - zmena práv*/
}
return 0;
}
Príklad fungovania programu:
//pred spustením
drw-rwxrw- 2 sofia sofia 4096 apr 23 19:30 dir05
-r-xrwxrwx 1 sofia sofia 22 apr 23 19:30 file13.txt
$ ./u6-4R file13.txt
$ ./u6-4R dir05
drwxrw-rw- 2 sofia sofia 4096 apr 23 19:30 dir05
-rwxr-xr-x 1 sofia sofia 22 apr 23 19:30 file13.txt
//otestovanie riešenia
./tests/u6-4-test.sh
Upozornenie
Ak ste nechtiac upravili súbory, potrebnú štruktúru môžete vytvoriť nasledujúcim postupom.
//príprava
echo "na zaciatku prava 577" > file13.txt;
chmod 577 file13.txt;
mkdir dir05;
chmod 676 dir05
Poznámka
Príklady bitových operácií:
//pridanie práv na čítanie pre skupinu
current_mode | S_IRGRP
//odobranie práv na čítanie pre skupinu
current_mode & ~S_IRGRP
//odobranie práv na čítanie a vykonávanie pre skupinu
current_mode & ~(S_IRGRP | S_IXGRP)
Krok 7: Špeciálne bity
Teória
sticky bit
Ak je súbor v adresári, ku ktorému má viacero používateľov právo na zápis (napr. sú členmi pracovnej skupiny), môže sa stať, že súbor jedného používateľa bude zmazaný niektorým iným používateľom.
Ak je potrebné to obmedziť, vlastník adresára môže adresáru nastaviť sticky bit, čím zabezpečí, že iba root a vlastník súboru môžu zmazať súbor v adresári.
Môžné je to vidieť pri adresári /tmp
drwxrwxrwt 15 root root 4096 máj 2 07:52 tmp
Príklad:
Nastavenie sticky bit
//stav na začiatku
drwxrwxrwx 2 sofia sofia 4096 máj 2 08:38 pr6-2-dir
$ ls -l pr6-2-dir/
celkom 0
-rw-rw-r-- 1 sofia sofia 0 máj 2 08:38 file16.txt
//nastavenie možné viacerými spôsobmi
$ chmod +t pr6-2-dir
$ chmod 1777 pr6-2-dir
//stav na konci
drwxrwxrwt 2 sofia sofia 4096 máj 2 08:38 pr6-2-dir
$ ls -l pr6-2-dir/
celkom 0
-rw-rw-r-- 1 sofia sofia 0 máj 2 08:38 file16.txt
Pri obyčajných súboroch môže nastavenie sticky bitu ovplyvniť rýchlosť práce so súborom. Viac informácii na stránke alebo v man.
Teória
setuid a setgid bit
Keď používateľ spustí program, program má rovnaké práva ako používateľ. Môže upravovať iba súbory, ku ktorým má daný používateľ právo na zápis. Môže nastať situácia, keď je potrebné dočasne rozšíriť prístupové práva.
Napríklad príkaz passwd
, ktorý potrebuje upravovať súbor s heslami, ku ktorému nemajú prístup všetci používatelia. Viac informácii na stránke alebo v man.
-rwsr-xr-x 1 root root 59640 mar 22 20:05 /usr/bin/passwd
Príklad 7.2:
Nastavenie setuid
//stav na začiatku
-rwxr-xr-x 1 root root 0 máj 2 10:14 program
//nastavenie možné viacerými spôsobmi
chmod u+s program
chmod 4755 program
//stav na konci
-rwsr-xr-x 1 root root 0 máj 2 10:14 program
Pri spustení iným používateľom ako root program bude mať práva ako root.
Na podobnom princípe funguje aj setgid. Pri spustení programu iným používateľom program bude mať práva, ako má jeho skupina. Viac informácii na stránke alebo v man.
Príklad 7.3: Nastavenie setgid
//stav na začiatku
-rwxr-xr-x 1 root root 0 máj 2 10:19 program2
//nastavenie možné viacerými spôsobmi
chmod g+s program2
chmod 2755 program2
//stav na konci
-rwxr-sr-x 1 root root 0 máj 2 10:19 program2