Виконує скрипт при запуску або вимкненні linux. Створення свого скрипта автозапуску під час завантаження комп'ютера Редагування скриптів запуску PPP

Якщо ви ще не знаєте про pCloud, то можете почитати .

PCloud для Linux пропонує програму синхронізації для Linux у вигляді appimage (найсвіжішу версію можна). Вирішення здавалося б простого питання автоматизації процесу " запуск клієнта – синхронізація – вимикання клієнта " призвело до необхідності вирішення кількох завдань, що з особливостями роботи клієнта pCloud. Рішення наводиться стосовно графічного оточення xfce.

Зрештою рішення з автоматизації автоматизація процесу вилилося у запуск двох чи трьох завдань за розкладом (див. ).

Запуск клієнта pCloud

Для запуску клієнта використовується простий скрипт, наприклад, pcloud1.sh

#!/bin/bash
/шлях_до_файлу/pcloud

А команда завдання користувача являє собою

Export DISPLAY=:0 && /path/pcloud1.sh

Path – шлях до скрипту pcloud1.sh

Початкове додавання до pcloud1.sh рядка exit (завершення pcloud1.sh) не призвело до бажаного результату. У диспетчері завдань спостерігалося 2 процеси:

Pcloud1.sh
sh -c export DISPLAY=:0 && /path/pcloud1.sh

Щоб pcloud1.sh "не висів" у менеджері завдань був створений скрипт pcloud2.sh, що запускаються за розкладом через хвилину після запуску pcloud1.sh Скрипт являє собою "прохання" завершити всі наявні процеси з найменуванням pcloud1.sh

#!/bin/bash
killall -s TERM pcloud1.sh
sleep 1 && exit

Зупинка клієнта pCloud

Цей скрипт, з погляду його створення, став найбільш трудомістким, що пояснюється двома причинами.

Запитання 1.Робота клієнта стала супроводжуватись декількома процесами. Наприклад, при запуску клієнта та наступним за ним автоматичним відкриттям всіх вікон у диспетчері завдань можна побачити 6 процесів pcloud:


Після закриття основного вікна клієнта та екземпляра менеджера файлів, що відображає вміст хмари pCloudDrive, у диспетчері завдань залишиться 5 процесів pcloud:


Оскільки термінальної команди для завершення роботи клієнта не існує, то можна застосувати рішення щодо "м'якого" завершення процесу pcloud за його значенням pid, тобто командою kill -15 pid_pcloud

Але якщо запросити pid процесу pcloud, то в результаті буде отримано або 6 груп цифр, що відповідають pid процесам pcloud (приклад: 16129 16103 16077 16048 16036 16032), або 5 груп (приклад: 29419 2939 23 Дані значення pid щоразу змінюватимуться.

Кількість процесів (5 або 6) залежить від того, чи у Вас відкриті всі вікна, що відкриваються автоматично при запуску клієнта, або ці вікна закриті і активний тільки значок стану на підставці робочого столу (системної панелі, треї).

Виникає закономірне питання: а який процес необхідно вимикати?

Запитання 2.При запуску клієнта pCloud автоматично відкриваються 2 вікна, одне з яких є вікном клієнта, а друге екземпляром файлового менеджера, що відповідає відкритому каталогу pCloudDrive, зміст якого становить контент змонтованого в нього простору хмари облікового запису pCloud, наприклад:



Якщо після вимкнення клієнта pCloud вікно клієнта (верхній малюнок) зникне, друге вікно так і залишиться відкритим. Вміст другого вікна буде порожнім, тому що в процесі завершення роботи клієнта хмара pCloud була розмонтована.

Питання: як його автоматично закрити?

Примітка. Питання про закриття відкритого вікна програми pCloud не порушується, тому що в xfce значок на панелі (системному лотку, треї) відображає лише стан "синхронізовано" або "синхронізується". Відомості про кількість файлів, що завантажуються або завантажуються, а також швидкості процесу відображаються в нижній частині відкритого вікна програми pCloud.

Відповідатимемо на поставлені питання будемо послідовно.

Відповідь 1.Експериментально було встановлено, що для виходу клієнта pcloud необхідно вимикати pcloud з найменшим значенням pid, що відповідає процесу pCloud Drive (див. диспетчер завдань). Тому найважчим завданням автоматизації буде вибірка з отриманих значень найменшого pid, щоб потім його призначити змінною.

Як виявилося, це завдання можна вирішити принаймні чотирма способами. Крім того, "м'яке" вимкнення всіх процесів pcloud можна здійснити командою killall із зазначенням імені процесу. Оскільки всі рішення, яких набирається 5, ведуть одному й тому результату, то нижче слід їх перерахування.

1 варіант: killall -s TERM pcloud

Тут усе зрозуміло. Видається команда завершення всіх процесів pcloud.

Наступні три способи являють собою низку послідовних операцій. Спочатку виробляється отримання значень pid всіх екземплярів pcloud та його запис у файл (наприклад pcloud.txt). Зміст файлу є послідовністю з 5-ти або 6-ти груп цифр (див. пояснення вище). Далі "виловлюється" остання група (5 цифр) з отриманого ряду значень pid і надається змінною (наприклад VAR). Заключна дія є виконанням команди kill -15 $VAR, що рівнозначно виконанню kill -15 із зазначенням найменшого значення pid із файлу pcloud.txt

2, 3, 4 варіанти:
pidof pcloud> ~/pcloud.txt
VAR=`cat ~/pcloud.txt | grep -o *$`
kill -15 $VAR

Pidof pcloud> ~/pcloud.txt
VAR=`cat ~/pcloud.txt | awk "(print $NF)"`
kill -15 $VAR

Pidof pcloud> ~/pcloud.txt
VAR=`cat ~/pcloud.txt | rev | cut-d" "-f 1 | rev
kill -15 $VAR

Варіанти 1–4 були запропоновані користувачі форуму Linuxmint.com.ru з ніками slant (2), Chocobo (3 та 4), demonlibra (1). Користуючись нагодою, хотілося б ще раз висловити свою подяку.

5 варіант

При отриманні списку pid процесів pcloud командою pgrep результат у файлі pcloud.txt буде представлений "у стовпчик", тобто кожне значення pid розташовуватиметься в новому рядку в порядку їх зростання, наприклад:

29320
29324
29352
29398
29419

Наступним кроком буде присвоєння змінної значення першого рядка файлу pcloud.txt

Pgrep pcloud> ~/pcloud.txt
VAR=`sed -n "1p" ~/pcloud.txt`
kill -15 $VAR

Відповідь 2.Незважаючи на простоту команди закриття активного вікна Thunar командою thunar -q (отримана після виконання в терміналі thunar --help), в даному випадку вона не спрацьовує.

Після розгляду деревини процесів виявлено, що в переліку активних процесів є Thunar --daemon:


Закрити відкрите клієнтом pCloud вікно Thunar можна трьома способами:

А) завершити всі активні процеси Thunar killall-s TERM/usr/bin/Thunar;

Б) отримати pid процесу Thunar, записати його в змінну і завершити його командою kill -15

OUTPUT="$(pidof /usr/bin/thunar)"
kill -15 $ (OUTPUT)

В) отримати pid процесу Thunar, записати його в файл, присвоїти змінної значення, отримане з читання файлу і завершити його командою kill -15 значення_змінної

Pidof /usr/bin/Thunar> ~/thunar.txt
VAR2=`cat ~/thunar.txt`
kill -15 $VAR2

Усі варіанти рівнозначні. Результатом їх виконання є завершення процесів thunar --daemon та Thunar (відповідає відкритому вікну з вмістом каталогу pCloudDrive).

Щодо "важливості" процесу thunar --daemon на англомовному форумі була знайдена інформація, що на функціональність Thunar і системи в цілому це істотного впливу не має. Єдиний мінус полягає в тому, що без цього процесу під'єднаний знімний носій (наприклад, флешка) буде автоматично змонтований тільки при відкритому вікні Thunar. Якщо жодного екземпляра Thunar не запущено, знімний носій автоматично не монтується. У цьому випадку доведеться відкрити Thunar і здійснити монтування вручну, наприклад:


У будь-якому випадку після чергового запуску системи thunar --daemon буде запущено автоматично


що визначається змістом файлу

/etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml (див. --daemon)



Отже, скрипт завершення роботи клієнта pCloud (наприклад pcloud3.sh) може бути наступного змісту (вибирається один варіант та один спосіб):

#!/bin/bash
варіант 1, 2, 3, 4, 5
sleep 5
спосіб а, б, с
sleep 5 && exit

Команда 5-секундної паузи slеep 5 була введена для тестування скрипта для спостереження за процесами. У робочому скрипті її можна використати.

Приклад користувача cron для щоденної 40-хвилинної автоматичної синхронізації з хмарою pCloud з 21:40 до 22:20

40 21 * * * export DISPLAY=:0 && /home/user/Tools/scripts/pcloud1.sh
41 21 * * * /home/user/Tools/scripts/pcloud2.sh

Якщо обмежитися тільки скриптами запуску та вимкнення, тобто pcloud1.sh і pcloud3.sh, то скрипт pcloud3.sh повинен вимикати pcloud c процесом pid не найменшим, а на одиницю більше, тобто з отриманого ряду значень, наприклад,

28354 28355 28359 28371 28399 28426 28449 28684 ,

Повинне бути обране друге (28355). Пояснюється тим, що 28354 відповідає активному скрипту pcloud1.sh.

Відповідно, у цьому випадку для вимкнення процесів pcloud буде використовуватися такий код:

Pgrep pcloud> ~/pcloud.txt
VAR=`sed -n "2p" ~/pcloud.txt`
kill -15 $VAR

Тоді користувальницьке завдання набуває вигляду, наприклад:

40 21 * * * export DISPLAY=:0 && /home/user/Tools/scripts/pcloud1.sh
20 22 * ​​* * /home/user/Tools/scripts/pcloud3.sh

Якщо питання: «як додати програму в автозавантаження?» — користувачі-початківці знаходять відповідь досить швидко, то питання про запуск скрипта, при вимкненні/перезавантаження, ставить їх у глухий кут. У статті буде описано стандартний спосіб автоматичного виконання команд при включенні та вимкненні linux, а також більш простий спосіб для користувачів, у яких встановлений gdm і графічний інтерфейс, наприклад ubuntu.

Консольний варіант.

Небагато теорії.
Слід знати, що у Linux існує 7 рівнів запуску. Однак, можуть використовуватися тільки 6.
Як у всіх програм, що поважають себе, відлік починається з 0-ля.
0 — Зупинка або вимкнення системи.
1 — Однокористувальний режим.
2 — Розрахований на багато користувачів режим, але без підтримки мережі.
3 - Теж саме, але з мережею.
4 — Додали для краси Не використовується.
5 — Графічний режим із завантаженням сервера X.
6 — Перезавантаження.
Якщо перейти до папки /etc (У деяких дистрибутивах /etc/rc.d) можна побачити папки з 7-ма рівнями запуску.

Наприклад, при вимкненні комп'ютера виконуються всі скрипти з папки rc0.d


Тут слід зупинитися детальніше. Справа в тому, що самих скриптів (а точніше сценаріїв) у цій папці немає, а є лише посилання на файли, що лежать у папці /etc/init.d. Ці сценарії виконують різні завдання, залежно від параметра start або stop (наприклад /etc/init.d/reboot start та /etc/init.d/reboot stop – це різні команди, а /etc/init.d/reboot взагалі не буде) працювати). Якщо посилання стоїть перша літера S, значить сценарію подається параметр start, і якщо стоїть буква K(від слова kill), то параметр stop. Цифра після літери означає порядок виконання сценарію.
Наприклад, на вище вставленому скріншоті спочатку виконати команду /etc/init.d/hddtemp stop, а вже пізніше /etc/init.d/networking start.
Досить теорії. Переходимо до практики.
Щоб додати команду в автозавантаження, достатньо помістити її у файл /etc/rc.local.

У цій частині статті як редактор буде використовуватися nano, але ви можете користуватися своїм улюбленим редактором, наприклад gedit.

sudo nano /etc/rc.local

І поміщаємо наші команди трохи вище за рядок з exit 0.
Для того, щоб команди виконувались перед вимкненням або перезавантаженням, нам потрібно створити сценарій у папці /etc/init.d

sudo nano /etc/init.d/ім'я_сценарію

Вставляємо наступний код:

#! /bin/sh
case "$1" in
start)
echo "подано сигнал start"
;;
stop)
echo "подано сигнал stop"
;;; esac

Якщо подаватиметься лише один сигнал, то просто закоментуйте рядок поставивши на початку команди знак #
Наприклад

...
case "$1" in
start)
#
;;
...

Тепер робимо файл виконуваним:

sudo chmod +x /etc/init.d/ім'я_сценарію

sudo update-rc.d имя_сценария start 20 0 6 . stop 1 0 6 .

Крапки важливі (обидві). Досліджуючи простори інтернету, у мене склалося враження, що синтаксис цієї програми інколи змінюється. Актуальні приклади можна переглянути за командою "man update-rc.d". Приклади будуть у низу.

Ця команда створить по 2 посилання у каталогах /etc/rc 0 .d (друге число в команді) та /etc/rc 6 .d (третє число у команді). Причому спочатку буде виконуватися сценарій з параметром stop (бо стоїть 1), а вже потім з параметром start (бо стоїть 20).
Якщо другий параметр не потрібен, можна виконати команду:

sudo update-rc.d имя_сценария stop 1 0 6 .

Раджу ставити пріоритет вище (тобто число після start або stop має бути маленьким), бажано менше 20. Інакше у мене іноді зависав комп'ютер при спробі перезавантажитися.

Для користувачів ubuntu та й багатьох інших сучасних дистрибутивів з gdm можна скористатися.

Графічний варіант.

Що стосується автозавантаження то можна скористатися способом описаним.
Або просто відкрити «додатки, що автоматично запускаються» командою:

gnome-session-properties

Для виконання скрипта при вимиканні комп'ютера поміщаємо його у файл /etc/gdm/PostSession/Default

sudo gedit /etc/gdm/PostSession/Default

Просто над строчкою exit 0.

Пишемо скрипти в Linux (навчання на прикладах)

———————————————————————————-

1. Введення

Що потрібно, щоб писати скрипти
Володіння інструментами командного рядка та їх необхідними опціями.
Базові знання англійської рівня початкової школи не завадять.

Навіщо потрібні скрипти
По-перше, адміністрування linux-сервера тією чи іншою мірою зводиться до систематичного виконання одних і тих самих команд. Причому не обов'язково, щоб ці команди виконувала людина. Їх можна запрограмувати виконання машиною.
По-друге, навіть просто виконання звичайної задачі, яка (раптом) складає 20-1000… одноманітних операцій МІСТО простіше реалізувати в скрипті.

Що таке скрипт
Скрипт — це набір інструкцій, які потрібно в певному порядку та в певний час виконати комп'ютер. Інструкціями можуть бути як внутрішні команди оболонки (цикли, умови, обробка текстової інформації, робота зі змінними оточення та інше), так і будь-яка програма, яку ми виконуємо в консолі з необхідними параметрами.

Як писати скрипт
У нашому випадку скрипт буде являти собою текстовий файл з атрибутами виконання. Якщо файл сценарію починається з послідовності #!, що у світі UNIX називається sha-bang, це вказує системі який інтерпретатор слід використовувати у виконання сценарію. Якщо це важко зрозуміти, то просто запам'ятайте, що всі скрипти ми починатимемо писати саме з рядка #!/bin/bash або #!/bin/sh, а далі підуть команди та коментарі до них.

Побажання
Я Вам щиро раджу писати якнайбільше коментарів чи не до кожного рядка в скрипті. Мине час і Вам знадобиться змінити або модернізувати написаний скрипт. Якщо не пам'ятаєш або не розумієш, що написано в скрипті, то складно його змінювати, простіше писати з нуля.

Які скрипти можуть нам знадобитися:

    встановлює правила фаєрвола при завантаженні системи.
    виконує backup налаштувань та даних.
    додає поштові скриньки до поштового сервера (точніше до бази mysql)
    запускає в певний час (краще щоночі) програму, яка сканує логи проксі-сервера і видає зручний web-звіт за кількістю скачаного трафіку.
    що надсилає нам на пошту інформацію про те, що хтось отримав доступ до нашого сервера по ssh, час підключення та адресу клієнта.

Про методику написання скриптів
Створюємо текстовий файл, редагуємо його, встановлюємо права виконання, запускаємо, дивимося помилки, виправляємо, запускаємо, дивимося помилки…
Коли все вилізане і працює правильно, ставимо його в автозавантаження або планувальник на певний час.

———————————————————————————-

2. Навчання написання сценаріїв внутрішньою мовою BASH
оригінал: https://www.linuxconfig.org/Bash_scripting_Tutorial

Цей посібник передбачає відсутність попередніх знань про методику написання сценаріїв (далі скриптів) за допомогою внутрішньої мови Bash. За допомогою цього посібника ви виявите незабаром, що написання скриптів дуже просте завдання. Давайте почнемо наше навчання з простого сценарію, що виконує виведення рядка Hello World! (у перекл. з англ. - Всім привіт!)

1. Сценарій "Всім привіт"
Ось ваш перший приклад bash-скрипту:

#!/bin/bash
echo «Hello World»

Переходимо в директорію, що містить файл hello_world.sh і робимо його виконуваним:

Код: Виділити все $chmod+x hello_world.sh

Запускаємо скрипт на виконання

Код: Виділити все $./hello_world.sh

2. Простий архівуючий bash-скрипт

#!/bin/bash
tar -czf myhome_directory.tar.gz /home/user

Код: Виділити все $./backup.sh

$ du -sh myhome_directory.tar.gz
41M myhome_directory.tar.gz

3. Робота зі змінними
У цьому прикладі ми оголошуємо просту змінну та виводимо її на екран за допомогою команди echo

#!/bin/bash
STRING="HELLO WORLD!!!"
echo $STRING

Код: Виділити все $./hello_world.sh
HELLO WORLD!

Наш архівуючий скрипт зі змінними:

#!/bin/bash
OF=myhome_directory_$(date +%Y%m%d).tar.gz
IF=/home/user
tar -czf $OF $IF

Код: Виділити все $./backup.sh
tar: Removing leading "\" від member names
$ du -sh *tar.gz
41M myhome_directory_20100123.tar.gz

3.1 Глобальні та локальні змінні

#!/bin/bash
# Оголошуємо глобальну змінну
# Така змінна може використовуватись у будь-якому місці цього скрипту
VAR="global variable"
function bash (
# Оголошуємо локальну змінну
Така змінна дійсна тільки для функції, в якій її оголосили
local VAR="local variable"
echo $VAR
}
echo $VAR
bash
# Зверніть увагу, що глобальна змінна не змінилася
echo $VAR

Код: Виділити все $./variables.sh
global variable
local variable
global variable

4. Передаємо аргументи у скрипт

#!/bin/bash
# Використовуйте певні змінні для доступу до аргументів
# Виводимо аргументи на екран
echo $1 $2 $3 ' -> echo $1 $2 $3’

#Ми також можемо отримати доступ до аргументів через спеціальний масив args=(« [email protected]»)
# Виводимо аргументи на екран
echo $(args) $(args) $(args) ' -> args=(« [email protected]»); echo $(args) $(args) $(args)’

# Використовуйте змінну [email protected]для виведення всіх аргументів відразу
echo [email protected]' -> echo [email protected]

Використовуйте змінну $# для виведення кількості передано в скрипт аргументів
echo Number of arguments passed: $# ' -> echo Number of arguments passed: $#'

Код: Виділити все $./arguments.sh Bash Scripting Tutorial
Bash Scripting Tutorial -> echo $1 $2 $3
Bash Scripting Tutorial -> args=(" [email protected]"); echo $(args) $(args) $(args)
Bash Scripting Tutorial -> echo [email protected]
Число слів: 3 -> echo Кількість слів: $#

5. Виконання у скрипті команд оболонки

#!/bin/bash
# використовуйте зворотні лапки » `` для виконання команди оболонки
echo `uname -o`
# Тепер спробуємо без лапок
echo uname -o

Код: Виділити все $ uname -o
GNU/Linux
$./bash_backtricks.sh
GNU/Linux
uname -o

Як бачимо, у другому випадку вивелася сама команда, а не результат її виконання

6. Читаємо введення користувача (інтерактивність)

#!/bin/bash
echo -e "Hi, please type the word: \c"
read word
echo "The word you entered is: $word"
echo -e «Can you please enter two words? »
read word1 word2
echo "Here is your input: \"$word1\" \"$word2\"»
echo -e «How do you feel about bash scripting? »
# read command now stores a reply into default build-in variable $REPLY
read
echo You said $REPLY, I'm glad to hear that! »
echo -e «What are your favorite colours? »
# -a makes read command to read into an array
read -a colours
echo "My favorite colors є $(colours), $(colours) and $(colours):-)"

Код: Виділити все $./read.sh
Hi, please type the word: something
The word you entered is: something
Can you please enter two words?
Debian Linux
Here is your input: "Debian" "Linux"
How do you feel про bash scripting?
good
You said good, I'm glad to hear that!
What are your favorite colours?
blue green black
My favorite кольори є також blue, green and black:-)

7. Використання пастки

#!/bin/bash
# оголошуємо пастку
trap bashtrap INT
# Очищаємо екран
clear;
функція пастки виконується, коли користувач натискає CTRL-C:
# На екран буде виводитися => Executing bash trap subrutine!
# але скрипт продовжуватиме виконуватись
bashtrap()
{
echo «CTRL+C Detected !…executing bash trap !»
}
# скрипт буде рахувати до 10
for a in `seq 1 10`; do
echo "$a/10 to Exit."
sleep 1;
done
echo «Exit Bash Trap Example!»

Код: Виділити все $./trap.sh
1/10
2/10
3/10
4/10
5/10
6/10

7/10
8/10
9/10
CTRL+C Detected !...executing bash trap !
10/10
Exit Bash Trap Example!

Як бачимо, поєднання клавіш Ctrl-C не зупинило виконання скрипта.

8. Масиви
8.1 Оголошуємо простий масив

#!/bin/bash
# Оголошуємо простий масив із 4 елементами
ARRAY=('Debian Linux' 'Redhat Linux' Ubuntu Linux)
# Отримуємо кількість елементів у масиві
ELEMENTS=$(#ARRAY[@])

# Виводимо в циклі кожен елемент масиву
for ((i=0;i<$ELEMENTS;i++)); do
echo $(ARRAY[$(i)])
done

Код: Виділити все $/arrays.sh
Debian Linux
Redhat Linux
Ubuntu
Linux

8.2 Заповнюємо масив значеннями з файлу

#!/bin/bash
# Оголошуємо масив
declare -a ARRAY
# Команда exec # stdin (зазвичай це клавіатура) буде вироблятися з цього файлу. Це дає можливість читати
# вміст файлу, рядок за рядком, та аналізувати кожен введений рядок за допомогою sed та/або awk.
exec 10 let count=0

while read LINE<&10; do

ARRAY[$count]=$LINE
((count++))
done

echo Кількість елементів: $(#ARRAY[@])
# Виведення значень масиву
echo $(ARRAY[@])
# закриваємо файл
exec 10>&-

Код: Виділити все $ cat bash.txt
Debian Linux
Redhat Linux
Ubuntu
Linux
$./arrays.sh
Кількість елементів: 4
Debian Linux Redhat Linux Ubuntu Linux

9. Умови «якщо інакше»
9.1. Просте використання «якщо інакше» умов
Зверніть увагу на прогалини у квадратних дужках, без яких умова не працюватиме.

#!/bin/bash
directory=»./BashScripting»

# перевіряємо наявність директорії
if [-d $ directory]; then
echo «Directory exists»
else
echo "Directory does not exists"
fi

Код: Виділити все $./if_else.sh
Directory does not exists
$ mkdir BashScripting
$./if_else.sh
Directory exists

9.2 Вкладені «якщо інакше» умови

#!/bin/bash
# Оголошуємо змінну зі значенням 4
choice=4
# Виводимо на екран
echo “1. Bash»
echo “2. Scripting»
echo “3. Tutorial»

# Виконуємо, поки змінна дорівнює чотирьом
# Зациклювання
while [$ choice -eq 4]; do

# читаємо введення користувача
read choice
# вкладена «якщо інакше» умова
if [$choice-eq 1]; then

echo «Ви маєте chosen word: Bash»

if [$choice-eq 2]; then
echo You have chosen word: Scripting
else

if [$choice-eq 3]; then
echo «Ви маєте chosen word: Tutorial»
else
echo "Please make a choice between 1-3!"
echo “1. Bash»
echo “2. Scripting»
echo “3. Tutorial»
echo -n «Please choose a word? »
choice=4
fi
fi
fi
done

Код: Виділити все $./nested.sh
1. Bash
2. Scripting
3. Tutorial

5

1. Bash
2. Scripting
3. Tutorial
Please choose a word?
4
Please make a choice between 1-3!
1. Bash
2. Scripting
3. Tutorial
Please choose a word?
3
You have chosen word: Tutorial

Отже спочатку тіло циклу «while» виконується, т.к. змінна choice спочатку дорівнює чотирьом. Потім читаємо в неї введення користувача, і якщо введення не дорівнює 1,2 або 3 то робимо нашу змінну знову рівну 4, у зв'язку з чим тіло циклу повторюється (знову необхідно вводити 1,2 або 3).

10. Порівняння
10.1 Арифметичні порівняння

Lt<
-gt >
-le<=
-ge >=
-eq ==
-ne! =

#!/bin/bash

NUM1=2
NUM2=2
if [$ NUM1 -eq $ NUM2]; then
echo "Both Values ​​are equal"
else
echo "Values ​​are NOT equal"
fi

Код: Виділити все $./equals.sh
Both Values ​​are equal

#!/bin/bash
# Оголошуємо змінні з цілими значеннями
NUM1=2
NUM2=3
if [$ NUM1 -eq $ NUM2]; then
echo "Both Values ​​are equal"
else
echo "Values ​​are NOT equal"
fi

Код: Виділити все $./equals.sh
Values ​​are NOT equal

#!/bin/bash
# Оголошуємо змінні з цілими значеннями
NUM1=2
NUM2=1
if [$ NUM1 -eq $ NUM2]; then
echo "Both Values ​​are equal"
elif [$ NUM1 -gt $ NUM2]; then
echo "$NUM1 is greater then $NUM2"
else
echo "$NUM2 is greater then $NUM1"
fi

Код: Виділити все $./equals.sh
2 is greater then 1

10.2. Символьно-текстові порівняння

Одинакові
!= не однакові
< меньще чем
> більше ніж
-n s1 змінна s1 не порожня
-z s1 змінна s1 порожня

#!/bin/bash

S1="Bash"

S2="Scripting"
if [$ S1 = $ S2]; then

else
echo "Strings are NOT equal"
fi

Код: Виділити все $./statement.sh
Strings are NOT equal

#!/bin/bash
# Оголошуємо символьну змінну S1
S1="Bash"
# Оголошуємо символьну змінну S2
S2="Bash"
if [$ S1 = $ S2]; then
echo "Both Strings are equal"
else
echo "Strings are NOT equal"
fi

Код: Виділити все $./statement.sh
Both Strings are equal

11. Перевірка файлів

B filename Block special file
-c filename Special character file
-d directoryname Check for directory existence
-e filename Check for file existence
-f filename Check for regular file existence not a directory
-G filename Check if file exists and is owned by effective group ID.
-g filename true if file exists and is set-group-id.
-k filename Sticky bit
-L filename Symbolic link
-O filename True if file exists and is owned by the effective user id.
-r filename Check if file is a readable
-S filename Check if file is socket
-s filename Check if file is nonzero size
-u filename Check if file set-ser-id bit is set
-w filename Check if file is writable
-x filename Check if file is executable

#!/bin/bash
file=»./file»
if [-e $file]; then
echo "File exists"
else
echo "File does not exists"
fi

Код: Виділити все $ ls
file.sh
$./file.sh
File does not exists
$ touch file
$ls
file file.sh
$./file.sh
File exists

Аналогічно для прикладу ми можемо використовувати "в той час як" петлі, щоб перевірити, якщо файл не існує. Цей сценарій буде спати, доки файл не існує. Зверніть увагу на Bash заперечувач «!» що зводить нанівець (інвертує) -e опцію.

12. Цикли
12.1. Цикл For

#!/bin/bash
# for цикл
for f in $(ls/var/); do
echo $f
done

Запуск for циклу з командного рядка bash:

Код: Виділити $ for f in $(ls /var/); do echo $f; done Код: Виділити все $ for f in $(ls /var/); do echo $f; done
backups
cache
crash
games
lib
local
lock
log
mail
opt
run
spool
tmp
www

12.2. While цикл

#!/bin/bash
COUNT=6
# while цикл
while [$ COUNT -gt 0]; do

let COUNT=COUNT-1
done

Код: Виділити все $./while_loop.sh
Value of count is: 6
Value of count is: 5
Value of count is: 4
Value of count is: 3
Value of count is: 2
Value of count is: 1

12.3. Until цикл

#!/bin/bash
COUNT=0
# until цикл
until [$ COUNT -gt 5]; do
echo Value of count is: $COUNT
let COUNT=COUNT+1
done

Код: Виділити все $./until_loop.sh
Value of count is: 0
Value of count is: 1
Value of count is: 2
Value of count is: 3
Value of count is: 4
Value of count is: 5

12.4. Цикли з неявними умовами
У наступному прикладі умовою while циклу є наявність стандартного введення.
Тіло циклу буде виконуватися доки є чому перенаправлятися зі стандартного виведення в команду read.

#!/bin/bash
# Даний скрипт буде шукати та видаляти прогалини
# у файлах, замінюючи їх на підкреслення
DIR=».»
Управління циклом із командою read шляхом перенаправлення виведення у циклі.
find $ DIR -type f | while read file; do
# використовуємо POSIX-клас [:space:] щоб знайти прогалини в іменах файлів
if [[ «$file» = *[[:space:]]* ]]; then
# заміна пробілів підкресленнями
mv "$file" `echo $file | tr ‘ ‘ ‘_’`
fi;
done

Код: Виділити все $ ls -1
script.sh
$ touch "file with spaces"
$ ls -1
file with spaces
script.sh
$./script.sh
$ ls -1
file_with_spaces
script.sh

13. Функції

#!/bin/bash
# Функції можуть бути оголошені у будь-якому порядку
function function_B (
echo Function B.
}
function function_A (
echo $1
}
function function_D (
Echo Function D.
}
function function_C (
echo $1
}
# Викликаємо функції
# передаємо параметр у функцію function A
function_A "Function A."
function_B
# передаємо параметр у функцію function C
function_C "Function C."
function_D

Код: Виділити все $./functions.sh
функція A.
функція B.
функція C.
функція D.

14. Оператор вибору - Select

#!/bin/bash
PS3='Choose one word: '
# select
select word in "linux" "bash" "scripting" "tutorial"
do
echo "The word you have selected is: $word"
# Перериваємо, інакше цикл буде нескінченний.
break
done
exit 0

Код: Виділити все $./select.sh
1) linux
2) bash
3) scripting
4) tutorial
Choose one word: 4
The word you have selected is: tutorial

15. Оператор вибору - Case

#!/bin/bash
echo «What is your preferred programming/scripting language»
echo "1) bash"
echo "2) perl"
echo "3) phyton"
echo "4) c++"
echo "5) I do not know!"
read case;
# проста структура case-вибору
# зверніть увагу, що в даному прикладі $case — лише змінна
# і має так називатися. Це лише приклад
case $case in
1) echo "You selected bash";;
2) echo "You selected perl";;
3) echo "You selected phyton";;
4) echo "You selected c++";;
5) exit
esac

Код: Виділити все $./case.sh
What is your preferred programming / scripting language
1) bash
2) perl
3) phyton
4) c++
5) I do not know!
4
You selected c++

———————————————————————————-

Більш детальну інформацію можна отримати з різних джерел, наприклад, звідси
оригінал: https://www.linuxconfig.org/Bash_scripting_Tutorial
https://ruslandh.narod.ru/howto_ru/Bash-Prog-Intro/
https://bug.cf1.ru/2005-03-17/programmin... -book.html

https://ubuntologia.ru/forum/viewtopic.php?f=109&t=2296

Для написання простого скрипта на bash, нам потрібно виконати такі прості дії:

Як це все працює:

перший рядок нашого скрипта #!/bin/bash вкрай необхідний, щоб наш скрипт успішно виконався.

другий рядок mkdir testdir створює каталог testdir

третій рядок cd testdir дозволяє перейти до створеного каталогу testdir

команда touchу наступному рядку touch file1 file2 file3 створює три файли

і остання команда в рядку нашого скрипта ls -al дозволяє вивести на екран вміст поточного каталогу, в якому завдяки попередньому рядку з'явилося три порожні файли.

Як ми бачимо, у нашому простому скриптівсі команди починаються з нового рядка. Кожен рядок під час запуску скрипта послідовно виконує свою роботу, здійснюючи ті чи інші дії.

Якщо ви щодня виконуєте ланцюжок будь-яких однакових команд (з постійними параметрами) в Linux, то можливо вам має сенс написати такий самий простий скрипт на bashякий дозволить вам заощадити ваш час і автоматизувати вашу роботу.

Хоча ви можете продовжувати реєструватися вручну як було показано вище, краще налаштувати деякі скрипти, щоб для вас це відбувалося автоматично.

Набір скриптів автоматизує процес входу в систему і запускає PPP так що все, що ви повинні зробити (від root або член групи PPP) - дати одну команду запуску вашого з'єднання.

15.1 Скрипти з'єднання для аутентифікації на ім'я/пароль користувача

Якщо ваш ISP не вимагає використання PAP/CHAP, вам потрібні ці скрипти!

Якщо пакет ppp встановлено правильно, ви повинні мати два прикладні файли. Для PPP 2.1.2 вони знаходяться в /usr/sbin, а для PPP 2.2 вони знаходяться в /etc/ppp/scripts. Вони називаються

для PPP-2. 1.2

а для PPP-2. 2

ppp-off ppp-on ppp-on-dialer

Тепер, якщо ви використовуєте PPP 2.1.2, я наполегливо прошу вас видалити прикладні файли. З ними є потенційні проблеми (і не повідомляйте мені, що вони чудово працюють), я використав їх дуже довго (і навіть рекомендував їх у першій версії цього HOWTO)!

Для користувача PPP 2.1.2 є КРАЩА версія шаблону, взята з дистрибутива PPP 2.2. Я пропоную вам скопіювати та використовувати ці скрипти замість старого скрипта PPP-2.1.2.

15.2 Скрипт ppp-on

Це перший з ПАРИ скриптів, які фактично запускають з'єднання.

#!/bin/sh # # Скрипт для ініціації з'єднання PPP. Це перша частина пари скриптів. # Не секретні скрипти, оскільки коди видно командою ps. Однак це приклад. # # Це параметри. Змініть їх як слід. TELEPHONE=555-1212 # Телефонний номер з'єднання ACCOUNT=george # Ім'я користувача для входу ("George Burns") PASSWORD=gracie # Пароль для цього облікового запису (і "Gracie Allen") LOCAL_IP=0.0.0.0 # Локальна IP адреса, якщо відома . Динамічний = 0.0.0.0 REMOTE_IP=0.0.0.0 # Видалена IP-адреса, якщо бажана. Зазвичай 0.0.0.0 NETMASK=255.255.255.0 # Відповідна мережева маска, якщо потрібна # # Експортуємо їх, щоб вони були доступні в "ppp-on-dialer" export TELEPHONE ACCOUNT PASSWORD # # # Система. Будь ласка, використовуйте абсолютне ім'я файлу, оскільки опція connect # не використовує змінну $PATH. (Якщо це зробити, то "root" обліковий запис буде # дірою в захисті, так що не просіть.) # DIALER_SCRIPT=/etc/ppp/ppp-on-dialer # # Ініціація з'єднання # # exec /usr/sbin/pppd debug / dev/ttySx 38400 \ $LOCAL_IP:$REMOTE_IP \ connect $DIALER_SCRIPT

Це скрипт ppp-on-dialer:

#!/bin/sh # # Це друга частина скрипта ppp-on. Вона виконує встановлення бажаного з'єднання. # /usr/sbin/chat -v \ TIMEOUT 3 \ ABORT "\nBUSY\r" \ ABORT "\nNO ANSWER\r" \ ABORT "\nRINGING\r\n\r\nRINGING\r" \ "" \rAT \ "OK-+++\c-OK" ATH0 \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT "" \ ogin:--ogin: $ACCOUNT \ assword: $PASSWORD

Для PPP-2.2, сценарій ppp-off приблизно такий:

#!/bin/sh ############################################ ########################## # # Визначити перерваний пристрій. # if [ "$1" = "" ]; then DEVICE=ppp0 else DEVICE=$1 fi ######################################## ############################# # Якщо pid файл ppp0 є, тоді програма працює. Зупинити її. if [ -r /var/run/$DEVICE.pid ]; then kill -INT `cat /var/run/$DEVICE.pid` # # Якщо kill не працює, тоді немає процесу, запущеного під цим pid. # Це також може означати, що існує сторонній lock файл. # Можливо, ви захочете видалити його. if [ ! "$?" = "0"]; then rm -f /var/run/$DEVICE.pid echo "ERROR: Removed stale pid file" exit 1 fi # # Відмінно. Нехай pppd поправить свій недолік. echo "PPP link to $DEVICE terminated." exit 0 fi # # для ppp0 не запущено ppp процес echo "ERROR: PPP link is not active on $DEVICE" exit 1

15.3 Редагування скриптів запуску PPP

Оскільки нові скрипти надходять двома частинами, ми своєю чергою відредагуємо їх.

Скрипт ppp-on

Ви повинні будете відредагувати скрипт, щоб вставити ваше ім'я користувача на вашому ISP, ваш пароль на вашому ISP, номер телефону вашого ISP.

Кожен із рядків типу TELEPHONE= - це фактично встановлені змінні shell, які містять інформацію праворуч від = (за винятком коментарів, звичайно). Відредагуйте кожен із цих рядків так, щоб вони відповідали вашому ISP та з'єднанню.

Також, оскільки ви встановлюєте IP адресу (якщо вам це потрібно) у файлі /etc/ppp/options , видаліть рядок, який говорить

$LOCAL_IP:$REMOTE_IP \

Також, переконайтеся, що змінна оболонка DIALER_SCRIPT вказує на повний шлях та ім'я скрипта для дозвону, який ви фактично збираєтеся використовувати. Отже, якщо ви перемістили його або перейменували скрипт, переконайтеся, що ви відредагували цей рядок правильно в скрипті ppp-on !

Сценарій ppp-on-dialer

Це другий скрипт, який фактично піднімає наш PPP зв'язок.

Зверніть увагу: chat скрипт зазвичай однорядковий. Похилі риси вліво використовуються, щоб розмістити рядки на кількох фізичних рядках (для зручності читання людиною) і не формувати частину скрипта самому.

Однак, дуже корисно розглянути це докладно так, щоб ми зрозуміли, що ж фактично (імовірно) відбувається!

15.4 Що означає скрипт chat...

Скрипт chat - послідовність пар очікуваний рядокрядок, що посилається. Зокрема зверніть увагу, що ми ЗАВЖДИ чекаємо на щось перед тим, як пошлемо що-небудь.

Якщо ми повинні надіслати щось БЕЗ того, щоб спочатку отримати щось, ми повинні використовувати порожній рядок очікування (позначається "") і аналогічно для очікування чогось без того, щоб посилати щось! Також, якщо рядок складається з декількох слів (наприклад, NO CARRIER), ви повинні взяти рядок у лапки, щоб chat сприйняв його як одне ціле.

Рядок chat у нашому шаблоні:

Exec /usr/sbin/chat-v

У виклику chat опція -v каже, щоб chat копіював ВЕСЬ введення/виведення в сисний лог (зазвичай /var/log/messages). Як тільки ви переконаєтеся, що скрипт chat працює надійно, відредагуйте цей рядок, щоб видалити -v, щоб не зберігати непотрібну інформацію у вашому syslog

Це встановлює паузу для очікуваного введення в 3 секунди. Ви можете збільшити це значення до 5 або 10 секунд, якщо ви використовуєте повільний модем!

ABORT "\nBUSY\r"

Якщо отримано рядок BUSY, то операція аварійно припиняється

ABORT "\nNO ANSWER\r"

Якщо отриманий рядок NO ANSWER, то операція аварійно припиняється

ABORT "\nRINGING\r\n\r\nRINGING\r"

Якщо (повторимося) отримано рядок RINGING, то операція аварійно припиняється.

Це тому, що хтось сидить на телефонній лінії!

Не чекаємо нічого від модему, і надісламо рядок до нього

OK-+++\c-OK ATH0

Це трохи складніше, оскільки використовує деякі можливості відновлення при помилках chat .

What is says is... Очікуємо OK, якщо він не отриманий (бо модем не в командному режимі), потім посилаємо +++ (стандартний рядок для Hayes-сумісних модемів, яка повертає модем у командний режим) і очікуємо OK.

Потім посилаємо ATH0 (рядок для завершення зв'язку модему). Це дозволяє вашому скрипту справлятися з модемом, що завис під час сеансу зв'язку!

Встановимо паузу за часом в 30 секунд для команд скрипта, що залишилися. Якщо ви маєте проблеми зі скриптом chat , що переривається через паузи, збільште це значення до 45 секунд або більше

OK ATDT$TELEPHONE

Чекаємо OK(відповідь модему на команду ATH0) та набираємо номер, на який ми хочемо зателефонувати

Чекаємо рядка CONNECT (який наш модем посилає, коли видалені модем відповідає) і не посилаємо у відповідь нічого

Ogin:--ogin: $ACCOUNT

Знову, тут ми вставляємо деяке виправлення помилок. Очікуємо підказку входу в систему (... ogin:), але якщо ми не отримуємо її після паузи, то посилаємо повернення каретки і потім шукаємо підказку входу в систему знову. Коли підказка отримана, надсилаємо username (збережена в змінній shell $ ACCOUNT).

Assword: $PASSWORD

Чекаємо на запит пароля і надсилаємо наш пароль (аналогічно збережений в змінній shell).

Цей скрипт chat має прийнятну можливість виправлення помилок. chat має значно більше можливостей, ніж показано тут. Для детальної інформації проконсультуйтеся з man chat (man 8 chat).

Запуск PPP на серверному боці єднання

Хоча скрипт ppp-on-dialer відмінно підходить для серверів, які автоматично запускають pppd на серверній стороні, як тільки ви зареєструвалися, деякі сервери вимагають, щоб ви явно дали команду запуску PPP на сервері.

Якщо ви повинні дати команду запустити PPP на сервері, ви повинні відредагувати скрипт ppp-on-dialer .

У КІНЦІ сценарію (після рядка пароля) додайте додаткову пару очікуваного-надсилається рядків, яка шукала б вашу підказку реєстрації в системі (розрізняючи символи, які мають спеціальне значення в оболонці Bourne: типу $ і [ або ] (відкриті та закриті квадратні дужки)).

Як тільки програма chat знайшла командний рядок оболонки, вона має видати команду запуску ppp, потрібну для PPP сервера вашого ISP.

У моєму випадку, мій сервер PPP використовує стандартну підказку bash Linux

і вимагає, щоб я надрукував

запустити PPP на сервері.

Добре було б врахувати тут деякі помилки, наприклад у моєму випадку я використовую

Hartr - hartr ppp

Це означає, що якщо ми не отримали підказку протягом заданої паузи, то посилаємо повернення каретки і шукаємо підказку знову.

Як тільки підказка отримана, надсилаємо рядок ppp.

Не забудьте додати \ до кінця попереднього рядка, так що б chat думав, що весь сценарій chat складається з одного рядка!

На жаль, на деяких серверах набір підказок часто змінюється!

Можливо, вам знадобиться кілька разів зареєструватися, використовуючи minicom, щоб зрозуміти, що відбувається, і знайти стійку очікуванурядок.

15.5 Сценарій chat для з'єднання PAP/CHAP

Якщо ваш ISP використовує PAP/CHAP, ваш сценарій chat набагато простіший.

Весь ваш сценарій chat повинен робити ось що: дзвонити за номером телефону, чекати на з'єднання і потім дозволити pppd обробити реєстрацію в системі!

#!/bin/sh # # Цей пункт 2 з Ppp-on script. It will perform the connection # protocol for the desired connection. # exec /usr/sbin/chat -v \ TIMEOUT 3 \ ABORT "\nBUSY\r" \ ABORT "\nNO ANSWER\r" \ ABORT "\nRINGING\r\n\r\nRINGING\r" \ "" \ rAT \ "OK-+++\c-OK" ATH0 \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT "" \

15.6 Налагодження pppd та опція file option_file

Як ми вже бачили, ви можете включити налагоджувальну інформацію опцією -d pppd . Опція debug еквівалентна їй.

Оскільки ми встановлюємо нове з'єднання з новим скриптом, поставте опцію налагодження.

Якщо у вас мало дискового простору, то логи pppd можуть швидко збільшити файл syslog і створити вам проблему.

Як тільки ви порадієте, що все працює правильно, можете видалити цю опцію.

Якщо ви назвали ваш ppp файл опцій інакше, ніж /etc/ppp/options , або /etc/ppp/options.ttySx , визначте ім'я файлу опцією file в pppd , наприклад

Exec /usr/sbin/pppd debug file options.myserver /dev/ttyS0 38400 \