├── exer01.tar ├── exer02.tar ├── exer03.tar ├── exer04.tar ├── exer05.tar ├── exer06.tar ├── exer07.tar ├── exer08.txt ├── exer09.txt ├── exer10.txt ├── exer12.txt ├── exer13-K3-preparation-tasks.txt ├── exer13.txt ├── homework01-02.txt ├── homework01.txt └── homework02.txt /exer01.tar: -------------------------------------------------------------------------------- 1 | exer01/0000775000175000017500000000000012666072056010652 5ustar jrdnjrdnexer01/exersice01.txt0000664000175000017500000001604012666071700013357 0ustar jrdnjrdnРазписани упражнения по Операционни системи за специалност Софтуерно Инженерство от Йордан Бабуков. 2 | 3 | Операционни системи, материал от упражнениe 1 4 | 5 | ВАЖНО: 6 | Контролните са с тежест на писмен изпит. Писмен изпит в редовната сесия няма! 7 | 8 | Дати за контролните: 9 | Към момента не са фиксирани, но ще са 3 броя 10 | 11 | Увод в курса 12 | Практическата част от курса по операционни системи е разделенa на 2 части. През първата част се изучават основни Linux команди, изпълнявани под bash (bourne again shell) работа с текстов редактор vi и създаване на скриптове. През втората част на курса се изучават системни примитиви за работа с файлове и процеси под C. 13 | 14 | Какво е Linux? 15 | Linux е безплатна стабилна операционна система с отворен код, нещо като Windows, но по-добро. 16 | Безплатна означава, че може да изтеглим софтуерният продукт и да го инстлираме без никакви финансови задължения. 17 | С отворен код означава, че имаме свободата (ако разбираме достатъчно) да я променим спрямо своите нужди и желания. 18 | 19 | Къде се среща Linux? 20 | 97% от суперкомпютрите са с Linux базирана операционна система. 21 | NASA 22 | CERN 23 | Смарт телефоните 24 | Сървъри 25 | Работни станции (персонални компютри) 26 | Колите от ново поколение 27 | Телевизори 28 | Хладилници 29 | 30 | Кога и как е стартирал Linux? 31 | През 1991 година, като проект на студента Линус Торвалдс. 32 | През 2015 година Linux се състои от повече от 18 милиона реда код. 33 | Интересни? факти: 34 | Версия 2.6.34-rc5-2.6.34–2.6.35 на операционната система се казва "Sheep on Meth" 35 | Версия 4.0 се казва "Hurr durr i'ma sheep" 36 | Версия 4.3-rc5 се казва "Blurry Fish Butt" 37 | 38 | Организация на файловата система в Linux базирани операционни системи: 39 | Файловата система при линукс базираните операционни системи е с йерархична дървовидна структура. 40 | Корен на файловата система е "/" 41 | Някои основни директории: 42 | /home/ -> съдържа home директориите на потребителите в системата 43 | /root/ -> home директорията на администраторския акаунт в Linux 44 | /bin/ -> съдържа изпълними файлове (например: ls, cat, grep, sort, ...) 45 | /dev/ -> съдържа драйвъри за системата 46 | /etc/ -> съдържа конфигурационни файлове 47 | /proc/ -> специална директория, съдържа информация за операционната система в реално време. От нея например може да разберете дали процесорната ви архитектура поддържа виртуализация по следния начин: 48 | За Intel изпълняваме следния команден ред: 49 | grep --color vmx /proc/cpuinfo 50 | За AMD архитектури: 51 | grep --color svm /proc/cpuinfo 52 | *Ако след изпълнение на съответния команден ред видите странно изглеждат текст, значи поддържате. Ако не.. не. 53 | 54 | Команди и опции към командите взети до момента: 55 | Всички команди: 56 | pwd, ls -al, echo, date, man, cd 57 | 58 | Влезте на сървъра представен от ФМИ, но поддържан от екипа по операционни системи. 59 | *Когато въвеждате паролата си, няма да бъдат показани звездички, но не се притеснявайте. Идеята е, ако някой ви наблюдава екрана да не разбере колко е дълга паролата ви. Ако се знае дължината на паролата, времето за разбиването ѝ спада драстично. 60 | Пример: пуснал съм екрана си на проектора и си въвеждам паролата. Нямате представа колко е дълга. 61 | 62 | 1) 63 | pwd -> print working directory, показва ни директорията в която се намираме. 64 | Пример: 65 | [root@dancho bios-update]# pwd 66 | /root/bios-update 67 | 68 | 2) 69 | ls -> показва имена на файлове и директории съдържащи се в директорията, в която се намираме. 70 | ls -l -> показва имена на файлове и директории, но с допълнителна информация. 71 | ls -a -> показва и скритите файлове (започват с "." ) 72 | 73 | Пример: 74 | [root@dancho bios-update]# ls -l 75 | -rw-r--r--. 1 root root 1474560 Sep 3 2006 fdboot.img 76 | 77 | 3) 78 | echo -> извежда символи на стадартния изход (монитора) 79 | 80 | Пример: 81 | [root@dancho ~]# echo "Hello! " 82 | Hello! 83 | 84 | 4) 85 | date -> извежда текущото време на система. 86 | 87 | [root@dancho ~]# date 88 | Sat Oct 25 16:24:59 EEST 2014 89 | 90 | Преформатиране на изхода от команда date: 91 | Например: date +%Y%m%d 92 | [root@dancho ~]# date +%Y%m%d (година/месец/ден) 93 | 20141025 94 | 95 | 5) 96 | man -> manual, offline документация за команди под bash 97 | 98 | Пример: 99 | [root@dancho tmp]# man man 100 | *Излизаме от man с клавиша с надпис "q" 101 | 102 | 6) 103 | cd -> променя директорията, в която се намираме 104 | 105 | Примери: 106 | Отивамe в директория dir1, която се намира в моята home директория. 107 | cd /home/jbabukov/dir1 108 | Връщамe се едно ниво по-нагоре в йерархията на файловата система. 109 | cd .. 110 | *двоеточието се асоциира с родителската директория. 111 | *едноточието се асоциира с текущата директория. 112 | Връщане в последната директория, в която сме били, преди смяна 113 | cd - 114 | Връщане в home директорията 115 | cd ~ 116 | cd /home/jbabukov 117 | cd 118 | 119 | 120 | exer01/virtualMachine-how-to.txt0000664000175000017500000000502112666072056015577 0ustar jrdnjrdnРъководство за вдигане на CentOS6 виртуална машина с VirtualBox под Windows, разписано от Йордан Бабуков 121 | 122 | Host OS: Windows -> guess OS: CentOS 123 | How to 124 | 1) create 125 | 2) install 126 | 3) configure 127 | 4) make share folder 128 | 129 | 0) Ако сме 64 битови изтегляме последната версия на CentOS. Версия 7. 130 | http://mirrors.neterra.net/centos/7.2.1511/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso 131 | Ако сме 32 битови изтегляме CentOS6 за 32 битови процесорни архитектури. 132 | http://mirrors.neterra.net/centos/6.7/isos/i386/CentOS-6.7-i386-minimal.iso 133 | 134 | 1) Изтегляме VirtualBox 135 | http://sourceforge.net/projects/virtualbox.mirror/files/VirtualBox%204.3.12/ 136 | 137 | Важно - версия 4.3.12 138 | Инсталираме най-общия вариант. (139MB) 139 | 140 | 2) Инсталираме виртуална машина: 141 | New 142 | Name: CentOS 6.5 143 | Type: Linux 144 | Version: Red Hat 32bit 145 | 512MB RAM (може да я намалим после) 146 | Create virtual hard disk 147 | VDI (virtual disk image) 148 | Да избере dynamically или fixed size - препоръчвам fixed 149 | 4GB HDD е достатъчно 150 | 151 | settings -> storage -> избираме изтеглият oт нас файл с CentOS 152 | 153 | Start 154 | *re-initialiaze 155 | **use free space 156 | 157 | ### 158 | За тази стъпка ще ни трябва и Интернет свързаност. Достатъчно е да си пъхнете кабела в host машината или да я свържете към Wi-Fi мрежа с излаз към Интернет. 159 | ### 160 | 3) yum install -y man gcc 161 | Проверка на заделените ресурси за виртуалната машина: 162 | df -h 163 | top 164 | cat /proc/meminfo 165 | cat /proc/cpuinfo 166 | 167 | yum -y update (чакаме търпеливо пакета за ядрото) 168 | reboot 169 | 170 | ### 171 | Може и без стъпка 4. 172 | ### 173 | 4) 174 | yum -y install yum-plugin-protectbase perl 175 | rpm -Uvh http://mirrors.neterra.net/epel/6/i386/epel-release-6-8.noarch.rpm 176 | yum repolist 177 | yum -y --enablerepo epel install dkms 178 | On virtual machine: devides -> insert Guest Addition 179 | mount /dev/cdrom /mnt 180 | 181 | /mnt/VBoxLinuxAdditions.run (чакаме търпеливо пакетите за ядрото) 182 | Указваме къде да бъде директорията на host machine: 183 | Settings -> shared folder -> auto mount + make permanent 184 | 185 | Автоматично монтиране на споделената директория: 186 | vi /etc/rc.local 187 | mount -t vboxsf sharedfolder /mnt 188 | 189 | Край. 190 | -------------------------------------------------------------------------------- /exer02.tar: -------------------------------------------------------------------------------- 1 | exer02/0000775000175000017500000000000012670323233010642 5ustar jrdnjrdnexer02/exersice02-practice.txt0000664000175000017500000000546612670316344015164 0ustar jrdnjrdnЗадача 1: 2 | Копирайте файловете f1,f2,f3 от директорията /tmp/os2015/exer02/ в директория dir1, намираща се във вашата home директория. Ако нямате такава, създайте я. 3 | 4 | Задача 2: 5 | Нека файлът f2 бъде преместен в директория dir2, намираща се във вашата home директория и бъде преименуван на numbers 6 | 7 | Задача 3: 8 | Уверете се, че съдържанието на файла numbers се състои само от числа 9 | 10 | Задача 4: 11 | Сортирайте файла numbers 12 | Сортирайте го числово, има ли разлика? Обосновете се 13 | 14 | Задача 5: 15 | Направете копие на файла /etc/passwd във вашата home директория под името my_passwd. 16 | Сортирайте файла числово по трето поле, спрямо разделител ":" 17 | 18 | Задача 6: 19 | Сортирайте файла my_file лексикографски по трето поле спрямо разделител " ". Обяснете резултата. 20 | 21 | Задача 7: 22 | Изведете само 1ва и 5та колона на файла my_passwd, спрямо разделител ":" 23 | 24 | Задача 8: 25 | Изведете съдържанието на файла my_passwd от 3-та колона до края, спрямо разделител "а" 26 | 27 | Задача 9: 28 | Изведете съдържанието на файла my_passwd от 2ри до 6ти символ. 29 | *Използвайте команда head или команда tail 30 | 31 | Задача 10: 32 | Намерете факултетния си номер във файл my_passwd. 33 | 34 | Задача 11: 35 | Изведете съдържанието на файла, така че факултетният ви номер да се намира най-отгоре на екрана. 36 | 37 | Задача 10: 38 | Копирайте файла modified_passwd намиращ се в /tmp/os2015/exer02/ във вашата home директория. 39 | Изведете на стандартния изход всички редове съдържащи стринга "Georgi". 40 | 41 | Задача 11: 42 | Изведете на стандартния изход само реда на потребител "Georgi" 43 | 44 | Задача 12: 45 | Преместете всички новосъздадени файлове и директории в директория exer02, намираща се във вашата home директория. Ако нямате такава, създайте я. 46 | В края на упражнението, трябва да имате само една директория exer02 във вашата home директория. 47 | 48 | Край! 49 | exer02/exersice02.txt0000664000175000017500000002340612670323233013361 0ustar jrdnjrdnРазписани упражнения по Операционни системи за специалност Софтуерно Инженерство от Йордан Бабуков. 50 | 51 | Операционни системи, упражнение 02 52 | 53 | Команди до момента: 54 | pwd, ls, echo, date, man 55 | 56 | Вече имате създадени индивидуални акаунти за достъп до сървъра. 57 | *Сървърът може да бъде достъпен само от учебните зали на ФМИ. От вкъщи няма да успеете. 58 | 59 | Да разгледаме процеса на аутентикация пред сървъра: 60 | 1) протоколът, по който я осъществяваме е ssh. Това е протокол, който криптира паролата на потребителя по време на осъществяването на аутентикацията. По този начин, ако някой подслушва (sniff) трафика, няма да ви прихване паролата. За самостоятелна работа разгледайте алгоритъма Diffie Hellman за обмяна на ключове за криптиране. 61 | 2) портът по подразбиране, на който слуша ssh услугата е 22. Добра практика е портът да бъде сменен. 62 | 3) ако сме въвели правилните потребител и парола системата ни допуска до нея. Проверката потребител и парола се осъществява на базата на два файла. /etc/passwd и /etc/shadow. 63 | Aко потребителят, който сме въвели съществува във файл /etc/passwd, то следва проверка на въведената парола, която в общия случай се намира в /etc/shadow, в хеширан вид. 64 | Aко потребителят съществува и паролата съответства на тази на потребителя сме пожънали успех. 65 | *Протокол, който не криптира аутентикацията е telnet. 66 | 67 | Структура на ФС в Linux базирани ОС. 68 | 69 | Нови команди и опции към тях: 70 | who, passwd, write, mesg, cat, more, less, head, tail, touch, rm, mkdir, rmdir, cp, mv, sort, cut, grep 71 | 72 | 0) 73 | who -> показва текущо влезлите потребители в система 74 | 75 | 0.5) 76 | passwd -> смяна на паролата 77 | 78 | 0.6) 79 | write -> можем да си пишем с логнатите потребители. Това е и причината да не правите контролните на компютър.. 80 | write username 81 | txt,txt,txt... 82 | ctrl+c за спиране. 83 | 84 | 0.7) 85 | Когато вече не ви харесва да ви пишат, може да изпълните команда mesg, с опция n. 86 | mesg n 87 | За активиране отново на чата: 88 | mesg y 89 | 90 | 1) 91 | cat -> conCATanate - обединява съдържание на файлове и ги извежда на стандартния изход (терминала) 92 | 93 | Общ вид на командата: 94 | cat f1 f2 f3... fn 95 | 96 | Пример: 97 | Нека имаме файл с име 1 и съдържание "a", файл с име 2 и съдържание "b", файл с име 3 и съдържание "c" 98 | 99 | [root@dancho os2014]$ cat 1 2 3 100 | a 101 | b 102 | c 103 | 104 | 2) 105 | head -> прочита първите n реда от файл. 106 | 107 | Общ вид на командата: 108 | head -n[number] file_name 109 | 110 | Пример: 111 | [root@dancho os2014]$ head -n3 my_file.txt 112 | a 113 | b 114 | c 115 | 116 | 3) 117 | tail -> аналогично на head, но работи за последните n на брой реда. 118 | 119 | Пример: 120 | [root@dancho os2014]$ tail -n3 1 121 | d 122 | e 123 | f 124 | 125 | 4) 126 | touch 127 | 128 | Общ вид на командата: 129 | touch f1 f2.. fn 130 | Създава n на брой празни файла. Ако файлът вече съществува, променя времето му на създаване, достъп и промяна. 131 | 132 | [root@dancho exersSvetlio]$ touch 1 2 3 133 | [root@dancho exersSvetlio]$ ls -l 134 | total 0 135 | -rw-rw-r--. 1 jrdn jrdn 0 Oct 25 17:53 1 136 | -rw-rw-r--. 1 jrdn jrdn 0 Oct 25 17:53 2 137 | -rw-rw-r--. 1 jrdn jrdn 0 Oct 25 17:53 3 138 | 139 | Бонус информация: 140 | Всеки файл има 3 времена, access, modify и change. 141 | Access -> кога последно е достъпван файлът за четене. 142 | Modify -> кога последно е променяно съдържанието на файла. 143 | Change -> кога последно са променяни правата на файла, преименуване, променяно съдържанието на файла. 144 | 145 | Можем да ги видим с команда stat: 146 | [root@dancho ~]# stat anaconda-ks.cfg 147 | File: ‘anaconda-ks.cfg’ 148 | Size: 1443 Blocks: 8 IO Block: 4096 regular file 149 | Device: fd02h/64770d Inode: 269214086 Links: 1 150 | Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root) 151 | Context: system_u:object_r:admin_home_t:s0 152 | Access: 2015-12-17 18:45:22.636133037 +0200 153 | Modify: 2015-12-18 01:13:02.731025144 +0200 154 | Change: 2015-12-18 01:13:02.733025145 +0200 155 | Birth: - 156 | 157 | 5) 158 | rm 159 | 160 | Общ вид на командата: 161 | rm f1 f2 ... fn 162 | Трие n на брой файла. 163 | 164 | [root@dancho exersSvetlio]$ rm 1 2 3 165 | [root@dancho exersSvetlio]$ ls -l 166 | total 0 167 | 168 | 6) 169 | mkdir 170 | 171 | Oбщ вид на командата: 172 | mkdir dir1 dir2... dirn 173 | Създава n на брой директории 174 | 175 | [root@dancho exersSvetlio]$ mkdir dir1 dir2 dir3 176 | [root@dancho exersSvetlio]$ ls -l 177 | total 12 178 | drwxrwxr-x. 2 jrdn jrdn 4096 Oct 25 17:55 dir1 179 | drwxrwxr-x. 2 jrdn jrdn 4096 Oct 25 17:55 dir2 180 | drwxrwxr-x. 2 jrdn jrdn 4096 Oct 25 17:55 dir3 181 | 182 | 7) 183 | rmdir 184 | 185 | Oбщ вид на командата: 186 | rmdir dir1 dir2... dirn 187 | Изтрива n на брой дирекории, само ако директорията е празна! 188 | 189 | Ако директорията не е празна, може да я трием по следния начин: 190 | rm -r dir1 191 | 192 | 8) 193 | cp -> създава копие на файл(ове) 194 | 195 | cp f1 ./dir1/f2 -> създава копие на файлът f1, намиращ се в текущата директория. Копираният файл е с име f2 и се намира в поддиректория dir1 на текущата ни директория. 196 | Oбщ вид на командата: 197 | cp f1 f2 f3.... fn dir1 198 | Създава копия на файловете f1..fn в директория dir1. 199 | 200 | 9) 201 | mv -> преименува, мести, или преименува и мести файл или директория 202 | 203 | Преименуване на файл с име f1 на файл с име f2 204 | mv f1 f2 205 | 206 | Преместване на файл: 207 | mv /home/jbabukov/f1 /home/jbabukov/dir1/ 208 | 209 | Преместване на файл f1, намиращ се в home директорията на потребител jbabukov в поддиректория dir1 и го преименуваме на f2: 210 | mv /home/jbabukov/f1 /home/jbabukov/dir1/f2 211 | 212 | Филтри: 213 | Какво е филтър? Филтри се наричат команди, които обработват данни без да променят първоначалните такива. (оригиналът на данните остава същият) 214 | 215 | 10) 216 | sort 217 | 218 | *За my_file може да ползваме копие на файла /etc/passwd 219 | 220 | sort my_file 221 | sort -n my_file 222 | sort -d my_file 223 | sort -u my_file 224 | sort -n -u my_file 225 | Числово сортиране по трето поле, спрямо разделител ":" 226 | sort -n -t ":" -k3 my_file 227 | Лексикографско сортиране по трето поле, спрямо разделител " " 228 | sort -d -t " " -k3 my_file 229 | 230 | 11) 231 | cut -> филтър на ниво колони 232 | Извеждане само на първа и пета колона от файл my_file, спрямо разделител ":" 233 | cut -f1,5 -d ":" my_file 234 | Извеждане на съдържанието от трета до пета колона на файл my_file, спрямо разделител " " 235 | cut -f3-5 -d " " my_file 236 | Извеждане на съдържанието от четвърто поле до края на реда на файл my_file, спрямо разделител " " 237 | cut -f4- -d " " my_file 238 | Извеждане на съдържанието от второ до пето поле и седмо поле на файл my_file, спрямо разделител ":" 239 | cut -f2-5,7 ":" my_file 240 | *f=field=поле 241 | Извеждане на съдържанието от четвърти символ включително до края на реда на файл my_file, спрямо разделител " " 242 | cut -c4- my_file 243 | *c=character=символ 244 | За работен файл (my_file) може да ползвате копие на /etc/passwd 245 | 246 | 12) 247 | grep -> филтър на ниво редове 248 | 249 | Общ вид на командата: 250 | grep [опции] [шаблон] my_file 251 | 252 | Специални символи: 253 | ^ -> начало на ред 254 | $ -> край на ред 255 | Опции 256 | -v -> въвежда логическо отрицание в изпълнението на командата 257 | --color -> оцветява намерените думи 258 | 259 | Пример: 260 | Изведете всички редове съдържащи низа "Georgi" 261 | grep "Georgi" /etc/passwd 262 | Изведете всички редове, започващи с "Georgi" 263 | grep "^Georgi" /etc/passwd 264 | Изведете всички редове, завършващи с "Georgi" 265 | grep "Georgi$" /etc/passwd 266 | Изведете всички редове, които не започват със низа "Gancho" 267 | grep -v "^Gancho" /etc/passwd 268 | -------------------------------------------------------------------------------- /exer03.tar: -------------------------------------------------------------------------------- 1 | exer03/0000775000175000017500000000000012673454134010653 5ustar jrdnjrdnexer03/exersice03-practice-2.txt0000664000175000017500000001346312673453541015325 0ustar jrdnjrdnЗадачи комплект 1) 2 | 3 | Задача 1: Изведете съдържанието на файла myFile02 сортирано по 4 | потребителско име 5 | Задача 2: Сортирайте файла myFile02 по трето поле. Сега направете числово 6 | сортиране отново по трето поле. Има ли разлика? 7 | Задача 3: Изведете всички редове от файла myFile02, които съдържат низа 8 | "user". Запазете изхода във файл "grepped". Използвайте филтър, за да 9 | преброите редовете от файла "grepped" 10 | Задача 4: Изведете всички редове от файла myFile02, чиито потребителски 11 | имена завършват с цифра. 12 | Задача 5: Изведете само home директориите на всички потребители в 13 | системата, чийто потребителски имена започват с главна латинска буква. 14 | 15 | Текстът по-долу да се запамети във файл myFile02. 16 | 17 | Малко информация какво представляват самите полета по-долу 18 | 1) потребителски акаунт (име) 19 | 2) означава, че паролата не се пази в /etc/passwd, ами в /etc/shadow и то 20 | в криптиран вид 21 | 3) UID (user ID) на съответния потребител 22 | 4) GUID (group user ID) на съответния потребител 23 | 5) коментар към потребителя 24 | 6) home директория на съответния потребител 25 | 7) програма, която ще бъде изпълнена при успешно аутентикиране на 26 | потребителя (т.е. въвел е правилни съответни потребител и парола) 27 | 28 | root:x:0:0:root:/root:/bin/bash 29 | bin:x:1:1:bin:/bin:/sbin/nologin 30 | daemon:x:2:2:daemon:/sbin:/sbin/nologin 31 | adm:x:3:4:adm:/var/adm:/sbin/nologin 32 | lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 33 | sync:x:5:0:sync:/sbin:/bin/sync 34 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 35 | halt:x:7:0:halt:/sbin:/sbin/halt 36 | tcpdump:x:72:72::/:/sbin/nologin 37 | dhcpd:x:177:177:DHCP server:/:/sbin/nologin 38 | radvd:x:75:75:radvd user:/:/sbin/nologin 39 | ntp:x:38:38::/etc/ntp:/sbin/nologin 40 | apache:x:48:48:Apache:/var/www:/sbin/nologin 41 | cat:x:501:501:normal user:/home/cat:/bin/bash 42 | dog:x:502:502:normal user:/home/dog:/bin/bash 43 | woman:x:515:515:no user:/home/woman:/bin/bash 44 | tree:x:570:570:super normal user:/home/tree:/bin/bash 45 | l33t:x:556:556:normal user:/home/l33t:/bin/bash 46 | dancho7:x:588:588::/home/dancho7:/bin/bash 47 | user01:x:557:557:normal user:/home/user01:/bin/bash 48 | 15hello:x:522:522:normal user:/home/15hello:/bin/bash 49 | Nadq03:x:599:599:privilleged user:/home/Nadq03:/bin/bash 50 | Nikoleta88:x:561:561:normal user:/home/Nikoleta88:/bin/bash 51 | inna2013:x:581:581:normal user:/home/inna2013:/bin/bash 52 | 53 | Задачи комплект 2) 54 | 1. Запаметете във файл в своята home директория резултатът от командата 55 | ls -l изпълнена за вашата home директорията. 56 | 57 | 2. Сортирайте файла по второ поле (numeric, alphabetically) 58 | 59 | 3. Извлечете всички редове от файла с информация за файловете/директориите 60 | модифицирани през септември месец, запазете ги във файл и изведете броят им. 61 | 62 | Задачи комплект 3) 63 | Да се напише командa или последователност от команди, която: 64 | 65 | 1)Извежда на стандартния изход само имената на логически включените потребители и броят им. Пример: 66 | s43000 67 | s44000 68 | Броя на потребителите е 2 69 | 2)Чете от стандартния вход 2 низа – име на логически включен потребител и съществуващ файл. Изпраща съобщение на потребителя с текст от файла. 70 | 3)Чете от стандартния вход имената на 3 файла. Обединява редовете на първите два, подрежда ги по азбучен ред и резултата записва в третия файл. Извежда на стандартния изход размерите на трите файла. 71 | 4)Чете от стандартния вход име на съществуващ файл и символен низ. Проверява дали низа се съдържа във файла. 72 | 73 | 74 | 75 | 76 | Примерни решения 77 | Задачи коплект 1: 78 | 1) sort -d -t ":" -k 1 myFile02 79 | 2) sort -t ":" -k 3 myFile02 80 | sort -n -t ":" -k 3 myFile02 81 | Да, има. Без указана опция по подразбиране прави лексикографско сортиране. 82 | 3) grep "user" /etc/passwd > grepped 83 | wc -l grepped 84 | 4) cut -f1 -d ":" /etc/passwd | grep "[0-9]$" 85 | 5) grep "^[A-Z]" /еtc/passwd | cut -f6 -d ":" 86 | 87 | Задачи коплект 2: 88 | 1) ls -l ~/ > my_file 89 | 2) sort -t " " -k 2 my_file 90 | 3) grep "Oct" my_file > my_file_2 91 | wc -l my_file_2 92 | 93 | Задачи комплект 3: 94 | 1) who | wc -l 95 | 2) read string1 string2 (приканваме потребителя да въведе два низа) 96 | jbabukov my_file (подавам вход) 97 | write $string1 < $string2 98 | 3) read string1 string2 string3 (string1,2,3 са имена на променливи, те ще се асоциират съответно с my_file1,2,3) 99 | my_file1 my_file2 my_file3 100 | cat $string1 $string2 | sort -d > $string3 101 | wc -l $string1 $string2 $string3 102 | 4)read string1 string2 103 | grep "$string2" $string1 104 | exer03/exersice03-practice.txt0000664000175000017500000000712712673453541015166 0ustar jrdnjrdnЗадача-1: Създайте файл със съдържанието приложено в края на този файл. 105 | Задача0: Изведете на стандартния изход редовете, в които се среща низа "FOUND" (при проблеми преминете към Задача7) 106 | Задача1: Изведете на стандартния изход брой редове, завършващи на "ОК." (при проблеми преминете към Задача7) 107 | Задача2: Изведете на стандартния изход брой редове, при които проверката извършена от clamd демона е завършила без намиране на нередности. (при проблеми преминете към Задача7) 108 | Задача3: Изведете на стандартния изход редовете, при които проверката от clamd демона е завършила с намиране на червей (Worm). (при проблеми преминете към Задача7) 109 | Задача4: Изведете на стандартния изход редовете, само низа "stratum", който се среща в редове съдържащи низа "ntpd" (при проблеми преминете към задача 7) 110 | Задача5: Изведете на стандартния изход само низа "SelfCheck" (без ":" след SelfCheck), който се среща в редовете съдържащи низа "[4963]" (при проблеми преминете към задача 7) 111 | Задача6: Сортирайте редовете на файла спрямо минута на получаване на лога и ги запазете резултата във файл с име myFile, който да се намира в директория myDir, която се намира във вашата начална (home) директория. (при проблеми преминете към Задача7) 112 | Задача7: Поканете ме да видя какво сте направили. 113 | 114 | 115 | Oct 16 06:30:44 ns clamd[4963]: Worm.Mydoom-27 FOUND NOT OK. 116 | Oct 16 06:37:48 ns clamd[4963]: SelfCheck: Database status OK. 117 | Oct 16 06:49:14 ns clamd[4963]: SelfCheck: Database status OK. 118 | Oct 16 07:00:36 ns clamd[4963]: SelfCheck: Database status OK. 119 | Oct 16 07:11:13 ns clamd[4963]: SelfCheck: Database status OK. 120 | Oct 16 07:21:35 ns clamd[4963]: SelfCheck: Database status OK. 121 | Oct 16 07:24:00 ns clamd[4963]: Worm.NetSky-16 FOUND NOT OK. 122 | Oct 16 07:24:00 ns clamd[4963]: document.zip: Worm.NetSky-16 FOUND 123 | Oct 16 07:33:09 ns clamd[4963]: SelfCheck: Database status OK. 124 | Oct 16 07:48:06 ns clamd[4963]: SelfCheck: Database status OK. 125 | Oct 16 09:01:04 ns ntpd[1813]: synchronized to 93.180.6.3, stratum 2 126 | Oct 16 09:02:18 ns clamd[4963]: Exploit.HTML.IFrame-8 FOUND 127 | Oct 16 09:02:18 ns clamd[4963]: Worm.NetSky-16 FOUND NOT OK. 128 | Oct 16 09:04:12 ns clamd[4963]: SelfCheck: Database status OK. 129 | Oct 16 10:12:04 ns clamd[4963]: SelfCheck: Database status OK. 130 | Oct 16 10:24:48 ns clamd[4963]: SelfCheck: Database status OK. 131 | Oct 16 10:34:59 ns clamd[4963]: SelfCheck: Database status OK. 132 | Oct 16 10:45:02 ns clamd[4963]: SelfCheck: Database status OK. 133 | Oct 16 10:51:02 ns ntpd[1813]: synchronized to 2001:67c:20d0:b0::123, stratum 2 134 | Oct 16 10:55:04 ns clamd[4963]: SelfCheck: Database status OK. 135 | Oct 16 11:05:44 ns clamd[4963]: SelfCheck: Database status OK. 136 | Oct 16 12:51:30 ns clamd[4963]: SelfCheck: Database status OK. 137 | Oct 16 13:01:49 ns clamd[4963]: SelfCheck: Database status OK. 138 | exer03/exersice03.txt0000664000175000017500000002236512673454134013376 0ustar jrdnjrdnРазписани упражнения по Операционни системи за специалност Софтуерно Инженерство от Йордан Бабуков. 139 | 140 | Операционни системи, упражнение 03 141 | 142 | Команди до момента: 143 | упр1) pwd, ls, echo, date, man, cd 144 | упр2) who, passwd, cat, more, less, head, tail, touch, rm, mkdir, rmdir, cp, mv, sort, cut, grep 145 | 146 | Новo: 147 | Команди wc, sleep, read. Код на изход на команда. 148 | Фонов режим на команди. 149 | Работа с променливи. 150 | Wildcards към команда "ls" 151 | Пренасочване на стандартен вход, стандартен изход, изход за грешка. 152 | Регулярни изрази към команда "grep" 153 | Конвейр от команди. 154 | 155 | 0) 156 | wc -> извежда информация за броя редове, броя думи и броя символи във файл. 157 | wc -l /etc/passwd -> извежда броят редове във файл /etc/passwd 158 | wc -w /etc/passwd -> извежда броят думи във файл /etc/passwd 159 | wc -c /etc/passwd -> извежда броят символи във файл /etc/passwd 160 | Може да комбинираме опции по следния начин: 161 | wc -wc /etc/passwd -> извежда броят думи и броят символи във файл /etc/passwd 162 | 163 | 1) 164 | read -> приканва потребителят да въведе низ. 165 | 166 | Общ вид на командата: 167 | read str1 str2... strn 168 | 169 | Пример: 170 | read input1 input2 171 | Hello Nadq! 172 | #низът Hello се асоциира с променливата input1, а Nadq! се асоциира с променливата input2 173 | echo "$input1 $input2" 174 | #със специалния символ "$" можем да достъпим стойност на променлива. "$" форсира изчисляване. По-надолу има примери. 175 | 176 | 2) 177 | sleep 5 -> вкарва ни в 5 секунден интервал на изчакване. 178 | 179 | 3) 180 | Фонов режим на изпълнение - чрез специален символ & 181 | sleep 5 & -> ще стартираме изчакването във фонов режим. Така изчакването остава прозрачно за потребителя. 182 | 183 | 4) 184 | Работа с променливи: 185 | my_var=5 186 | echo $my_var -> ще изведе на стандартния изход стойността на променливата "my_var" 187 | echo my_var -> ще изведе на стандартния изход стринга "my_var" 188 | 189 | read enter_your_name 190 | dancho 191 | echo $enter_your_name 192 | 193 | my_var=$(grep dancho /etc/passwd) -> ще присвой на променливата my_var изхода от команден ред grep "dancho" /etc/passwd 194 | "$" изисква първо да се изчисли изхода от "grep dancho /etc/passwd". 195 | Пример: ако в /etc/passwd има общо трима потребителя с последователност от символи "dancho" в името си, изхода ще е: 196 | echo $my_var 197 | dancho:x:... 198 | danchocho:x:... 199 | dadancho:x:... 200 | 201 | 5) 202 | Wildcards към команда ls 203 | Създаваме десетина файла, с които да работим: 204 | touch a ab bab cba xba axb zz zzb 205 | ls -l a* -> ще изведе информация за всички файлове започващи с буква "a", без значение дали има други символи след буквата. 206 | ls -l *a -> ще изведе информация за всички файлове завършващи с буква "a", без значение дали има други символи преди буквата. 207 | ls -l a -> ще изведе информация само за файлът "a" 208 | ls -l *a* -> ще изведе информация за всички файлове съдържащи буквата "a" 209 | ls -l a[bcd] -> ще изведе информация за файлове "ab, ac, ad" 210 | ls -l a[c-z] -> ще изведе информация за файлове "ac, ad, ae, af,... , az" 211 | ls -l a[A-Z]* -> ще изведе информация за всички файлове започващи с малка буква "а", последвани от една произволна голяма 212 | латинска буква, без значение дали има други симвoли след голямата латинска буква. 213 | 214 | 6) 215 | Всяка команда е асоциирана със стандартен вход, стандартен изход и изход за грешки. Можем да ги манипулираме. 216 | Стандартен изход: ако програмата завърши успешно и има за цел да изведе изход. 217 | Пример 218 | ls 219 | a ab bab cba xba axb zz zzb -> стандартен изход. 220 | ls > my_file_01 -> пренасочваме изхода от команда ls, към файл my_file_01. ">" ако файлът не съществува го създава, ако съществува го занулява. Да се внимава! 221 | ls >> my_file_01 -> пренасочваме изхода от команда ls, към файл my_file_01. ">>" ако файлът не съществува го създава, ако съществува добавя съдържението към края на файла (append) 222 | 223 | Изход за грешки: когато програмата завърши с неуспех. 224 | пример: 225 | cp 226 | cp: missing operand... -> команда cp изисква минимум два аргумента. Съответно извежда съобщение за грешка. 227 | cp 2> my_file_02 -> пренасочваме изхода за грешки към файл my_file_02 228 | cp 2>> my_file_02 -> пренасочваме изхода за грешки към файл my_file_02 229 | Внимание: 230 | cp > my_file_02 -> Какъв ще е резултатът от този команден ред? Защо? 231 | 232 | Стандартен вход: 233 | read whats_your_name 234 | Gerlana 235 | Горният пример приканва потребителя да въведе вход! 236 | Манипулация на стандартния вход: 237 | echo Gerlana > my_file_with_names 238 | read whats_your_name < my_file_with_names 239 | echo $whats_your_name 240 | Gerlana 241 | 242 | 6.5) 243 | Код на завършване на команда 244 | След завършването си на изпълнение (успешно или не) всяка команда връща код на изход. 245 | Кодът на изход можем да видим с изпълнението на следния команден ред: 246 | echo $? 247 | Aко командата е завършила успешно тя връща код на изход 0 и по-голям от 0 в противен случай. 248 | Максималната стойност, която може да върне е 255, тъй като за целта е заделен 1 байт памет. 249 | Пример: 250 | ls 251 | echo $? 252 | 0 253 | 254 | cp 255 | cp: missing file operand 256 | Try 'cp --help' for more information. 257 | echo $? 258 | 1 259 | 260 | 7) 261 | Регулярни изрази към команда grep 262 | Особеност при използване на регулярни изрази към команда grep, е че звездата се асоциира със символa пред нея. 263 | 264 | Нека във файла my_file имаме следните редове: 265 | dan 266 | danc 267 | danch 268 | dancho 269 | dancho123 270 | danchoo 271 | danchooo 272 | danchoooo123 273 | Тогава регулярният израз: 274 | grep "dancho*$" /etc/passwd 275 | ще ни даде следния изход: 276 | 277 | danch 278 | dancho 279 | danchoo 280 | danchooo 281 | 282 | Логиката, по която работи е следната: 283 | изведи всички редове завършващи на низа "danch" последван от символа "о" срещащ се нула или повече на брой последвателни пъти. 284 | 285 | grep "^[a-z]" /etc/passwd -> ще изведе всички редове започващи с малка латинска буква 286 | grep "[0-9]$" /etc/passwd -> ще изведе всички редове завършващи на цифра 287 | 288 | Извличане на редовете, състоящи се само и единственo от цифри: 289 | grep "^[[:digit:]][[:digit:]]*$" my_digit_file.txt 290 | 291 | 8) Конвейр 292 | До момента винаги изпълнявахме по една команда и считахме, че резултатът е достатъчен. Но ако желаем да продължим по ефикасен начин обработката на изхода ни, прилагаме конвейр. 293 | Изхода от една команда го подаваме като вход на друга команда 294 | Пример: 295 | Нека имаме файл /etc/passwd със съдържание: 296 | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 297 | saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin 298 | 299 | Желаем да изведем само трето поле спрямо разделител ":" на редовете съдържащи низа "ftp" и да пренасочим изхода към файл "my_file_03" 300 | grep "ftp" /etc/passwd | cut -f3 -d ":" > my_file_03 301 | -------------------------------------------------------------------------------- /exer04.tar: -------------------------------------------------------------------------------- 1 | FMIcoursesBYME/OperatingSystems/exer04/exersice04-practice.txt0000664000175000017500000000572612640524333023177 0ustar jrdnjrdnЗадача 1: 2 | Нека сме си забравили факултетния номер. 3 | Напишете командна процедура на bash, която да извежда на стандартния изход факултетния ви номер. 4 | 5 | 6 | Задача 2: 7 | Напишете командна процедура на bash, която приканва потребителя да въведе низ - потребителско име на потребител от системата. След което 8 | извежда на стандартния изход, колко пъти потребителят се е логнал. 9 | 10 | 11 | Задача 3: 12 | Напишете командна процедура на bash, която приканва потребителя да въведе пълното име на съществуваща директория. 13 | След което да изведе на стандартния изход подходящо съобщение за броя на всички файлове в нея и броя на всички директории в нея. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Решение задача 1: 34 | [..]$ vi task_01_$(date +"%Y%m%d%l").sh 35 | 36 | #bash script starts 37 | 38 | echo $(whoami | cut -c2-) 39 | 40 | #bash script ends 41 | 42 | :wq 43 | 44 | Малко обяснение: команда whoami връща потребителското име, с което сте се логнали на системата. В случая ще е факултетния номер с 45 | буква "s" пред него. По условие се иска само факултетния номер, затова извеждаме на стандартния изход от втори символ нататък. 46 | 47 | 48 | Решение задача 2: 49 | [..]$ vi task_02_$(date +"%Y%m%d%l%M").sh 50 | 51 | #bash script starts 52 | 53 | echo "Please enter login name: " 54 | read login_name 55 | 56 | number_of_sessions=$(who | grep "$login_name" | wc -l) 57 | echo "User $login_name has $number_of_sessions active sessions. " 58 | 59 | #bash script ends 60 | 61 | :wq 62 | 63 | Решение задача 3: 64 | [..]$ vi task_03_$(date +"%Y%m%d%l%M%s").sh 65 | 66 | #bash script starts 67 | 68 | echo "Please enter an absolute name of existing directory! " 69 | read existing_directory 70 | 71 | number_of_directories=$(ls -l $existing_directory | grep "^d" | wc -l) 72 | number_of_ordinery_files=$(ls -l $existing_directory | grep "^-" | wc -l) 73 | echo "Number of directories in directory $existing_directory is $number_of_directories " 74 | 75 | echo "Number of ordinery files in directory $existing_directory is $number_of_ordinery_files " 76 | 77 | #bash script ends 78 | 79 | :wq 80 | 81 | Обяснение: 82 | [s44909@localhost ~]$ls -l /etc/passwd 83 | -rw-r--r--. 1 root root 19271 Oct 29 20:57 /etc/passwd 84 | 85 | [s44909@localhost ~]$ls -dl /etc/ 86 | drwxr-xr-x. 58 root root 4096 Oct 30 11:30 /etc/ 87 | 88 | По първия символ, на първото поле, спрямо разделител "." (или празен символ) разпознавам дали това с което работя е обикновен 89 | файл или директория. 90 | FMIcoursesBYME/OperatingSystems/exer04/exersice04.txt0000664000175000017500000002121312675160775021412 0ustar jrdnjrdnРазписани упражнения по Операционни системи от Йордан Бабуков. 91 | 92 | Операционни системи, упражнение 04 93 | 94 | Команди до момента: 95 | упр1) pwd, ls, echo, date, man 96 | упр2) who, passwd, cat, more, less, head, tail, touch, rm, mkdir, rmdir, cp, mv, sort, cut, grep 97 | упр3) wc, read, sleep, код на завършване, работа с променливи, изпълнение на команди във фонов режим, пренасочване на стандартен изход, стандартен вход, стандартен изход за грешка, Wildcards към команда ls, регулярни изрази към команда grep, конвейр от команди. 98 | 99 | Новo: 100 | Системни променливи: HOME, PS1, PATH 101 | Екраниращи символи "", '', \ 102 | Работа с текстов редактор "vi" 103 | 104 | 1) 105 | Системни променливи: 106 | echo $HOME -> извежда на стандартния изход home директорията на потребителя изпълнил командата. 107 | Пример: 108 | [s61851@localhost ~]$pwd 109 | /home/SI/s61851 110 | 111 | echo $PS1 -> от тази променлива се задава стойността на първоначалния prompt. 112 | Пример: 113 | [s61851@localhost ~]$echo $PS1 114 | [\u@\h \W]\$ 115 | \u се асоциира с потребителя, който изпълнява команден ред echo $PS1, в случая s61851 ;) ? 116 | \h се асоциира с hostnamе на работната станция, от която сме изпълнили командa echo с аргумент $PS1 117 | \W се асоциира с текущата директория, в която се намираме 118 | Можем да променим да показва каквото ние желаем по следния начин: 119 | PS1="[dancho@pencho mda]\$" 120 | Mожем да върнем първоначалният вид по следния начин: 121 | PS1="[\u@\h \W]\$" 122 | 123 | echo $PATH -> тук се указват директориите, в които bash ще търси дали командата съществува. Ако съществува ще я изпълни, ако 124 | не ще върне съобщение за грешка. 125 | Пример: 126 | [s44909@localhost ~]$echo $PATH 127 | /usr/local/bin:/bin:/usr/bin 128 | 129 | 2) 130 | Екраниращи символи: 131 | "" -> Двойни кавички, не отменят специалното значение на символи. 132 | \ -> обратна наклонена черта, отменя значението само на символа след нея. 133 | '' -> единични кавички, отменят значение на всички специални символи между тях. 134 | 135 | [s61851@localhost ~]$my_var=555 136 | [s61851@localhost ~]$echo $my_var 137 | 555 138 | [s61851@localhost ~]$echo "$my_var" 139 | 555 140 | [s61851@localhost ~]$echo \$my_var -> отменям специалното значение на символа $, съответно не успявам да достъпя стойността на променливата и екранирам низа "$my_var" 141 | $my_var 142 | [s61851@localhost ~]$echo "\$my_var" -> само \ отменя специалното значение на символа $ 143 | $my_var 144 | [s61851@localhost ~]$echo '$my_var' -> тук единичните кавички отменят специалното значение на $ 145 | $my_var 146 | [s61851@localhost ~]$echo '\$my_var' -> единичните кавички отменят специалното значение както на \, така и на $. 147 | \$my_var 148 | 149 | 3) 150 | Работа с текстов редактор "vi" 151 | Отваряне на файл за работа с "vi". 152 | vi my_file -> Ако файлът съществува, се отваря в готовност на работа с текстов редактор "vi" 153 | -> Ако файлът несъществува, бива създаден и отворен в команден режим (какво е команден режим - след малко) 154 | 155 | В текстов редактор "vi" има три основни режима: 156 | Команден(command mode), редови(command line), за въвеждане(insert mode) 157 | 158 | command mode -> се счита за неутрелен режим. В него отиваме чрез натискане на клавиша "ESC" 159 | insert mode -> това е режима, в който може да въвеждаме текст. В него може да отидем с някой от следните клавиши: 160 | i -> влизаме в режим на писане, като мястото на редакция е мястото на курсора в момента на натискане на клавиша 161 | I -> влизаме в режим на писане, в началото на реда, на който се намира курсора в момента на натискане на клавиша 162 | а -> като "i", но мястото на редакция е след мястото на курсора в момента на натискането на клавиша 163 | A -> влизаме в режим на писане, в края на реда, на който се намира курсора в момента на натискане на клавиша 164 | o -> създава нов празен ред, над мястото на курсора, като ни поставя в режим на писане 165 | O -> създава нов празен ред, под мястото на курсора, като ни поставя в режим на писане 166 | 167 | command line -> В него се влиза чрез клавишна комбинация shift+; (т.е. ":" ) от него можем например да запаметим 168 | текущата си работа и/или излезем от файл 169 | :w -> записваме файла 170 | :q -> излизаме от файл, ако сме го запаметили 171 | :q! -> излизаме от файл дори да не сме го запаметили 172 | :wq -> запаметяваме и излизаме 173 | :x -> същото като :wq 174 | 175 | Копиране на текст във файл, отворен с редактор "vi": 176 | yy -> копира реда, на който е курсора (мястото където временно се пази копието се нарича "clipboard") 177 | 5yy -> копира 5 реда, започвайки от реда на който е курсора 178 | yw -> копира думата над която е курсора 179 | 5yw -> копира 5 думи, започвайки от думата, на която е курсора 180 | y^ -> копира текста от текущото положение на курсора до началото на реда 181 | y$ -> копира текста от текущото положение на курсора до края на реда 182 | 183 | Поставяне на текст във файл, отворен с редактор "vi": 184 | p -> поставя текущото съдържанието на "clipboard" на нов ред, под курсора. 185 | P -> поставя текущото съдържанието на "clipboard" на нов ред, над курсора. 186 | 187 | Триене на текст във файл, отворен с редактор "vi": 188 | dd -> трие реда, на който е курсора (запазва се временно в "clipboard") 189 | 5dd -> трие 5 реда, започвайки от реда на който е курсора 190 | d^ -> трие текста от текущото положение на курсора до началото на реда 191 | d$ -> трие текста от текущото положение на курсора до края на реда 192 | 193 | Разхождане из съдържанието на файл отворен чрез редактор "vi": 194 | w -> премества ни една дума надясно от текущото положение на курсора 195 | 5w -> премества ни 5 думи надясно от текущото положение на курсора 196 | b -> премества ни една дума наляво от текущото положение на курсора 197 | 5b -> премества ни 5 думи наляво от текущото положение на курсора 198 | G -> изпраща ни на последния ред 199 | 5G -> изпраща ни на ред номер 5 200 | 1G -> изпраща ни в началото на файла 201 | 202 | *control + G ни връща полезна информация, когато сме се изгубили. 203 | -------------------------------------------------------------------------------- /exer05.tar: -------------------------------------------------------------------------------- 1 | exersice05-practice.txt0000664000175000017500000000543212677213770014061 0ustar jrdnjrdnЗадача 1: 2 | Напишете командна процедура на bash, приемаща от командния си ред три аргумента. Трите аргумента са цели числа съответстващи 3 | на число и краища на числов интервал. 4 | Скрипта да проверява дали числото е в указания интервал и да извежда подходящо съобщение спрямо случая, в който попада. 5 | При неуспех командната процедура да връща код на изход 99. 6 | 7 | Задача 2: 8 | Напишете командна процедура на bash, приемаща на командния си ред разумен брой аргументи. 9 | Програмата да създава любовен n-ъгълник. Любовният n-ъгълник може да бъде както отворен, така и затворен. 10 | 11 | Примерен вход на командния ред за отворен: 12 | bash love_n_angle.sh Teodora Daqna Genov Mariq Stanimir 13 | 14 | Примерен вход на командния ред за затворен: 15 | bash love_n_angle.sh Teodora Daqna Genov Iliqn Genov 16 | 17 | Примерен изход: 18 | Teodora loves Daqna 19 | Daqna loves Genov 20 | Genov loves Iliqn 21 | Iliqn loves Genov 22 | 23 | (Daqna has no luck) 24 | 25 | 26 | Задача 3: 27 | Да се състави командна процедура, която получава при стартиране като параметър в командния ред идентификатор на потребител. 28 | Процедурата периодично (+ sleep) проверява дали потребителят е стартирал сесия, в който случай прекратява проверката, извеждайки 29 | на стандартния изход подходящо съобщение. 30 | 31 | Задача 4: 32 | Да се състави командна процедура, която получава като параметри на командния си ред при стартиране имена на съществуващи текстови 33 | файлове. Процедурата прочита от стандартния вход символен низ и за всеки от зададените файлове извежда по подходящ начин на 34 | стандартния изход броя на редовете, които съдържат низа. 35 | 36 | Още задачи: 37 | http://newkis.fmi.uni-sofia.bg/~svi/os/ex/prob5.html 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Решения на задачите: 66 | 67 | Ако имате нужда от решения, напишете ми имейл, ще се постарая да ви представя такива! 68 | exersice05.txt0000664000175000017500000001440412701641446012261 0ustar jrdnjrdnРазписани упражнения по Операционни системи от Йордан Бабуков. 69 | 70 | Операционни системи, упражнение 05 71 | 72 | Команди до момента: 73 | упр1) pwd, ls, echo, date, man 74 | упр2) who, passwd, cat, more, less, head, tail, touch, rm, mkdir, rmdir, cp, mv, sort, cut, grep 75 | упр3) wc, read, sleep, работа с променливи, изпълнение на команди във фонов режим, пренасочване на стандартен изход, стандартен вход, 76 | стандартен изход за грешка, регулярни изрази към команда ls, регулярни изрази към команда grep, конвейр от команди. 77 | упр4) Системни променливи: HOME, PS1, PATH, Екраниращи символи "", '', \, Работа с текстов редактор "vi" 78 | 79 | Новo: 80 | Код на завършване на последно изпълнена команда 81 | Команда exit 82 | Позиционни параметри 83 | if 84 | whilе 85 | until 86 | for 87 | 88 | 89 | 1) 90 | Код на завършване на последно изпълнена команда 91 | 92 | Всяка изпълнена команда, след завършването си връща код, с който сигнализира дали е завършила успешно или не. 93 | Код на завършване при успех -> 0 94 | Код на завършване при неуспех -> число по-голямо от 0 95 | Визуализиране на изхода на завършване: echo $? 96 | Примери: 97 | При успех: 98 | [jbabukov@localhost ~]$ echo "Здравей" 99 | Здравей 100 | [jbabukov@localhost ~]$ echo $? 101 | 0 102 | 103 | При неуспех: 104 | [jbabukov@localhost ~]$ cp k1 k2 k3 105 | cp: target `k3' is not a directory 106 | [jbabukov@localhost ~]$ echo $? 107 | 1 108 | [jbabukov@localhost ~]$ echo $? 109 | 0 -> този изход е 0, защото последната изпълнена команда е предишното echo $? 110 | 111 | Команда exit 112 | Изпълнена в shell скрипт, команда exit приключва изпълнението на скрипта. 113 | Може да модифицираме кода на изход чрез команда exit. 114 | еxit, exit 99, exit 1, exit 200 115 | 116 | 117 | 2) 118 | Позиционни параметри 119 | 120 | При стартиране на скрипт от команден ред, подадените към него аргументи се наричат позиционни параметри (positional parameters) 121 | 122 | Достъп до позиционни параметри: $1, $2... ${10}, ${11},.. ${n} 123 | $0 -> се асоциира с името на скрипта, с който работим. 124 | $1 -> с първия му позиционен параметър и така нататък.. 125 | $* -> се асоциира с всички позиционни параметри последователно. 126 | $@ -> като $* 127 | $# -> брой позиционни параметри (не се включва името на баш скрипта) 128 | 129 | 130 | [jbabukov@localhost ~]$ cat bash_01.sh 131 | #!/bin/bash 132 | 133 | echo "The name of script is: $0" 134 | echo "First positional parameter's value is: $1" 135 | echo "Second positional parameter's value is: $2" 136 | 137 | echo 138 | 139 | echo "Number of positional parameters is: $#" 140 | 141 | echo 142 | 143 | echo "All positional parameters in once: $*" 144 | [jbabukov@localhost ~]$ bash bash_01.sh Dancho Gerlana 145 | The name of script is: bash_01.sh 146 | First positional parameter's value is: Dancho 147 | Second positional parameter's value is: Gerlana 148 | 149 | Number of positional parameters is: 2 150 | 151 | All positional parameters in once: Dancho Gerlana 152 | 153 | 154 | 155 | 3) 156 | Работа с условен оператор if 157 | 158 | Синтаксис: 159 | if [ ... ] 160 | then 161 | ... 162 | elif [ ... ] -> може да имаме N на брой вложени elif-а 163 | then 164 | ... 165 | else 166 | ... 167 | fi 168 | 169 | Числово сравняване: 170 | number1 -eq number2 (equal) 171 | number1 -ne number2 (not equal) 172 | number1 -gt number2 (greater than) 173 | number1 -ge number2 (greater or equal) 174 | number1 -lt number2 (less than) 175 | number1 -le number2 (less or equal) 176 | 177 | Сравняване на низове 178 | "стринг1" = "стринг2" 179 | "стринг1" != "стринг2" 180 | "стринг1" >= "стринг2" 181 | "стринг1" > "стринг2" 182 | "стринг1" <= "стринг2" 183 | "стринг1" < "стринг2" 184 | 185 | Логически съединения: -o, -a, &&, || 186 | 187 | cat bash_02.sh 188 | #!/bin/bash 189 | 190 | if [ $# -ne 1 ] 191 | then 192 | exit 99 193 | fi 194 | 195 | if [ $1 -le 10 -a $1 -gt 2 ] 196 | then 197 | echo "$1 is between (2 and 10]" 198 | elif [ $1 -le 2 ] 199 | then 200 | echo "$1 is less or equal to 2" 201 | else 202 | echo "$1 is greater than 10" 203 | fi 204 | 205 | 206 | cat bash_03.sh 207 | #!/bin/bash 208 | 209 | if [ $# -ne 1 ] 210 | then 211 | exit 99 212 | fi 213 | 214 | if [ $1 -le 10 ] && [ $1 -gt 2 ] 215 | then 216 | echo "$1 is between (2 and 10]" 217 | elif [$1 -le 2] 218 | then 219 | echo "$1 is less or equal to 2" 220 | else 221 | echo "$1 is greater than 10" 222 | fi 223 | 224 | 4) 225 | Оператор while и оператор until 226 | 227 | Синтаксис 228 | while [ ... ] 229 | do 230 | ... 231 | done 232 | 233 | #Приканва потребителят да въвежда вход, докато не въведе число в интервала [0-9] 234 | while [ true ] 235 | do 236 | echo "Enter digit between 0 and 9" 237 | read my_digit 238 | 239 | if ! [ $my_digit -lt 0 -o $my_digit -gt 9 ] 240 | then 241 | echo "Good job! " 242 | break 243 | else 244 | echo "Try again! " 245 | continue 246 | fi 247 | 248 | echo "This line will never be printed - why? " 249 | done 250 | 251 | ---- 252 | until -> синтаксис: идентичен на while. Логика: идентична на while с разлика едно логическо отрицание в условието, до което ще бъдат изпълнявани. 253 | 254 | 5) 255 | Оператор for 256 | 257 | Синтаксис 258 | for my_var in val1 val2 val3... 259 | do 260 | ... 261 | done 262 | 263 | Примери: 264 | for i in 2 5 1 10 265 | do 266 | echo "$i" -> ще изведе на стандартния изход числата 2 5 1 10 всяко на нов ред. 267 | done 268 | 269 | for i in $(seq 1 20) 270 | do 271 | echo "$i" -> ще изведе на стандартния изход числата от 1 до 20 през стъпка 1 всяко на нов ред. 272 | done 273 | 274 | for i in $(seq 1 5 20) 275 | do 276 | echo "$i" -> ще изведе на стандартния изход числата от 1 до 20 през стъпка 5. (1,6,11,16) 277 | done 278 | 279 | 280 | Обхождане на позиционни параметри: 281 | for i in $* 282 | do 283 | echo "$i" 284 | done 285 | 286 | 6) 287 | set; shift 288 | -------------------------------------------------------------------------------- /exer06.tar: -------------------------------------------------------------------------------- 1 | exersice06.txt0000664000175000017500000000544612704000177012261 0ustar jrdnjrdnРазписани упражнения по Операционни системи от Йордан Бабуков. 2 | 3 | Операционни системи, упражнение 06 4 | 5 | Още проверки към условен оператор if 6 | -z проверка дали файл или променлива е с празно съдържание. 7 | -n проверка дали файл или променлива е с непразно съдържание. 8 | -f проверка дали файл съществува и е обикновен 9 | -d проверка дали файл съществува и е директория 10 | -e проверка дали файл съществува, без значение какъв е. 11 | -r проверка дали файл има права за четене. 12 | -w проверка дали файл има права за писане 13 | -x проверка дали файл има права за изпълнение. 14 | 15 | Опции към команда echo 16 | -n премахва символа за нов ред в края на изписания текст. 17 | -е указва на команда echo да разбира от специални символи като \t и \n 18 | Примери: 19 | [root@dancho ~]# echo ala-bala 20 | ala-bala 21 | [root@dancho ~]# 22 | [root@dancho ~]# echo -n ala-bala 23 | ala-bala[root@dancho ~]# 24 | 25 | [root@dancho ~]# echo -e "ala\t@\nbala" 26 | ala @ 27 | bala 28 | 29 | "Аритметични изрази под bash. expr, bc. 30 | expr 1 + 2 събиране 31 | expr 1 - 2 изваждане 32 | expr 2 \* 3 умножение 33 | expr 3 / 6 деление 34 | еxpr 2 % 7 модулно деление 35 | expr \( 2 + 4 \) / 4 36 | k=1 37 | expr $k + 1 38 | k=$(expr $k + 1) 39 | echo $k 40 | NB! еxpr работи само с цели числа. 41 | 42 | За аритметика с числа с плаваща запетая може да използваме команда bc. 43 | [root@dancho ~]# echo "3 * 1.2" | bc 44 | 3.6 45 | [root@dancho ~]# echo "scale=3; 10 / 3" | bc 46 | 3.333 47 | 48 | Намиране на дължина на низ 49 | k="GardensOfMarqueyssac" 50 | expr length $k 51 | 52 | Извличане на подниз от низ 53 | expr substr $k 10 10 54 | Изличаме от 10ти символ, следващите 10 символа от низа "$k" 55 | 56 | Намиране на индекс на символ 57 | expr index $k M 58 | 59 | Файл ~/.bash_profile 60 | Това е файл, в който може да задаваме набор от команди и/или скриптове, които да бъдат изпълнявани веднага след аутентикирането ни пред системата. 61 | Може да добавим команден ред "mesg n" в края на файла, така всеки път като влизаме в системата веднага забраняваме на влюбените колеги да ни пишат. 62 | exersice06-practice.txt0000664000175000017500000000616512704000640014043 0ustar jrdnjrdnЗадача 1: 63 | Напишете командна процедура на bash, приемаща от командния си ред при стартиране три параметъра, съответсващи на тройка цели числа. 64 | Намерете сбора от първи и трети подаден входен параметър. Сбора умножете по втория подаден параметър и полученият резултат 65 | повдигнете на втора степен. 66 | 67 | Изведете на стандрартния изход подходящо съобщение съдържащо резултата от пресмятанията. 68 | 69 | Задача 2: 70 | Напишете командна процедура на bash, приканваща потребител да въведе числов низ. 71 | Процедурата да приканва потребителя, докато не той/тя/то не въведе числов низ с дължина над 5 символа. 72 | Изведете цифрата на стотиците на стандартния изход с подходящо съобщение. 73 | 74 | Бонус: 75 | Изведете последователно всяка една цифра на въведения низ в посока отляво надясно. 76 | 77 | Задача 3: 78 | Да се състави командна процедура, която получава в командния ред при стартиране два параметъра 79 | – първият от които – символен низ, а вторият – число. Ако съществува директория с име, съвпадащо с низа, 80 | процедурата извежда на стандартния изход имената на всички обикновени файлове в нея, които имат размер (в символи) по-голям 81 | от подаденото число. В противен случай (ако не съществува такава директория) – на стандартния изход се извежда подходящо съобщение. 82 | 83 | Задача 4: 84 | Да се състави командна процедура, която получава на командния си ред при стартиране един параметър - параметърът да бъде естествено число. 85 | Процедурата да извежда N на брой звездички на първи ред. 86 | N-1 брой звездички на втори ред и така, докато N не стане 0. 87 | Стойността на N съответства на подадения входен параметър. 88 | Звездичките да бъдат приравнени откъм десния край. 89 | 90 | Примерен вход и резултат: 91 | bash my_stars.bash 3 92 | *** 93 | ** 94 | * 95 | 96 | Задачи 5: 97 | Сложете скриптът написан от задача 4 като съобщение, което ви приветства всеки път когато се логнете в акаунта си. 98 | exersice06-practice-2.txt0000664000175000017500000000566112704001247014206 0ustar jrdnjrdn0. 99 | Напишете командна процедура приемаща два аргумента на командния си ред, съответващи на две естествени числа. 100 | Нека процедурата изведе подходящо съобщение на стандртния изход за стойността на квадратите на тези числа. 101 | 102 | 1. 103 | Напишете командна процедура приемащата произволен брой аргументи на командния си ред. 104 | Всеки подаден позиционен параметър съответства на естествено число. 105 | Нека процедурата изведе на стандартния изход числото повдигнато на квадрат. 106 | 107 | 2. 108 | Модифицирайте задача 1, така че програмата да изведе числото вдигнато на квадрат, само ако то е в интервала [5,105) 109 | 110 | 3. 111 | Модифицирайте задача 2, така че интервалът да бъде въведен от потребителя. 112 | 113 | 4. 114 | Напишете командна процедура, която приема на командния си ред три позиционни параметъра. 115 | Нека процедурата проверява, дали вторият позиционен параметър се намира в интервал дефиниран от първия и третия позиционен параметър. 116 | Като третият съответства на лявата страна на интервала. 117 | 118 | 8. 119 | Напишете командна процедура, която приема на командния си ред два параметъра - две директории. 120 | Нека командната процедура копира всички обикновени файлове от директорията, подадена като първи позиционен параметър в директорията 121 | подадена като втори позиционен параметър. 122 | 123 | 9. 124 | Модифицирайте задача 8, така че процедурата да извежда подходящо съобщение на стандартния изход за броя копирани файлове. 125 | 126 | 10. 127 | Модифицирайте задача 9, така че процедурата да извежда подходящо съобщение на стандартния изход за броя на копираните файлове с размер 128 | по-голям от число въведено от потребителя. 129 | 130 | 11. 131 | Модифицирайте задача 10, така че потребителя да бъде приканван да въведе число, докато то не е по-голямо от 100 и по-малко от 10000 132 | -------------------------------------------------------------------------------- /exer07.tar: -------------------------------------------------------------------------------- 1 | exersice07-practice.txt0000664000175000017500000001326112706610361014050 0ustar jrdnjrdnРазписани упражнения по Операционни системи от Йордан Бабуков. 2 | 3 | Операционни системи, задачи към упражнение 7 4 | 5 | 1) 6 | Да се състави командна процедура, която получава като параметри на комадния ред, при стартиране, два символни низа - 7 | потребителско име и име на съществуващ файл, който съдържа информация за текущо стартираните процеси от всички потребители. 8 | Нека процедурата да прекратява изпълнението на всички процеси, стартирани от потребителя, подаден като входен параметър и записва 9 | броя на тези процеси във файл с име - името на потребителя. 10 | 11 | Приемаме, че съдържанието на файла, подаден като входен параметър, има следната структура: 12 | UID PID STIME COMMAND 13 | root 23787 13:36 /bin/chroot 14 | lora 23791 13:36 /bin/rsync 15 | milena 23792 13:36 /bin/dmidecode 16 | vasilen 23843 13:50 /bin/dd 17 | panayot 23847 13:58 /bin/ls -alhtris 18 | dancho 23848 13:58 /bin/cat 19 | manuela 23849 13:58 /bin/gz 20 | dimitar 23891 14:36 /bin/tar 21 | irina 23892 14:36 /bin/lspci 22 | sendmail 23943 14:50 /bin/date 23 | georgi 23947 14:58 /bin/lvdisplay 24 | liubomir 23948 14:58 /bin/vgdisplay 25 | asen 23949 14:58 /bin/uname -a 26 | и че потребителските имена не съдържат празни символи. 27 | 28 | *Ако виждате името си - обяснете стартирана от вас команда. Ще получите +. Може да използвате Интернет. 29 | **Ако не виждате името си - обяснете команда по ваш избор. Ще получите +. Може да използвате Интернет. 30 | ***Нямате право да избирате команди на специалните потребители: root, sendmail и dancho. 31 | 32 | 2) 33 | Да се състави командна процедура, която получава като параметър на командния ред символен низ - име на процес. 34 | Ако процес с това име е стартиран в системата, създава директория, чието име е прочетено от стандартния вход, с пълни права за 35 | собственика, четене и изпълнение за групата му и никакви права за останалите. Копира в нея всички изпълними обикновени файлове 36 | от началната потребителска директория. 37 | 38 | 3) 39 | Да се състави командна процедура, която получава на комадния си ред, при стартиране произволен брой аргументи. 40 | Нека командната процедура проверява дали подаден входен параметър е директория и ако е - обхожда съдържанието му и за всеки 41 | обикновен файл със зададен собственик съотвестващ на зададения собственик на родителската му директория да променя групата на 42 | файла да бъде като групата на родителската директория и задава само права за четене на групата. 43 | Ако входния параметър не е директория, нека параметърът бъде пропуснат от последвала обработка. 44 | 45 | забележка: 46 | Ако до момента имате поне една оценка по-висока от 4.5 по ОС, нямате право да обхождате подадените позиционни параметри с 47 | оператор за цикъл "for" 48 | *попитайте с команда shift 49 | 50 | 4) 51 | Напишете командна процедура, която приканва потребителя да въведе факултетният си номер. 52 | Докато потребителя не въведе ФН, процедурата продължава да го приканва. 53 | При коректно въведен ФН да се създаде файл в текущата директория с име стойността на въведения ФН и съдържание отново същата стойност. 54 | Ако ФН е четно число да се зададат пълни права за достъп върху новосъздадения файл, в противен случай да се зададат единствено права за четене и писане. 55 | 56 | 5) 57 | Да се състави командна процедура, която получава като параметър на командния си ред, при стартиране, символен низ - потребителско име. 58 | Нека процедурата да прекратява изпълнението на всички cat процеси, стартирани от потребителя, подаден като входен параметър и записва броя на тези процеси във файл с име - името на потребителя. 59 | 60 | примерно решение 61 | ps -u $1 | grep "cat" | wc -l > $1.txt 62 | killall -9 cat -u $1 63 | exersice07-solutions.txt0000664000175000017500000003056712706611734014332 0ustar jrdnjrdnОперационни системи, упражнение 08, решения 64 | 65 | 1) 66 | Да се състави командна процедура, която получава като параметри на комадния ред, при стартиране, два символни низа - 67 | потребителско име и име на съществуващ файл, който съдържа информация за текущо стартираните процеси от всички потребители. 68 | Нека процедурата да прекратява изпълнението на всички процеси, стартирани от потребителя, подаден като входен параметър и записва 69 | броя на тези процеси във файл с име - името на потребителя. 70 | 71 | Приемаме, че съдържанието на файла, подаден като входен параметър, има следната структура: 72 | UID PID STIME COMMAND 73 | root 23787 13:36 /bin/chroot 74 | lora 23791 13:36 /bin/rsync 75 | milena 23792 13:36 /bin/dmidecode 76 | vasilen 23843 13:50 /bin/dd 77 | panayot 23847 13:58 /bin/ls -alhtris 78 | dancho 23848 13:58 /bin/cat 79 | manuela 23849 13:58 /bin/gz 80 | dimitar 23891 14:36 /bin/tar 81 | irina 23892 14:36 /bin/lspci 82 | sendmail 23943 14:50 /bin/date 83 | georgi 23947 14:58 /bin/lvdisplay 84 | liubomir 23948 14:58 /bin/vgdisplay 85 | asen 23949 14:58 /bin/uname -a 86 | и че потребителските имена не съдържат празни символи. 87 | 88 | *Ако виждате името си - обяснете стартирана от вас команда. Ще получите +. Може да използвате Интернет. 89 | **Ако не виждате името си - обяснете команда по ваш избор. Ще получите +. Може да използвате Интернет. 90 | ***Нямате право да избирате команди на специалните потребители: root, sendmail и dancho. 91 | 92 | Решение: 93 | #проверка дали позиционните параметри са точно 2 94 | if [ $# -ne 2 ] 95 | then 96 | echo "Wrong number of arguments, try with 2! " 97 | exit 99 98 | fi 99 | 100 | #Вариант 1: 101 | #$2 е файлът с информация за стартираните процеси, който сами сме си направили например с изпълняването на следния команден ред: "ps aux > txt.txt" 102 | 103 | #От стартираните процеси извличан (grep) тези, които са на потребител подаден като първи позиционен аргумент, след което извличам PID-а на процеса и го убивам. 104 | #Тъй като стартираните процеси може да са повече от 1 итерирам по всички извлечени PID-ове. 105 | for i in $(grep ^$1 "$2" | cut -f2 -d " ") 106 | do 107 | kill -9 $i 108 | done 109 | 110 | #Вариант 2, ако не работехме върху фиктивен файл, а върху реално текущо стартираните процеси: 111 | #Убиваме (спираме, killall) всички процеси (-a) на потребител (-u) подаден като първи позиционен аргуемнт ($1) 112 | killall -a -u $i 113 | 114 | 2) 115 | Да се състави командна процедура, която получава като параметър на командния ред символен низ - име на процес. 116 | Ако процес с това име е стартиран в системата, създава директория, чието име е прочетено от стандартния вход, с пълни права за 117 | собственика, четене и изпълнение за групата му и никакви права за останалите. Копира в нея всички изпълними обикновени файлове 118 | от началната потребителска директория. 119 | 120 | Решение: 121 | #Проверяваме дали има стартиран процес подаден като 1-ви аргумент 122 | #ps aux извежда всички текущо стартирани процеси на системата (сървърчето/компютърчето, на което работим) 123 | #grep $1 извлича всички процеси с това име 124 | # wc -l преброяваме ги 125 | # -ge 1 ако има поне 1 стартиран такъв процес продължаваме по условието на задачата 126 | if [ $(ps aux | grep $1 | wc -l) -ge 1 ] 127 | then 128 | #Приканваме потребителя да въведе име на директория (стартен вход) 129 | echo -n "Enter directory name that will be created: " 130 | read dir_name 131 | 132 | #Създаваме директория с въведеното име 133 | mkdir $dir_name 134 | 135 | #Задаваме пълни права на собственика на директория (7) 136 | #Задаваме на групата на файла права за четене (r = 4) + права за достъп до съдържанието на директорията (x = 1) общо 5. 137 | #Задаваме никакви права за всички останали (0) 138 | chmod 750 $dir_name 139 | 140 | #Копираме всички изпълними файлове от home директорията ни в ново създадената директория. 141 | for i in $(ls ~/) 142 | do 143 | if [ -f $i & -x $i ] 144 | then 145 | cp $i $dir_name 146 | fi 147 | done 148 | fi 149 | 150 | 3) 151 | Да се състави командна процедура, която получава на комадния си ред, при стартиране произволен брой аргументи. 152 | Нека командната процедура проверява дали подаден входен параметър е директория и ако е - обхожда съдържанието му и за всеки 153 | обикновен файл със зададен собственик съотвестващ на зададения собственик на родителската му директория да променя групата на 154 | файла да бъде като групата на родителската директория и задава само права за четене на групата. 155 | Ако входния параметър не е директория, нека параметърът бъде пропуснат от последвала обработка. 156 | 157 | забележка: 158 | Ако до момента имате поне една оценка по-висока от 4.5 по ОС, нямате право да обхождате подадените позиционни параметри с 159 | оператор за цикъл "for" 160 | *попитайте с команда shift 161 | 162 | Решение: 163 | #обхождаме позиционните параметри 164 | for i in $* 165 | do 166 | #проверяваме дали текущия позиционен параметър е директория 167 | if [ -d $i ] 168 | then 169 | #ако е директория обхождаме съдържанието ѝ 170 | for j in $(ls $i) 171 | do 172 | #проверяваме дали съдържанието има обикновени файлове 173 | if [ -f $j ] 174 | then 175 | #ако има обикновен файл, то: 176 | #проверяваме дали собственика на файла (файлът е $j, а собственикът е 3то поле от изхода на команда ls -l за $j) не е същият като този на родителската директория (родителската директория е $i и с ls -ld виждаме нейните права, от които извличаме 3то поле - собственикът ѝ) 177 | if [ $(ls -l $j | tr -s " " | cut -f3 -d" ") = $(ls -ld $i | tr -s " " | cut -f3 -d" ") ] 178 | then 179 | #ако двете съвпадат, то сменяме групата на файла ($j) да е такава каквато е на родителската директория ($i) 180 | chown .$(ls -ld $i | tr -s " " | cut -f3 -d" ") $j 181 | 182 | #също така сменяме правата на групата за достъп до файла. 183 | chmod g=r $j 184 | fi 185 | fi 186 | done 187 | fi 188 | done 189 | 190 | 4) 191 | Напишете командна процедура, която приканва потребителя да въведе факултетният си номер. 192 | Докато потребителя не въведе ФН, процедурата продължава да го приканва. 193 | При коректно въведен ФН да се създаде файл в текущата директория с име стойността на въведения ФН и съдържание отново същата стойност. 194 | Ако ФН е четно число да се зададат пълни права за достъп върху новосъздадения файл, в противен случай да се зададат единствено права за четене и писане. 195 | 196 | Решение: 197 | while [ true ] 198 | do 199 | #приканваме потребителят да въведе факултетният си номер 200 | echo -n "Въведете факултетният си номер: " 201 | read fac_num 202 | 203 | #ако факултетният номер е число правим нещо си, иначе пак бива приканен 204 | if [ $fac_num -eq $fac_num ] 2> /dev/null 205 | then 206 | #създаваме файл си име $fac_num и съдържание $fac_num 207 | echo $fac_num > ./$fac_num 208 | #ако $fac_num е четно, задаваме пълни права, иначе само за писане и четене 209 | if [ $(expr $fac_num % 2) -eq 0 ] 210 | then 211 | chmod 777 $fac_num 212 | else 213 | chmod 666 $fac_num 214 | fi 215 | break 216 | fi 217 | done 218 | 219 | 5) 220 | Да се състави командна процедура, която получава като параметър на командния си ред, при стартиране, символен низ - потребителско име. 221 | Нека процедурата да прекратява изпълнението на всички cat процеси, стартирани от потребителя, подаден като входен параметър и записва броя на тези процеси във файл с име - името на потребителя. 222 | 223 | примерно решение 224 | ps -u $1 | grep "cat" | wc -l > $1.txt 225 | killall -9 cat -u $1 226 | 227 | 6) 228 | Да се състави командна процедура, която обхожда файловете в HOME директорията на текущия потребител. 229 | За всеки файл в директорията, който има друг собственик, процедурата сменя собственика и групата на файла с текущия 230 | потребител и неговата група. 231 | 232 | Решение: 233 | #обхождане на всички файлове в текущата директория 234 | for i in $(ls ~/) 235 | do 236 | #ако сме текущо на обикновен файл със собственик различен от мен.. 237 | if [ -f $i -a $(ls -l $i | tr -s " "| cut -f3 -d" ") != $(whoami) ] 238 | then 239 | #сменяме собственика и групата на файла да бъдат мен. 240 | chown $(whoami).$(whoami) $i 241 | fi 242 | done 243 | exersice07.txt0000664000175000017500000003153212716700617012266 0ustar jrdnjrdnРазписани упражнения по Операционни системи от Йордан Бабуков. 244 | 245 | Операционни системи, упражнение 07 246 | 247 | Права на достъп: 248 | В повечето съвременни файлови системи всеки файл има права на достъп. 249 | *В Linux всичко е файл, дори клавиатурата и мишката. 250 | 251 | Правата на достъп до файл може да видим с команда "ls -l" 252 | -rwxr-x--- 1 jbabukov teachers 114 Nov 2 12:58 loveTriangle.sh 253 | 254 | Правата за достъп до файла са описани в първо поле, спрямо разделител " " или иначе казано "-rwxr-xr-x". 255 | Първият символ '-' ни носи информация за типа на самия файл. 256 | '-' означава, че файлът е обикновен. 257 | 'd' означава, че файлът е директория. 258 | 'l' означава, че файлът е символна връзка. 259 | 'c' означава, че файлът е character device. Пример за такъв файл е файлът асоцииран с клавиатурата. (ls -l /dev/) 260 | 'b' означава, че файлът е block device. 261 | 262 | Пример за файл, асоцийран с character устройство: 263 | [...]$ ls -l /dev/fuse 264 | crw-rw-rw-. 1 root root 10, 229 May 15 23:48 /dev/fuse 265 | 266 | Пример за файл тип символна връзка: 267 | ls -l /etc/rc.d/rc3.d/ 268 | lrwxrwxrwx. 1 root root 20 Dec 18 01:10 K50netconsole -> ../init.d/netconsole 269 | 270 | Малко повече инфо за последното: 271 | Символната връзка е удачно да се използва, когато имаме файл, който ще бъде прочитан от множество потребители. 272 | Например имаме един 100GB файл, с телефонни номера на студентки. Имаме на системата 5 потребителя, студенти. 273 | Вместо да копираме големият файл в home директориите на 5те студента, създаваме символни връзки. 274 | Символната връзка само сочи към дадения файл. 275 | Така реално имаме само един 100GB файл и всеки потребител има файл тип символна връзка, която сочи към истинския файл. 276 | Ако изтрием оригиналният файл, символните връзки са "счупени" - сочат към вече несъществуващ файл. 277 | 278 | #извеждане на информация с какъв потребител работя: 279 | [...]$ whoami 280 | jrdn 281 | 282 | Следват три тройки права. rwx rwx rwx. Ако някое от правата не е налично се означава с '-' 283 | 284 | Първата тройка права указват какво е позволено за собственикa на файла. 285 | В случая първата тройка права е 'rwx' и дава права за четене(Read), права за писане(Write) и права за изпълненение на файла (eXecute) на собственика на файла. 286 | 287 | Следващата тройка права са за групата, към която файлът принадлежи. 288 | В случая те са 'r-x', което означава, че групата може да прочете съдържанието на файла, както и да го изпълни, но не и да модифицира съдържанието на файла. 289 | 290 | Последната тройка права са за всички останали. 291 | В случая '---' не позволява на никого освен собственика и групата на файла да правят каквото и да било с този файл. 292 | 293 | *Aко правата бяха -rwx------ означава, че само аз мога да си играя с файла. 294 | 295 | Модифициране на права за достъп до файл: 296 | chmod u+r -> добавя права за четене на собственика (user) 297 | chmod g-wx -> премахва права за писане и изпълнение на групата (group) 298 | chmod o-rwx -> премахва всички права на всички останали (others) 299 | chmod -x -> премахва права за изпълнение на файла от всички (собс, група, всички останали) 300 | chmod +rx -> добавя права за четене и изпълнение на файл към всички (собс, група, всички останали) 301 | chmod u=r -> залага единствено права за четене на собственик. На групата и всички останали не се променят. 302 | chmod u= -> занулява правата за достъп до файла на собственика. 303 | chmod = -> занулява правата за достъп до файла до абсолютно всички. 304 | chmod ugo= -> занулява правата за достъп до файла до абсолютно всички. 305 | chmod uo=r -> задава права на собственика и всички останали права за четене. 306 | 307 | Алтернативен начин за работа с правата на файлове: 308 | 309 | Всяка тройка от права е представена в бинарен вид: 310 | rwx = 2^2, 2^1, 2^0, или иначе казано rwx -> 421 311 | За задаване на пълни права до собственика и никакви до всички останали става така: 312 | chmod 700 (read+write+execute за собственика и 0 за групата и останалите) 313 | 314 | Залагане на sticky bit: 315 | chmod 1752 -> само собственикът на файла може да изтрие файла, независимо от w правата. Пример за такава директория е /tmp 316 | 317 | SUID 318 | chmod 2710 -> файлът се изпълнява с правата на собственикът на файлът, а не с тези на изпълнителят. Пример за такава команда е ping. ls -l /bin/ . 319 | 320 | GUID 321 | chmod 4763 -> файловете, които биват създадени в директория с вдигнат GUID бит наследяват групата на собстветника на директорията. 322 | *Ползва се например при конфигуриране на git server 323 | **Питайте ме за повече инфо, как и защо се ползва 324 | 325 | Пример с права: 326 | Аз съм си разрешил на мен и на групата към която съм (преподавателите) да ми виждат съдържанието на директорийката, а на всички останали (вас) съм забранил. 327 | *Ако някой ме хакне ще се сдобие с решение на домашното - давайте. 328 | 329 | Да създадем 1 файл и 1 директория: 330 | touch f1 331 | mkdir dir1 332 | [dancho@varileka mir]$ls -l f1 333 | -rw-r--r-- 1 jbabukov teachers 0 Oct 19 11:27 f1 334 | 335 | [dancho@varileka mir]$ls -ld dir1 336 | drwxr-xr-x 3 jbabukov teachers 4096 Nov 11 16:55 dir1 337 | 338 | По подразбиране по security причини ново-създадените файлове нямат пълни права. Например ако си създадем директория попринцип не бихме искали другите да могат да създават и трият файлове от нея. Затова няма права w. 339 | 340 | Това става чрез umask 341 | [manuela@georgi lora]$umask 342 | 0022 343 | umask е като шапка. Ако правата на файла са 777, тя слага -0 на 1вите права, -2 на вторите и -2 на третите. Крайният резултат е: 755 или rwxr-xr-x, което виждаме за директория. 344 | 345 | Правата x за директория определят дали може да влезем в папката, а 'r' дали може да ѝ прочетем съдържанието. 346 | За файл правото x определя дали файлът може да бъде изпълнен. Тъй като е опасно всеки да може да изпълни файл по подразбиране на ново създадените файлове им се слага umask 133, вместо 022, което премахва x правото. 347 | 348 | Още един пример с права на файл: 349 | Когато споделяте нещо с dropbox, другият може да го види само ако му предоставим линка. 350 | 351 | Това става като имаме директория с права --x--x--x. Всеки може да достъпи съдържанието на директорията, но само ако знаете изрично как се казва, тъй като нямате права за изследване на съдържанието ѝ. 352 | 353 | Смяна на собственика и група: 354 | chown jbabukov f1 -> сменя само собственика 355 | chgrp jbabukov f1 -> сменя само групата 356 | chown jbabukov:jbabukov f1 -> сменя собственик и група 357 | chown :jbabukov f1 -> сменя само група 358 | chown jbabukov.jbabukov f1 -> аналогично на : 359 | chown .jbabukov f1 -> аналогично на : 360 | 361 | Процеси: 362 | ps -> дава инфо за стартираните процеси от потребителя (ама много оскъдно) 363 | *Процес -> програмен код в хода си на изпълнение. 364 | 365 | Всеки процес има PID (process ID) 366 | За повече инфо относно процесите: 367 | ps aux (a -> all, u -> user, x -> произволен потребител) т.е. дава инфо за всички процеси на всички потребители. 368 | 369 | За конкретен потребител: 370 | ps -a -u jbabukov 371 | 372 | ps aux | wc -l 373 | Това са всички текущо стартирани процеси. само 15тина са от нас, другите са системни. Те са нужни, за да имаме работна среда. 374 | 375 | Коя е хардуерната компоненета, която изпълнява тези процеси? 376 | 377 | 1 процесор, може да изпълни 1 процес даден момент, но го прави толкова бързо, че ние си мислим че вървят паралелно. 378 | 379 | ps -a -u jbabukov ft 380 | 381 | Така може да видим йерархията на стартираните процеси. 382 | Стартирал съм sshd сесия (това при аутентикирането) 383 | След това се е стартирал bash за мен. После съм стартирал процеса ps. 384 | 385 | Родителят на процеса се грижи да изчака детето да приключи изпълнението си и чак след това се връща в нормален режим на работа. 386 | Пример: sleep 5 -> bash (родителят) изчаква процеса да завърши и чак тогава пак сме ние. 387 | 388 | За всеки стартиран процес се заделя памет (хардуерен ресурс), какво се случва ако бащата не изчака процеса и той си увисне във въздуха? 389 | Осиновява се от init процеса - 1вият процес. 390 | 391 | Убиване на процес: 392 | kill -9 PID -> убива единичен процес 393 | killall -9 processName -> убива всички инстанции на процес (например няколко стартирани и зависнали firefox-a) 394 | 395 | Работа с процеси стартирани във фонов режим: 396 | sleep 10000 & 397 | ps aux | grep sleep 398 | процеса си стои.. 399 | jobs -> извежда всички стартирани процеси във фонов режим от мен. 400 | fg -> променя режима на стартирания процес от фонов (background) в явен (fg = foreground) 401 | ctrl + c спираме текущия процес. 402 | 403 | Пример за приложение на тези команди 404 | vi 123 405 | shift + z + z (изпращаме vi процеса във фонов режим) 406 | Разглеждаме си нещо 407 | fg (връщаме vi процеса да е текущ) 408 | Работим си върху скрипта. 409 | 410 | -------------------------------------------------------------------------------- /exer08.txt: -------------------------------------------------------------------------------- 1 | Commands till now: 2 | Till K1: 3 | pwd, ls, echo, date, man, who, passwd, cat, head, tail, touch, rm, mkdir, rmdir, cp, mv, sort, cut, grep, wc, read, sleep, exit, shift 4 | Работа с променливи, фонов режим, пренасочване на ст. вх/из/гр, конвейр, екраниращи символи. 5 | if (сравнение на числа и на стрингове) 6 | for, while, until 7 | 8 | Till K2: 9 | Още опции към оператор if: -z, -n, -f, -d, -e, -r, -w, -x 10 | Опции към команда echo, -n, -e 11 | Аритметични изрази с expr, expr length, expr substr, expr index 12 | chmod, chown, ps, kill 13 | 14 | 1. 15 | Напишете командна процедура на bash, която приема на командния си ред произволен брой аргументи. 16 | Аргументите съответстват на съществуващи обикновени файлове и директории в текущата директория. 17 | Нека командната процедура извежда на стандартния изход подходящо съобщение, ако подаден аргумент е файл с права за четене. 18 | Ако подаденият аргумент е директория, да изведе на стандартния изход само файловете, които имат по-малък размер от броя на файловете в директорията. 19 | 20 | Решение: 21 | #обхождаме всички подадени позиционни параметри 22 | for i in $* 23 | do 24 | #проверка, дали текущия позиционен параметър е обикновен файл с права за четене 25 | if [ -f ./$i ] && [ -r ./$i ] 26 | then 27 | echo "$1 is file with read permissions! " 28 | fi 29 | 30 | #проверяваме, дали текущият параметър е директория 31 | if [ -d ./$i ] 32 | then 33 | #ако е директория я обхождаме 34 | for j in $(ls ./$i) 35 | do 36 | #проверяваме дали големите на файл е по-малка от броя на обикновените файлове в тази директория 37 | if [ $(wc -c < ./$i/$j ) -lt $(ls -l ./$i | grep ^- | wc -l) ] 38 | #$i е директорията и в нея трябва да имаме файлове, които последователно ще обхождаме с променливата $j. 39 | then 40 | echo "Some friendly output" 41 | fi 42 | done 43 | fi 44 | done 45 | 46 | 2. 47 | Напишете командна процедура на bash, която приема на командния си ред един аргумент - символен низ, съответстващ на съществуваща директория. 48 | Нека командната процедура приканва потребителят да въведе директория, след което създава въведената от него директория във вашата home директория и копира всички обикновени файлове съдържащи се в директорията въведена от команден ред, които имат права за четене и писане в нея. 49 | 50 | Решение: 51 | #проверка дали е въведен точно е аргумент и дали съответства на директория се прави по желание. 52 | #приканваме потребителят да въведе нещо си 53 | echo -n "Dear user, please enter directory name: " 54 | read dir_name_entered_by_user 55 | 56 | #създаваме директорията, спрямо изискването от условието. 57 | mkdir ~/$dir_name_entered_by_user 58 | 59 | #копираме обикновените файлове от директория, въведена като първи позиционен аргумент - в тази въведена от потребителя. 60 | #за целта трябва да обходим съдържанието на $1 и за всяко едни нещо в нея да проверим дали отговаря на критериите от условието на задачата. 61 | for i in $(ls $1) 62 | do 63 | #проверка дали е файл, права за четене (read), права за писане (write) 64 | if [ -f $i ] && [ -r $i ] && [ -w $i ] 65 | then 66 | #ако покрива всичките тези условия, то тогава копираме файла в директорията въведена от потребителя. 67 | cp $i ~/$dir_name_entered_by_user 68 | fi 69 | done 70 | 71 | 72 | 3. 73 | Да се състави командна процедура, която получава като параметри на командния си ред два символни низа - имена на същестуваща директория и на съществуващ обикновен файл. 74 | За всеки обикновен файл от директорията да извежда по подходящ начин броя символи в него на стандартния изход, а името на всяка директория да се добавя към файла подаден като втори параметър на командната процедура. 75 | 76 | #обхождаме директорията, като правим проверка дали е файл или е директория нейното съдържание. 77 | for i in $(ls $1) 78 | do 79 | #проверка дали е файл: 80 | if [ -f $i ] 81 | then 82 | #извеждам по подходящ начин броят символи на файл 83 | echo "File $i contains $(wc -c < $i) symbols. " 84 | fi 85 | 86 | #проверявам дали е директория: 87 | if [ -d $i ] 88 | then 89 | #ако е директория.. добавям името на директорията във файл подаден като 2ри позиционен аргумент 90 | echo $i >> $2 91 | fi 92 | done 93 | 94 | 4. 95 | Да се състави командна процедура, която получава като параметри на командния си ред два символни низа - имена на съществуващи директории. 96 | Aко броят на файловете, чието име съдържа разширение ".out" в първата директория е по-голям от броя на същите във втората, изведете подходящо съобщение на стандартния изход. 97 | 98 | #извличам всички файлове с разширение .out 99 | first_dir_content=$(ls -l $1 | grep ^- | grep '.out'$ | wc -l) 100 | second_dir_content=$(ls -l $2 | grep ^- | grep '.out'$ | wc -l) 101 | 102 | #сверявам броят на файловете във всяка и спрямо сравнението предприемам някакво действие. 103 | if [ $first_dir_content -gt $second_dir_content ] 104 | then 105 | echo "First dir has more files with '.out' extension. " 106 | fi 107 | 108 | 109 | 5. 110 | Напишете командна процедура на bash, която приканва потребителят да въведе факултетния си номер. 111 | Докато потребителят не въведе ФН, процедурата да продължава да го приканва. 112 | При коректно въведен ФН, ако цифрите на десетиците е: 113 | 1, да изведе на стандартния изход "Вие сте от първа група" 114 | 2, да изведе на стандартния изход "Вие сте от втора група" 115 | 3, да изведе на стандартния изход "Вие сте от трета група" 116 | 4, да изведе на стандартния изход "Вие сте от четвърта група" 117 | 118 | *Стойността на ФН е произволно естествено число в интервала [100, 9999] 119 | 120 | #приканваме потребителя да въведе ФН: 121 | echo "Dear Gerlana, please enter a faculty number: " 122 | read fac_num 123 | 124 | #ако не е въвела фн (фн е число от 100 до 9999) 125 | while [ true ] 126 | do 127 | #check if the entered thing is really a faculty number: 128 | if [ $fac_num -gt 100 -a $fac_num -lt 10000 ] 2> /dev/null 129 | then 130 | echo "Good job! " 131 | #if it's faculty number, leave the infinite while loop 132 | break 133 | fi 134 | #if it's not a faculty number, keep prompting the user to enter a faculty number.. 135 | echo "Oh, no! You have to try again, please read the instructions" 136 | echo "Dear Gerlana, please enter a faculty number: " 137 | read fac_num 138 | done 139 | 140 | #това може и с if-ове. 141 | case $( expr $(expr $fac_num % 100) / 10 ) in 142 | 1) echo "You belong to group 1" ;; 143 | 2) echo "You belong to group 2" ;; 144 | 3) echo "You belong to group 3" ;; 145 | 4) echo "You belong to group 4" ;; 146 | *) echo "You don't belong to any group" ;; 147 | esac 148 | 149 | 6. 150 | Напишете командна процедура, която получава параметри на командния си ред списък с имена на файлове. 151 | За всеки обикновен файл от списъка, който съществува извежда на стандартния изход по един ред съдържащ първите 2 букви и дължината на името му. 152 | Имената на несъществуващите файлове от списъка, добавя във файла, чието име е прочетено от стандартния вход. 153 | 154 | #това е, заради края на задачата. 155 | echo "Enter file at which all non-existing file names will be placed." 156 | read file_with_filenames 157 | 158 | for i in $* 159 | do 160 | if [ -f $i ] 161 | then 162 | echo "File $i first two letters: $(expr substr $i 1 2), and has total name length $(expr length $i)" 163 | #приемаме че входните параметри са само файлове.... за да не правим проверка за символна връзка, директория, character device или block device 164 | else 165 | echo $i >> $file_with_filesnames 166 | fi 167 | 168 | done 169 | 170 | 7. 171 | Да се състави командна процедура, която получава в командния ред при стартиране два параметъра - първият, от които е символен низ, а вторият - число. 172 | Ако в нашата home директория съществува директория с име съвпадащо с низа, процедурата извежда на стандартния изход имената на всички обикновени файлове в нея, които имат размер по-голям от подаденото число. 173 | В противен случай (ако не съществува такава директория) на стандартния изход се извежда подходящо съобщение. 174 | 175 | #проверка, дали в нашата home директория, съществува директория, името на която съвпада с първия позиционен параметър 176 | if [ -d ~/$1 ] 177 | then 178 | #ако съществува такава директория.. обхождаме я и извеждаме всички имена на обикновени файлове с размер по-голям от 2рия позиционен параметър 179 | for i in $(ls ~/$1) 180 | do 181 | if [ -f ~/$1/$i ] -a [ $(wc -c < ~/$1/$i) -gt $2 ] 182 | then 183 | echo "$i" 184 | fi 185 | done 186 | else 187 | echo "Directory with such name does not exist in your home directory! " 188 | fi 189 | -------------------------------------------------------------------------------- /exer09.txt: -------------------------------------------------------------------------------- 1 | Разписани упражнения по Операционни системи от Йордан Бабуков. 2 | 3 | Операционни системи, упражнение 8. 4 | 5 | Cистемни примитиви на C за работа с файлове 6 | 7 | 1) 8 | int open(const char *pathname, int flag[| more flags] ); 9 | първият аргумент е име на файл, който искаме да поставим в режим flag. 10 | 11 | flags: 12 | О_RDONLY -> отваря файл pathname в режим на четене 13 | O_WRONLY -> отваря файл pathname в режим на писане 14 | O_RDWR -> отваря файл pathname в режим на писане и четене 15 | O_TRUNC -> отваря файл pathname, като му занулява съдържанието 16 | O_APPEND -> отваря файл pathname, като поставя указател към края на съдържанието на файла. 17 | O_CREAT -> създава нов файл с име pathname, ако не съществува. 18 | 19 | 2) 20 | int close(int fd); 21 | затваря новозаделеният файлов дескриптор от open() към файла. 22 | 23 | 3) 24 | ssize_t read(int fd, void *buf, size_t count); 25 | Първият аргумент е файлов дескриптор към файл, който трябва да е отворен за четене 26 | След което прочитаме count (третият аргумент) на брой символа, 27 | които се запаметяват временно в buf (вторият аргумент) 28 | 29 | 4) 30 | ssize_t write(int fd, const void *buf, size_t count); 31 | Първият аргумент е файлов дескриптор към файл, който трябва да е отворен за писане 32 | След което подаваме count (третият аргумент) на брой символа за запис 33 | Които са предварително запазени в buf (вторият аргумент) 34 | 35 | *Най-често размера на буферите за четене и писане са с еднакви 36 | 37 | Пример и обяснения - директно върху задачи: 38 | Задача 1: 39 | 40 | Копирайте съдържанието на файл1 във файл2 41 | ]$ vi task1.c 42 | //копирайте съдържанието на файл1 във файл2 43 | #include //библиотека необходима за изпълнение на open 44 | #include //библиотека необходима за изпълнение на exit() 45 | 46 | //argc е брой подадени входни параметри (в случая нула) 47 | //argv се асоциира със стойностите на подадените входни параметри 48 | //пример за достъп до 1-вия подаден входен параметър: argv[1] и тн 49 | //пример за обхождане на всички подадени входни параметри: argv[*] 50 | main(int argc, char* argv[]){ 51 | int fd1; //ще бъде асоцииран с първия файл от който ще четем 52 | int fd2; //ще бъде асицииран с втория файл, в който ще пишем 53 | char c; //това ще е текущо прочетения символ от първия файл, който ще записваме във втория файл. 54 | 55 | //системните примитив на C връщат код -1 при грешка и > от -1 при успех 56 | //Изключително желателно е да се прави проверка, дали файлът е отворен успешно 57 | //open връща цялочислена стойност, която служи за файлов дескриптор към файла 58 | //след успешно изпълнение на open, ще работим с файловия дескриптор, а не с името на файла! 59 | if ( ( fd1 = open("/home/jbabukov/file_to_read", O_RDONLY) ) == -1 ){ 60 | //двойката в долния ред се асоциира със стандартния изход за грешки, ако беше 1, щеше да се асоциира със стандартния изход 61 | write(2, "File failed to open in read mode\n", 33); 62 | exit(-1); 63 | } 64 | 65 | if ( ( fd2 = open("/home/jbabukov/file_to_write", O_CREAT|O_WRONLY) ) == -1 ){ 66 | write(2, "File failed to open in write mode\n", 33); 67 | exit(-1); 68 | } 69 | 70 | //прочитане символ по символ първия файл и като прочетем символ го записваме във втория. 71 | while ( read(fd1, &c, 1) ){ 72 | write(fd2, &c, 1); 73 | } 74 | 75 | //затваряме заделените файлови дескриптори 76 | close(fd1); 77 | close(fd2); 78 | } 79 | 80 | Остава да си компилираме творението: 81 | 82 | cc task1.c -o task1 83 | сега го стартираме и се наслаждаваме на резултатите: 84 | ./task1 85 | 86 | Задача 2: 87 | Реализирайте команда head без опции (т.е. винаги да извежда на стандартния изход само първите 10 реда от съдържанието на файл подаден като първи параматър) 88 | 89 | cat task2.c 90 | #include 91 | #include 92 | #include 93 | 94 | main(int argc, char* argv[]){ 95 | int fd1; 96 | int i=0; //броят на символи за нов редове 97 | char c; 98 | 99 | if ( ( fd1 = open(argv[1], O_RDONLY) ) == -1 ){ 100 | write(2, "File failed to open in read mode\n", 33); 101 | exit(-1); 102 | } 103 | 104 | while ( read(fd1, &c, 1) ){ 105 | if( c == '\n' ){ 106 | i=i+1; 107 | } 108 | 109 | //извеждаме на стандартния изход прочетения символ 110 | write(1, &c, 1); 111 | 112 | //при достигане на 10ти символ за нов ред, приключвамe изпълнението на програмата. 113 | if( i == 10 ){ 114 | close(fd1); 115 | exit(0); 116 | } 117 | } 118 | close(fd1); 119 | } 120 | 121 | Koмпилираме: 122 | cc task2.c -o task2 123 | 124 | и стартираме: 125 | ./task2 task1.c 126 | 127 | Задача 3: 128 | Реализирайте команда wc 129 | 130 | Опростено на максимум решение на задача 3: 131 | //Реализирайте команда wc, с един аргумент подаден като входен параметър 132 | //По-долу е предоставен вариант на решение на задачата без проверки (във възможно най-опростен вариант) 133 | #include 134 | #include 135 | #include 136 | 137 | main (int argc, char* argv[]){ 138 | int fd1; 139 | char c; //променлива, чрез която ще обхождам съдържанието на файла подаден като първи входен параметър 140 | int lines=0, words=0, chars=0; 141 | 142 | fd1 = open(argv[1], O_RDONLY); 143 | //Обхождам файла символ по символ и следя за разни символи, при които трябва да предприема някакво действие. 144 | //проверка дали успешно съм достъпил символ от съдържанието на файла. 145 | while( read(fd1, &c, 1) ){ 146 | if(c=='\n'){ 147 | lines++; 148 | words++; 149 | } 150 | 151 | if(c==' '){ 152 | words++; 153 | } 154 | 155 | chars++; 156 | 157 | } 158 | 159 | printf("File %s has:\n%d number of lines.\n%d number of words.\n%d number of chars.\n", argv[1], lines, words, chars); 160 | close(fd1); 161 | } 162 | 163 | 164 | По-истинско решение на задача 3: 165 | 166 | //Реализирайте команда wc, с един аргумент подаден като входен параметър 167 | //По-долу е предоставен вариант на решение на задачата включващ проверки. 168 | #include 169 | #include 170 | #include 171 | 172 | main (int argc, char* argv[]){ 173 | int fd1; 174 | char c; //променлива, чрез която ще обхождам съдържанието на файла подаден като първи входен параметър 175 | int lines=0, words=0, chars=0; 176 | ssize_t read_size; // Променлива, чрез която ще следя дали не настъпва грешка повреме на обхождането на съдържанието на файла. 177 | //Променливата е тип ssize_t, тъй като функцията read връща стойност тип ssize_t. 178 | 179 | /* 180 | проверка дали е подаден точно един входен параметър 181 | 2 означава че имаме точно един входен параметър (другият е името на самата команда) 182 | Пример: ./wc wc.c 183 | Първят е "wc", вторият "wc.c" 184 | */ 185 | 186 | if (argc != 2){ 187 | write(2,"Йоу, wrong number of arguments!\n", 32); 188 | exit(1); 189 | } 190 | 191 | /* 192 | Oтваряне на файлa подаден като първи входен параметър в режим на четене 193 | и проверка дали операцията се е осъществила успешно. 194 | */ 195 | if ( (fd1 = open(argv[1], O_RDONLY)) == -1 ){ 196 | write(2, "Operation open failed!", 27); 197 | exit(1); 198 | } 199 | 200 | //Обхождаме файла символ по символ и следим за разни символи, при които трябва да предприемем някакво действие. 201 | //проверка дали успешно сме достъпили символ от съдържанието на файла. 202 | while( ( read_size=read(fd1, &c, 1) ) > 0 ){ 203 | if(c=='\n'){ 204 | lines++; 205 | words++; 206 | } 207 | 208 | if(c==' '){ 209 | words++; 210 | } 211 | 212 | chars++; 213 | } 214 | 215 | printf("File %s has:\n%d number of lines.\n%d number of words.\n%d number of chars.\n", argv[1], lines, words, chars); 216 | close(fd1); 217 | } 218 | 219 | -------------------------------------------------------------------------------- /exer10.txt: -------------------------------------------------------------------------------- 1 | Задача 1: 2 | Реализирайте команда swap, разменяща съдържанието на два файла, подадени като входни параметри. 3 | 4 | Задача 2: 5 | Реализирайте команда cp, работеща с два аргумента, подадени като входни параметри. 6 | 7 | Задача 3: 8 | Реализирайте команда cat, работеща с произволен брой подадени входни параметри. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Решение на задача 1: 30 | //Реализирайте команда swap, разменяща 31 | //съдържанието на два файла, подадени като 32 | //входни параметри. 33 | //Приемаме, че двата файла имат еднакъв брой символи. 34 | 35 | //Примерно решение, когато 2та файла имат различен размер, е следното: 36 | //Проверяваме (обхождаме и в променлива брой символите) кой файл има по-голямо съдържание и него преливаме върху файла с по-малко такова. 37 | 38 | #include //библиотека, съдържаща реализиция на функции open, read, write, .. 39 | #include //библиотека, съдържаща реализация на функция exit 40 | #include //библиотека, съдържаща реализация на фунцкия printf 41 | 42 | main (int argc, char* argv[]){ 43 | int fd1, fd2, fd3; //третият файлов дескриптор асоциираме с третия, помощен файл. 44 | char c[4096]; //променлива, чрез която ще обхождамe съдържанието на файлoвете поблоково (четене и писане от/в файл/ове е препоръчително да се извършва на порции (на блокове от данни, а не символ по символ). Така става по-ефективно.) 45 | //пп: в задачата за реализация на команда wc, нямаше как да избегнем посимволното обхождане. 46 | 47 | ssize_t read_size; // Променлива, чрез която ще следим дали не настъпва грешка повреме на обхождането на съдържанието на файловете. 48 | 49 | /* 50 | проверка дали сa подадени точно два входни параметъра 51 | */ 52 | if (argc != 3){ 53 | write(2,"Йоу, wrong number of arguments!\n", 32); 54 | exit(1); 55 | } 56 | 57 | /* 58 | Oтваряне на файлa подаден като първи входен параметър едновременно в режим на четене и писане 59 | и проверка дали операцията се е осъществила успешно. 60 | */ 61 | if ( (fd1 = open(argv[1], O_RDWR)) == -1 ){ 62 | write(2, "Operation open failed!", 27); 63 | exit(1); 64 | } 65 | 66 | if ( (fd2 = open(argv[2], O_RDWR)) == -1 ){ 67 | write(2, "Operation open failed!", 27); 68 | exit(1); 69 | } 70 | 71 | //Създаване на нов помощен файл, чрез който ще си решим задачата по-лесно. 72 | if ( (fd3 = open("my_temp_file", O_CREAT|O_RDWR|O_TRUNC)) == -1 ){ 73 | write(2, "Operation open failed!", 27); 74 | exit(1); 75 | } 76 | 77 | //проверка дали успешно сме достъпили блок от символи от съдържанието на файла. 78 | while( ( read_size=read(fd1, &c, sizeof(c)) ) > 0 ){ 79 | //some debugging 80 | //printf("%s", c); 81 | //printf("%d", read_size); 82 | if ( write(fd3, &c, read_size) != read_size ){ 83 | write(2, "Error while writing occured!", 28); 84 | exit(1); 85 | } 86 | } 87 | 88 | //Тъй като вече един път сме обходили файла подаден като първи входен параметър, трябва да се погрижим за указателя. 89 | lseek(fd1,0,SEEK_SET); 90 | while( ( read_size=read(fd2, &c, sizeof(c)) ) > 0 ){ 91 | if ( write(fd1, &c, read_size) != read_size ){ 92 | write(2, "Error while writing occured!", 28); 93 | exit(1); 94 | } 95 | } 96 | 97 | lseek(fd2, 0, SEEK_SET); 98 | lseek(fd3, 0, SEEK_SET); 99 | while( ( read_size=read(fd3, &c, sizeof(c)) ) > 0 ){ 100 | if ( write(fd2, &c, read_size) != read_size ){ 101 | write(2, "Error while writing occured!", 28); 102 | exit(1); 103 | } 104 | } 105 | close(fd1); 106 | close(fd2); 107 | close(fd3); 108 | } 109 | 110 | 111 | Решение на задача 2: 112 | //Задача 2: 113 | //Реализирайте команда cp, работеща с два аргумента, подадени като входни параметри. 114 | 115 | #include 116 | #include 117 | #include 118 | main (int argc, char* argv[]){ 119 | int fd1, fd2; 120 | char c; //променлива, чрез която ще обхождаме съдържанието на файла подаден като първи входен параметър 121 | ssize_t read_size; // Променлива, чрез която ще следим дали не настъпва грешка повреме на обхождането на съдържанието на файла. 122 | //Променливата е тип ssize_t, тъй като функцията read връща стойност тип ssize_t. 123 | 124 | if (argc != 3){ 125 | write(2,"Йоу, wrong number of arguments!\n", 32); 126 | exit(1); 127 | } 128 | 129 | /* 130 | Oтваряне на файлът подаден като първи входен параметър в режим на четене 131 | и проверка дали операцията се е осъществила успешно. 132 | */ 133 | if ( (fd1 = open(argv[1], O_RDONLY)) == -1 ){ 134 | write(2, "Operation open failed!", 27); 135 | exit(1); 136 | } 137 | 138 | /* 139 | Oтваряне на файл в режим на писане, ако не съществува го създава, ако съществува му зануляваме съдържанието. 140 | */ 141 | 142 | if ( (fd2 = open(argv[2], O_CREAT|O_WRONLY|O_TRUNC)) == -1 ){ 143 | write(2, "Operation open failed!", 27); 144 | exit(1); 145 | } 146 | 147 | //каквото прочетем от първия файл го записваме във втория файл 148 | //проверка дали успешно сме достъпили символ от съдържанието на файла. 149 | while( ( read_size=read(fd1, &c, 1) ) > 0 ){ 150 | if ( write(fd2, &c, read_size) != read_size ){ 151 | write(2, "Error while writing occured!", 28); 152 | exit(1); 153 | } 154 | } 155 | close(fd1); 156 | close(fd2); 157 | } 158 | 159 | 160 | Решение на задача 3: 161 | //Задача 3: 162 | //Реализирайте команда cat, работеща с произволен брой подадени входни параметри. 163 | 164 | #include 165 | #include 166 | #include 167 | main (int argc, char* argv[]){ 168 | int fd1; 169 | int i; 170 | char c; //променлива, чрез която ще обхождам съдържанието на файла подаден като първи входен параметър 171 | ssize_t read_size; // Променлива, чрез която ще следим дали не настъпва грешка повреме на обхождането на съдържанието на файла. 172 | //Променливата е тип ssize_t, тъй като функцията read връща стойност тип ssize_t. 173 | 174 | /* 175 | проверка дали е подаден поне един входен параметър 176 | */ 177 | if (argc < 2){ 178 | write(2,"Йоу, wrong number of arguments!\n", 32); 179 | exit(1); 180 | } 181 | 182 | /* 183 | Обхождане на входните параметри и последователното им отваряне в режим на четене 184 | както и последвала проверка дали операцията се е осъществила успешно. 185 | */ 186 | for(i=1;i<=argc;i++){ 187 | if ( (fd1 = open(argv[i], O_RDONLY)) == -1 ){ 188 | write(2, "Operation open failed!", 27); 189 | exit(1); 190 | } 191 | 192 | //Обхождаме файлът, символ по символ 193 | //проверка дали успешно смe достъпили символ от съдържанието на файла. 194 | while( ( read_size=read(fd1, &c, 1) ) > 0 ){ 195 | if ( write(1, &c, read_size) != read_size ){ 196 | write(2, "Error while writing occured!", 28); 197 | exit(1); 198 | } 199 | } 200 | close(fd1); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /exer12.txt: -------------------------------------------------------------------------------- 1 | Разписани упражнения по Операционни системи от Йордан Бабуков. 2 | 3 | Операционни системи, упражнение 11 4 | 5 | Cистемни примитиви за работа с процеси под C 6 | 7 | Кратък увод в тема: какво са процесите? 8 | Днешните операционни системи, такива каквито ги познаваме, са многозадачни. 9 | Това означава, че успяват да се справят с изпълнението на много процеси "наведнъж", например докато работим с 10 | мишката може да слушаме музика заедно с това да гледаме видео клип, заедно с това на заден фон (background) да сме 11 | стартирали програма за съпоставяне на нуклеотидни прoчити от генома на пшеницата и още куп други странни неща. 12 | Всяко едно от изброените събития е свързано с даден процес изпълняващ се на нашия компютър. 13 | Тези процеси се изпълняват от хардуерна компонента, наречена.. процесор. 14 | 15 | Как всъщност се обработват "наведнъж" стартираните процеси? 16 | В най-простия случай процесорът е един, с една нишка. т.е. няма как да обработи повече от един процес в даден 17 | момент. Но... той постига заблудата паралелизъм, на която ние се наслаждаваме, като обработва процесите 18 | последователно един по един, но ги редува толкова бързо че ние не разбираме, за настъпването на смяната между 19 | различните процеси мишка-музика-клип-съпоставяне-мишка-музика-клип-съпоставяне и тн. 20 | 21 | В общия случай имаме около 60-100 процеса, които трябва бъдат изпълнявани на този редуващ се принцип. 22 | 23 | Как се определя кой процес, колко време да бъде изпълняван? 24 | Процесите се изпълняват от процесора на конкурентен принцип. Всеки един от тях се бори за процесорно време. 25 | Тъй като при тази борба, някой процес може да стане прекалено алчен за процесорно време и да заеме целия ресурс, 26 | съществува механизъм в ядрото нареден scheduler, който ни идва на помощ. 27 | Този scheduler указва на всеки процес, колко процесорно време да му бъде заделено(например два процесорни такта). 28 | Това става чрез определяне на nice levels за процесите. 29 | 30 | Пример: ако музикалният player е с най-висок приоритет, то при мърдане на мишката, тя ще насича, тъй като процеса 31 | свързан с нея, ще трябва да изчака да му дойде реда за изпълнение от процесора. 32 | Обратното: ако мишката е с най-висок приоритет, при събитие свързано с нея, музиката ни ще започва да прекъсва. 33 | 34 | Затова гоним златната среда. Оптималният компромисен вариант, така че всичко да върви без ние да усещаме прекъсване. 35 | Една от меките на Linux се крие точно в този scheduler и как той разпределя процесорното време. Може и ние 36 | самите да си играем (внимателно) с nice level-ите на процесите. 37 | 38 | 1) 39 | int execl(const char *path, const char *arg, ..., 0); 40 | първият аргумент е пълно име на бинарен файл (команда), който искаме да изпълним 41 | вторият аргумент е името на самата команда 42 | Следват N на брой аргументи - опции към командата, която искаме да изпълним 43 | Последният аргумент е 0, указва край на въвеждане на аргументи. 44 | 45 | Пример: 46 | искамe да изпълним команда ls, с опция -l 47 | execl("/bin/ls", "ls", "-l", 0); 48 | 49 | Особености (които трябва да знаем): 50 | При изпълнение на системния примитив execl се сменя образа на процеса, който я е изпълнил. 51 | т.е. изпълни ли се execl -> сменя се текущата програма с програмата ls и връщане назад, няма. 52 | Oще примери - най-долу директно в задача. 53 | 54 | Особености (които не е нужно да знаем): 55 | Първият аргумент на функцията е бинарния файл, който искаме да изпълним. 56 | Вторият аргумент е какво ще бъде името на стартирания процес, което може да видим с команда ps. 57 | 58 | 2) 59 | int execlp(const char *file, const char *arg, ..., 0); 60 | Аналогично на execl, но първият аргумент е собствено име на командата ( не пълният път до нея ) 61 | 62 | Пример: 63 | искам да изпълня команда dd с две опции if=/dev/uradom и of=/etc/ (Внимание: не я пробвайте!) 64 | execlp("dd", "dd", "if=/dev/uradom", "of=/etc/", 0); 65 | 66 | 3) 67 | exit(5); 68 | Процес прекратява собственото си изпълнение и връща код на завършване. 69 | 70 | 4) 71 | fork(); 72 | Създава нов процес(дете) 73 | Ново- създаденият процес е почти идентичен на бащиния (този, който го е създал). 74 | Защо почти? ами различават се например по PID (process ID, всеки процес има уникален PID) 75 | Тъй като са почти идентични процесите, трябва някак да ги различаваме. 76 | Различаваме ги по това какво връща fork(). 77 | fork() връща 0 при детето и > 0 при бащата. 78 | 79 | 5) 80 | wait(&status); 81 | Тъй като процесите се изпълняват на конкурентен принцип, бащата може да завърши изпълнението си преди детето. 82 | Но ако искаме изхода от детето да го ползваме в бащата, то трябва да укажем на бащата да изчака детето, да завърши. 83 | Това става чрез системен примитив wait(). 84 | Той следи за промяна на статуса на детето: 85 | Например настъпване на терминиране на процеса или на пауза или на събуждане от пауза. 86 | 87 | 6) 88 | get_pid(); -> връща PID на процеса, който изпълнява командата. 89 | get_ppid(); -> връща PID на бащата на процеса, който изпълнява командата. 90 | 91 | Задача 1: 92 | Да се напише програма на C, която изпълнява команда date. 93 | ]$ vi task1.c 94 | #include //printf 95 | #include //execl, execlp 96 | #include // fork, getpid, getppid 97 | #include // wait 98 | #include // exit 99 | 100 | main (){ 101 | //Системните примитиви връщат -1 при грешка и > -1 при успех. 102 | if ( execl("/bin/date", "date", 0) == -1 ){ 103 | exit(99); 104 | } 105 | else{ 106 | //След изпълнение на execl настъпва смяна на образа на текущия процес (самата програма, която пишем сега) 107 | //и в последствие ще стартираме с образа на команда date и долният ред няма да бъде изпълнен никога! 108 | printf("If Reni only knew that I know that Miro will know what Eli knows now..\n"); 109 | exit(0); 110 | } 111 | } 112 | 113 | Остава да си компилираме творението: 114 | cc task1.c -o task1 115 | сега го стартираме и се наслаждаваме на резултатите: 116 | ./task1 117 | 118 | Задача 2: 119 | Да се напише програма на C, която изпълнява команда ls с точно един аргумент 120 | 121 | #include //printf 122 | #include //execl, execlp 123 | #include // fork, getpid, getppid 124 | #include // wait 125 | #include // exit 126 | 127 | main(int argc, char* argv[]){ 128 | if (argc == 2){ 129 | //debugging 130 | // printf("%s", argv[1]); 131 | if ( execlp("/bin/ls", "ls", argv[1], 0) == -1 ){ 132 | exit(99); 133 | } 134 | else{ 135 | printf("Will this line ever be printed? Why?\n"); 136 | exit(0); 137 | } 138 | } 139 | else{ 140 | printf("Number of args is %d, enter exactly one.", argc); 141 | exit(0); 142 | } 143 | } 144 | 145 | Задача 3: 146 | Да се напише програма на C, която поставя Миро в режим на спане за 60 секунди. 147 | 148 | #include //printf 149 | #include //execl, execlp 150 | #include // fork, getpid, getppid 151 | #include // wait 152 | #include // exit 153 | 154 | main(int argc, char* argv[]){ 155 | if (argc == 2){ 156 | //debugging 157 | // printf("%s", argv[1]); 158 | if ( execlp("/bin/sleep", "Miro", "60", 0) == -1 ){ 159 | exit(99); 160 | } 161 | else{ 162 | printf("Will this line ever be printed? Why?\n"); 163 | exit(0); 164 | } 165 | } 166 | else{ 167 | printf("Number of args is %d, enter exactly one.", argc); 168 | exit(0); 169 | } 170 | } 171 | 172 | ps aux | grep -i miro 173 | 174 | Задача 4: 175 | Да се напише програма на C, която създава процес дете и демонстрира принцина на конкурентност при процесите. 176 | 177 | #include //printf 178 | #include //execl, execlp 179 | #include // fork, getpid, getppid 180 | #include // wait 181 | #include // exit 182 | 183 | main(int argc, char* argv[]) { 184 | int i,j; 185 | 186 | if( fork() > 0 ){ 187 | //father body 188 | for( i=0; i<1000000; i++) write(1,"i'm your father\n", 16); 189 | }else{ 190 | //child body 191 | for( i=0; i<1000000; i++) write(1,"i'm your son\n", 13); 192 | } 193 | } 194 | 195 | Задача 5: 196 | Да се напише програма на C, която е аналогична на горния пример, но принуждава бащата да изчака сина си да завърши, преди да започне собственото си изпълнение. 197 | 198 | #include //execl, execlp 199 | #include // fork, getpid, getppid 200 | #include // wait 201 | #include // exit 202 | 203 | main(int argc, char* argv[]) { 204 | int i,j; 205 | int status; 206 | 207 | if( fork() > 0 ){ 208 | //father body 209 | wait(&status); 210 | for( i=0; i<1000000; i++) write(1,"i'm your father\n", 16); 211 | }else{ 212 | //child body 213 | for( i=0; i<1000000; i++) write(1,"i'm your son\n", 13); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /exer13-K3-preparation-tasks.txt: -------------------------------------------------------------------------------- 1 | Задача 1: 2 | Нека Йордан (накратко Данчо) е станал световно известна личност (някак си) и всеки му знае името, но е станал кофти известена личност, толкова кофти, че буквите от краткото му име вече са забранени за изписване и на тяхно място изписваме символа * (астериск, звездичка). 3 | Коригирайте нежеланите букви във файла подаден като първи входен параметър чрез системни примитиви за работа с файлове под C. 4 | 5 | Примерно съдържание на файла: 6 | 7 | s61xxx:x:1129:502:Danail Benov, SI, kx, gx:/home/SI/s61xxx:/bin/bash 8 | s61xxx:x:1158:502:Diqn Doichev, SI, kx, gx:/home/SI/s61xxx:/bin/bash 9 | s61xxx:x:1126:502:Dancho Danchov, SI, kx, gx:/home/SI/s61xxx:/bin/bash 10 | s61xxx:x:1159:502:Jordan Stoychkov, SI, kx, gx:/home/SI/s61xxx:/bin/bash 11 | s61xxx:x:1123:502:Martin Angelow, SI, kx, gx:/home/SI/forgot_my_password:/bin/bash 12 | s61xxx:x:1125:502:Stanimir Dimitrov, SI, kx, gx:/home/SI/s61xxx:/bin/bash 13 | s61xxx:x:1157:502:Vladimir Genchev, SI, kx, gx:/home/SI/s61xxx:/bin/bash 14 | s61xxx:x:1121:502:Miroslav Nikolov, SI, kx, gx:/home/SI/s61xxx:/bin/bash 15 | 16 | //Решение: 17 | #include 18 | #include 19 | #include 20 | 21 | main(int argc, char* argv[]){ 22 | int fd1,fd2; 23 | char c; 24 | 25 | if ( (fd1=open(argv[1], O_RDONLY,0400)) == -1 ){ 26 | write(2, "error", 6); 27 | exit(-1); 28 | } 29 | 30 | if ( (fd2=open("file-k4-output", O_CREAT|O_TRUNC|O_WRONLY)) == -1 ){ 31 | write(2, "error", 6); 32 | exit(-1); 33 | } 34 | 35 | while( read(fd1, &c, 1) ){ 36 | write(1,&c,1); 37 | if(c=='D' || c=='a' || c=='n' || c=='c' || c=='h' || c=='o') c='*'; 38 | write(fd2, &c, 1); 39 | } 40 | 41 | close(fd1); 42 | close(fd2); 43 | } 44 | 45 | Задача 2: 46 | Условие на задачата с човешки думи: 47 | Баща се прибира от работа и заварва сина си да играе на компютъра, вместо да си пише домашните. 48 | Бащата се намръщва и му казва, че няма да излезе от стаята, докато не си напише домашното по литература, 49 | което представлява препис на страница 56 и страница 57 от учебника в тетрадката. 50 | 51 | Условие на задачата с нечовешки думи: 52 | Напишете командна процедура на C, приемаща два аргумента на командния си ред. 53 | Нека програмата създава нов процес, като заставя процесът баща да изчака завършването на процеса син. 54 | Процесът син има за задача да отвори в режим на четене файл, подаден като първи входен аргумент на програмата. 55 | След което започва да прелива съдържанието на отворения файл за четене в друг файл, подаден ѝ като втори аргумент, който трябва да отвори в 56 | режим на писане (ако файлът отворен в режим на писане съществува, да добавя съдържанието към края на файла. Ако 57 | несъществува, да го създаде). 58 | Когато приключи с преливането на съдържанието на файловете, процесът син трябва да изведе на стaндартния изход 59 | текста "Father pid_of_father, i'm done!" и да изпълни команда ls, с което да потвърди, че наистина е прелял 60 | информацията. 61 | Процесът баща проверява дали процеса син е приключил успешно изпълнението на задачата и ако е: извежда на 62 | стандартния изход "Very well, pid_of_child!". 63 | 64 | 65 | Решение: 66 | #include //printf 67 | #include //execl, execlp 68 | #include // fork, getpid, getppid 69 | #include // wait 70 | #include // exit 71 | #include 72 | 73 | main(int argc, char* argv[]){ 74 | int child, status, fd1, fd2; 75 | char c; 76 | if ( (child = fork()) > 0 ){ 77 | wait(&status); 78 | printf("Very well, my %d!\nSee You!\n", child); 79 | } 80 | else{ 81 | fd1=open(argv[1],O_RDONLY); 82 | fd2=open(argv[2],O_WRONLY|O_CREAT|O_APPEND); 83 | while (read(fd1,&c,1)) write(fd2,&c,1); 84 | printf("Father %d, i'm done!\n", getppid()); 85 | execlp("ls", "ls", 0); 86 | } 87 | close(fd1); 88 | close(fd2); 89 | } 90 | 91 | Задача 3: 92 | Напишете командна процедура на C, която създава нов процес, който отваря два файла за писане, ако файловете съществуват ги занулява, ако несъществуват ги създава. 93 | Нека единият файл е с име съвпадащо с името на първия аргумент подаден на програмата, след което записва в този файл текста "Switch1 Switch2 Switch3 " без кавичките. 94 | Нека вторият файл е с име съвпадащо с името на втория аргумент подаден на програмата, като в него добавя следния текст: 95 | eтаж 1, ФМИ. 96 | eтаж 2, ФМИ. 97 | eтаж 3, ФМИ. 98 | Процесът баща има за задача да изведе на стандартния изход текущата дата, последвана от следния текст извлечен от файловете подадени като входни аргументи: 99 | Switch1 етаж 1, ФМИ. 100 | Switch2 етаж 2, ФМИ. 101 | Switch3 етаж 3, ФМИ. 102 | 103 | Решение: 104 | #include 105 | #include 106 | #include 107 | #include 108 | 109 | main (int argc, char* argv[]){ 110 | int status; 111 | if ( fork() == 0 ){ 112 | int fd1, fd2; 113 | char c; 114 | if ((fd1 = open(argv[1], O_WRONLY| O_TRUNC|O_CREAT, 0644)) == -1){ 115 | write(2, "Cannot open file", 16); 116 | exit(-1); 117 | } 118 | write (fd1, "Switch1 Switch2 Switch3 ", 24); 119 | if(( fd2 = open(argv[2], O_WRONLY|O_TRUNC|O_CREAT, 0644)) == -1){ 120 | write(2, "Cannot open file", 16); 121 | exit(-1); 122 | } 123 | write(fd2, "етаж 1, ФМИ.\nетаж 2, ФМИ.\nетаж 3, ФМИ.\n", 60); 124 | close(fd1); 125 | close(fd2); 126 | }else{ 127 | wait(&status); 128 | if ( fork() == 0 ){ 129 | if ( execlp("date", "date", 0) == -1){ 130 | write(2, "Error\n", 6); 131 | exit(-1); 132 | } 133 | }else{ 134 | wait(&status); 135 | int fd1, fd2; 136 | char c; 137 | if ((fd1 = open(argv[1], O_RDONLY, 0644)) == -1){ 138 | write(2, "Cannot open file\n", 17); 139 | exit(-1); 140 | } 141 | 142 | if(( fd2 = open(argv[2], O_RDONLY, 0644)) == -1){ 143 | write(2, "Cannot open file\n", 10); 144 | exit(-1); 145 | } 146 | while (read(fd1, &c, 1)){ 147 | if (c != ' '){ 148 | write(1, &c, 1); 149 | }else{ 150 | char replacement = ' '; 151 | write(1, &replacement, 1); 152 | while(read(fd2, &c, 1)){ 153 | if (c != '\n'){ 154 | write(1, &c, 1); 155 | }else{ 156 | char replacement2 = '\n'; 157 | write(1, &replacement2, 1); 158 | break; 159 | }//else 160 | }//while 161 | }//else 162 | }//while 163 | }//else (father second time) 164 | }//else (father first time) 165 | }//main 166 | -------------------------------------------------------------------------------- /exer13.txt: -------------------------------------------------------------------------------- 1 | Операционни системи, упражнение 13 2 | 3 | Cистемни примитиви за работа с процеси и работа с файлове под C 4 | 5 | Функции, които ще трябва да знаете и ползвате: 6 | open() 7 | read() 8 | write() 9 | close() 10 | fork() 11 | wait() 12 | execl(); 13 | execlp(); 14 | exit(); 15 | getpid(); 16 | getppid(); 17 | 18 | Задача 1: 19 | 1. Да се напише програма на С, която получава като параметър - команда (без опции). При успешното на командата подадена като първи аргуемнт, нека програмата извежда на стандартния изход името на изпълнената команда. 20 | 21 | Решение: 22 | #include //printf 23 | #include //execl, execlp 24 | #include // fork, getpid, getppid 25 | #include // wait 26 | #include // exit 27 | 28 | main(int argc, char* argv[]){ 29 | int status; //променлива ползваща се от wait() и съдържаща кода на завършване на процеса дете. 30 | //fork връща 0 при детето и > 0 при бащата. По този начин различаваме кой процес, кой е. 31 | 32 | if( fork() > 0 ){ 33 | //тяло на бащата > 0 34 | wait(&status); //инструктираме процесът баща да изчака завършването на процеса син. 35 | //долните два реда ще се изпълнят чак след като сина завърши. 36 | printf("Name of executed command is: %s\n", argv[1]); 37 | exit(0); 38 | } 39 | else{ 40 | //тяло на сина = 0 41 | //чрез execlp изпълняваме процес, с цената на смяна на образа на този, който го 42 | изпълнява. 43 | if ( execlp(argv[1], argv[1], 0) == -1 ){ 44 | exit(-1); 45 | } 46 | else{ 47 | //кодът след смяната на образа на процеса никога няма да бъде изпълнен. 48 | printf("Will this line ever be printed? Why?\n"); 49 | } 50 | } 51 | } 52 | 53 | Задача 2: 54 | Да се напише програма на С, която получава като параметри три команди (без опции), след което ги изпълнява последователно, 55 | като изчаква края на всяка и извежда на стандартния изход номера на завършилия процес, както и неговият код на завършване. 56 | 57 | Решение: 58 | #include //printf 59 | #include //execl, execlp 60 | #include // fork, getpid, getppid 61 | #include // wait 62 | #include // exit 63 | 64 | /* 65 | За по-добра четимост на кода са премахнати коментарите от миналата задача, тъй като са идентични. 66 | */ 67 | 68 | main(int argc, char* argv[]){ 69 | int status; // съдържа код на завършване на процес дете. 70 | int pid_of_child; // в случая, когато fork връща стойност > 0, тази стойност е pid-ът на процеса син. При "форкване" пазим тази стойност в променлива с интуитивно име "pid_of_child" 71 | int i; //правим for цикъл, който обхожда входните параметри и ги изпълнява последователно. 72 | 73 | for (i=1; i<4; i++){ 74 | //тяло на бащата > 0 75 | //тук се случва врътката с пазенето на pid-a на процеса син в променлива 76 | if( ( pid_of_child = fork() ) > 0 ){ 77 | wait(&status); 78 | 79 | //долните редове ще се изпълнят чак, след като сина завърши. 80 | printf("Pid of first child is: %d, %d\n", pid_of_child, getpid() ); 81 | printf("Exit code of child with pid %d is: %d\n", pid_of_child, status); 82 | } 83 | //тяло на сина = 0 84 | else{ 85 | if ( execlp(argv[i], argv[i], 0) == -1 ){ 86 | exit(-1); 87 | } 88 | else{ 89 | printf("Will this line ever be printed? Why?\n"); 90 | } 91 | } 92 | } 93 | } 94 | 95 | 96 | 3. Да се напише програма на С, която получава като параметър име на файл. Създава процес син, който записва стрингът "Hello Tux!" в подадения файл (ако файлът не съществува, го създава, в противен случай го занулява), след което процесът родител прочита записаното във файла съдържание и го извежда на стандартния изход, добавяйки между всеки два символа, празен символ. 97 | 98 | Забележка: Ако някой си мисли, че Tux е нещо за хапване, моля да отвори връзката, предоставена на долния ред. 99 | http://en.wikipedia.org/wiki/Tux 100 | http://fc01.deviantart.net/fs13/f/2007/099/7/7/Kill_Bill_by_lahandi.png 101 | 102 | Решение: 103 | #include //printf 104 | #include //execl, execlp 105 | #include // fork, getpid, getppid 106 | #include // wait 107 | #include // exit 108 | #include 109 | #include 110 | #include 111 | 112 | /* 113 | За по-добра четимост на кода са премахнати част от коментарите от миналата задача, тъй като са идентични. 114 | */ 115 | main(int argc, char* argv[]){ 116 | int status; // съдържа код на завършване на процеса дете. 117 | int fd1; 118 | char c; 119 | 120 | //тяло на бащата > 0 121 | if( fork() > 0 ){ 122 | wait(&status); 123 | if( ( fd1 = open(argv[1], O_RDONLY, 0600 ) ) == -1 ){ 124 | write(2, "Something went wrong!\n", 22); 125 | exit(-1); 126 | } 127 | else{ 128 | while ( read(fd1, &c, 1) == 1 ){ 129 | write(1, &c, 1); 130 | if(c == '\n') continue; 131 | c=' '; 132 | write(1, &c, 1); 133 | } 134 | } 135 | exit(0); 136 | } 137 | //тяло на сина = 0 138 | else{ 139 | if( ( fd1 = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0600 ) ) == -1 ){ 140 | write(2, "Something went wrong!\n", 22); 141 | exit(-1); 142 | } 143 | else{ 144 | write(fd1, "Hello Tux!\n", 11); 145 | close(fd1); 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /homework01-02.txt: -------------------------------------------------------------------------------- 1 | Домашно -поправка 2 | 3 | Напишете командна процедура на bash, която приема два аргумента на командния си ред. Две естествени числа. 4 | Първото число отговаря на разклоненост на коледно дърво. 5 | Второто число отговаря на годината, която ще посрещнем в навечерието на 31 декември. 6 | Дървото трябва да има стъбло центрирано спрямо върха на елхата. 7 | Надписът "ЧНГ 'година' " да е центриран спрямо центрираното стъбло. 8 | Произволни елементи от дървото трябва да са оцветени на произволен принцип в един от следните три цвята: бяло, зелено, червено 9 | 10 | Оценяване: 11 | +1.5 правилно генериране на дърво (заедно със стъблото) 12 | +1.5 правилно генериране на новогодишния надпис спрямо стъблото (без генерирано дърво и стъбло няма как да се оцени) 13 | +1 добавяне на цвят за празнично настроение (без генерирано дърво няма как да се оцени) 14 | 15 | Примерен резултат: 16 | * 17 | * * 18 | * * * 19 | * * * * 20 | * * * * * 21 | * * * * * * 22 | *** 23 | ЧНГ 2016 24 | 25 | 26 | Краен срок за предаване на домашното: 27 | 2016.12.31, 23:59 минути. 28 | Бонус за предаване в интервала: 2017.01.01 00:00-01:00ч. 29 | 30 | Оценката получена върху домашно -поправката (ДП), има специалното свойство да пренапише оценката получена върху контролно номер 1(КН1). 31 | Като всяко специално нещо и тя има особености, но те са само две + едно на брой: 32 | 1) ако оценката от ДП е по-висока от КН1, тя ще бъде пренаписана автоматично 33 | 2) ако оценката от ДП е по-ниска от КН1, ще бъде пренаписана само при желание на студентa получил резултата 34 | 2+1) особеност 2) може да бъде отправена от произволен студент спрямо оценката на Симеон, стига студентът да идва с нас на упражнения 35 | 36 | Успех! 37 | -------------------------------------------------------------------------------- /homework01.txt: -------------------------------------------------------------------------------- 1 | Домашно 1 2 | 3 | Съставете командна процедура на bash, която приема два аргумента на командния си ред. Първият е естествено число, а вторият - низ. 4 | Числото отговаря на максималната широчина на великденски двузъбец (a.k.a китайска виличка). 5 | Вторият аргумент съответства на името, на собственика на великденския двузъбец. 6 | Двузъбецът трябва да има дръжка, центрирана спрямо острието на двузъбеца. 7 | Собственическият надпис да е центриран спрямо центрираната дръжка. 8 | Произволни елементи от острието трябва да са оцветени на произволен принцип в един от следните три цвята: жълт, циан, магента 9 | 10 | Примерен вход: 11 | bash ./easter.sh 10 Данчо 12 | 13 | Примерен резултат, ама цветен: 14 | * * 15 | ** ** 16 | *** *** 17 | *** **** 18 | ********* 19 | *** 20 | *** 21 | *** 22 | Данчо 23 | 24 | Краен срок за предаване на домашното: 25 | 04.29.2016г, 23:59 минути 26 | Моля, предайте домашното чрез платформата Moodle в предвидената за целта графа. 27 | 28 | Успех! 29 | -------------------------------------------------------------------------------- /homework02.txt: -------------------------------------------------------------------------------- 1 | Да се напише командна процедура на bash, която да приема на командния си ред два параметъра. 2 | Първият съответства на мрежови IPv4 адрес, вторият съответства на мрежова маска. 3 | Нека командната процура сканира мрежата дефинирана от подадените входни параметри за активни хостове. 4 | За всеки активен хост да извежда подходящо съобщение на стандартния изход. 5 | 6 | *Процедурата в никакъв случай да не се стартира при подадени невалидни първи и втори аргумент. 7 | --------------------------------------------------------------------------------