Files
linux_intro/labs/lab2/report.typ
2025-10-01 22:52:39 +03:00

255 lines
9.7 KiB
Typst
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#set text(size: 1.3em)
#show raw.where(block: false): box.with(
fill: luma(240),
inset: (x: 3pt, y: 0pt),
outset: (y: 3pt),
radius: 2pt,
)
#show raw.where(block: true): block.with(
fill: luma(240),
inset: 10pt,
radius: 4pt,
)
// title
#align(center)[Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики]
\
\
\
#align(center)[Факультет инфокоммуникационных технологий]
#align(center)[Направление подготовки 11.03.02]
\
\
#align(center)[Лабораторная работа №2]
#align(center)[Создание и использование размерных типов данных]
\
\
\ //#align(center)[Вариант 19]
\
\
\
\
\
\
\
#align(right)[Выполнил:]
#align(right)[Дощенников Никита Андреевич]
#align(right)[Группа: К3221]
#align(right)[Проверил:]
#align(right)[Береснев Артем Дмитриевич]
\
\
#align(center)[Санкт-Петербург]
#align(center)[2025]
#pagebreak()
=== Цель работы:
Получить практические навыки программирования на bash, освоить практические приемы работы с командной оболочкой bash.
=== Часть 1. Работа в среде bash.
Для изменения приглашения командной строки я отредактировал файл `~/.bashrc`, добавив туда строку:
```bash
PS1='\t \u \w \$ '
```
Теперь приглашение отображает текущее время, имя пользователя, текущий каталог и символ `$`.
#align(center)[#image("assets/1.png")]
Создал алиас для вывода приветствия:
```bash
alias hi='echo "Have a nice day, $(whoami)!"'
```
После этого при вводе команды `hi` в терминале появляется строка с приветствием и именем текущего пользователя.
#align(center)[#image("assets/2.png")]
Чтобы изменения сохранились при перезапуске, эти строки были добавлены в файл `~/.bashrc`. Применил изменения без выхода из системы командой:
```bash
source ~/.bashrc
```
=== Часть 2. Простые задачи на bash.
1. Принимает две строки как параметры и сравнивает их.
```bash
#!/bin/bash
[ "$#" -ne 2 ] && echo "usage: $0 str1 str2" && exit 1
[ "$1" = "$2" ] && echo "equal" || echo "not equal"
```
#align(center)[#image("assets/3.png")]
2. Принимает три целых числа и находит максимальное из них.
```bash
#!/bin/bash
[ "$#" -ne 3 ] && echo "usage: $0 a b c" && exit 1
a=$1
b=$2
c=$3
max=$a
(( b > max )) && max=$b
(( c > max )) && max=$c
echo "$max"
```
#align(center)[#image("assets/4.png")]
3. Считывает строки до тех пор, пока не встретится строка `q`. После завершения цикла все введённые строки объединяются и выводятся в одну строку.
```bash
#!/bin/bash
arr=()
while IFS= read -r line; do
[ "$line" = "q" ] && break
arr+=("$line")
done
printf "%s" "${arr[*]}"
```
#align(center)[#image("assets/5.png")]
4. Считывает последовательность целых чисел. Чтение продолжается, пока не встретится чётное число. После этого выводится количество введённых чисел до него.
```bash
#!/bin/bash
count=0
while IFS= read -r n; do
r=$(( n % 2 ))
[ "$r" -eq 0 ] && break
count=$(( count + 1 ))
done
echo "$count"
```
#align(center)[#image("assets/6.png")]
5. Создано текстовое меню с четырьмя пунктами: запуск редактора `nano`, редактора `vi`, браузера `links`, или выход. Перед выполнением команда `command -v` проверяет наличие программ. Если программа не установлена выводится сообщение и скрипт завершается.
```bash
#!/bin/bash
for cmd in nano vi links; do
command -v "$cmd" >/dev/null 2>&1 || { echo "$cmd is not installed"; exit 1; }
done
echo "1) nano"
echo "2) vi"
echo "3) links"
echo "4) exit"
read -r -p "choose 1-4: " choice
case "$choice" in
1) exec nano ;;
2) exec vi ;;
3) exec links ;;
4) exit 0 ;;
*) echo "invalid choice" ; exit 1 ;;
esac
```
#align(center)[#image("assets/7.png")]
#align(center)[#image("assets/8.png")]
6. Принимает три параметра: имя файла, режим (`h` или `t`), и число строк. В режиме `h` печатаются первые N строк файла (`head -n`). В режиме `t` последние N строк (`tail -n`). Ошибки при отсутствии файла подавляются перенаправлением `2>/dev/null`.
```bash
#!/bin/bash
[ "$#" -ne 3 ] && echo "usage: $0 file h|t N" && exit 1
file=$1
mode=$2
num=$3
case "$mode" in
h) head -n "$num" -- "$file" 2>/dev/null ;;
t) tail -n "$num" -- "$file" 2>/dev/null ;;
*) echo "mode must be h or t" ; exit 1 ;;
esac
```
#align(center)[#image("assets/6.png")]
=== Часть 3. Разработка скрипта расчета производительности.
1. В этой части требовалось написать скрипт `script23`, который измеряет производительность CPU в FLOPS (Floating Point Operations Per Second). Для этого необходимо было реализовать большое количество операций с плавающей запятой и зафиксировать время их выполнения.
2. Для вычислений использовалась утилита `bc`, так как она позволяет работать с произвольной точностью. В скрипте выставлена точность `scale=10`.
3. В скрипте организована функция `bench`, в которой выполняется $N$ умножений двух одинаковых чисел. Параметр $N$ можно передать в скрипт, по умолчанию используется 1 000 000.
4. С помощью команды `date +%s.%N` время сохраняется до и после выполнения функции. Далее определяется разница во времени и вычисляется показатель FLOPS по формуле:
$
F L O P S = frac(N, Delta t)
$
5. В завершении программа выводит три значения: количество итераций, время выполнения в секундах, и рассчитанный FLOPS.
```bash
#!/bin/bash
n=${1:-1000000}
command -v bc >/dev/null 2>&1 || { echo "bc is required"; exit 1; }
bench() {
printf 'scale=10\na=1.2345678901\nb=1.2345678901\nfor(i=0;i<%s;i++) x=a*b\n' "$n" | bc >/dev/null
}
start=$(date +%s.%N)
bench
end=$(date +%s.%N)
dur=$(echo "$end - $start" | bc -l)
flops=$(echo "$n / $dur" | bc -l)
printf "iterations=%s\ntime_s=%s\nFLOPS=%s\n" "$n" "$dur" "$flops"
```
#align(center)[#image("assets/10.png")]
=== Вопросы.
==== 1. Как определить сколько параметров пользователь передал в скрипт при запуске?
В bash для этого используется специальная переменная `$#`.
Она хранит количество аргументов, переданных скрипту.
Пример:
```bash
echo "amount of params: $#"
```
==== 2. Что выведет простой скрипт с постдекрементом?
Код:
```bash
count=10
echo $(( count-- ))
echo $(( count-- ))
```
#align(center)[#image("assets/11.png")]
Первая строка напечатает `10`, потому что оператор постдекремента возвращает старое значение, а потом уменьшает переменную. После этой операции `count=9`. Вторая строка напечатает `9` аналогично.
==== 3. Недостатки подхода к определению FLOPS в нашем скрипте
- Измеряется не только операция умножения, но и работа интерпретатора bash и программы `bc`.
- Не используется SIMD (векторные инструкции) и многопоточность, поэтому результат сильно занижен.
- Выполняется только умножение одинаковых чисел, что не отражает реальную работу CPU.
- На результат влияют другие процессы в системе, частота процессора, троттлинг, кэш.
- Такой метод больше демонстрационный и не сопоставим с эталонными тестами на C/Fortran.
=== Вывод.
В ходе проделанной работы я получил практические навыки программирования на bash, освоил практические приемы работы с командной оболочкой bash.