Рубрики
bash

bash scripts

link:

https://www.opennet.ru/docs/RUS/bash_scripting_guide/c118.html

1.

Напишите сценарий, который выводит дату, время, список зарегистрировавшихся пользователей, и uptime системы и сохраняет эту информацию в системном журнале.

тупо:
cat > 1.sh << "EOF"
#!/bin/bash
#set -x
LOG="log.txt"
echo "Текущая дата:" >> $LOG
date >>  $LOG
echo "" >> $LOG
echo "Пользователи в системе:" >>$LOG
w >> $LOG
echo "" >> $LOG
echo "Нагрузка на систему:" >> $LOG
uptime >> $LOG
echo "" >> $LOG
EOF


доработаем:
cat > 1m.sh << "EOF"
#!/bin/bash
#set -x
LOG="log.txt"

i=zero
for i in date w uptime; do
if [[ "$i" == "date" ]]; then
    echo "Текущая дата:" >> $LOG
    $i >>  $LOG
elif [[ "$i" == "w" ]]; then
    echo "Пользователи в системе:" >>$LOG
    $i >>  $LOG
elif [[ "$i" == "uptime" ]]; then
    echo "Нагрузка на систему:" >> $LOG  
    $i >>  $LOG
fi    
done
EOF

Доработаем еще:
cat > 1mm.sh << "EOF"
#!/bin/bash
#set -x
LOG="log.txt"

# Определяем заголовки как переменные
date_header="Текущая дата:"
w_header="Пользователи в системе:"
uptime_header="Нагрузка на систему:"

# Очищаем лог перед записью
###> "$LOG"

for command in date w uptime; do
    # Получаем имя заголовка динамически
    header_var="${command}_header"
    
    # Выводим заголовок
    echo "${!header_var}" >> "$LOG"
    
    # Выполняем команду
    $command >> "$LOG"
done
EOF


Доработаем еще и еще:
cat > 1mmm.sh << "EOF"
#!/bin/bash
LOG="log.txt"
#> "$LOG"

declare -A headers=(
    [date]="Текущая дата:"
    [w]="Пользователи в системе:"
    [uptime]="Нагрузка на систему:"
)

for cmd in date w uptime; do
    echo "" >> "$LOG"
    echo "${headers[$cmd]}" >> "$LOG"
    $cmd >> "$LOG"
done
EOF

Специальное назначение некоторых экранированных символов используемых совместно с echo и sed:

\n перевод строки (новая строка)
\r перевод каретки
\t табуляция
\v вертикальная табуляция
\b забой (backspace)
\a "звонок" (сигнал)
\0xx ASCII-символ с кодом 0xx в восьмеричном виде)

завершение / код завершения

echo hello
echo $?    # код возврата = 0, поскольку команда выполнилась успешно.
lskdf      # Несуществующая команда.
echo $?    # Ненулевой код возврата, поскольку команду выполнить не удалось.
echo
exit 113   # Явное указание кода возврата 113.
           # Проверить можно, если набрать в командной строке "echo $?"
           # после выполнения этого примера.
#  В соответствии с соглашениями, 'exit 0' указывает на успешное завершение,
#+ в то время как ненулевое значение означает ошибку.


Использование символа ! для логической инверсии кода возврата:

true  # встроенная команда "true".
echo "код возврата команды \"true\" = $?"     # 0
! true
echo "код возврата команды \"! true\" = $?"   # 1
# Обратите внимание: символ "!" от команды необходимо отделять пробелом.
#    !true   вызовет сообщение об ошибке "command not found

Операции проверки файлов:

Возвращает true если...
-e файл существует
-f обычный файл (не каталог и не файл устройства)
-s ненулевой размер файла
-d файл является каталогом
-b файл является блочным устройством (floppy, cdrom и т.п.)
-c файл является символьным устройством (клавиатура, модем, звуковая карта и т.п.)
-p файл является каналом
-h файл является символической ссылкой
-L файл является символической ссылкой
-S файл является сокетом
-t файл (дескриптор) связан с терминальным устройством
   Этот ключ может использоваться для проверки -- является ли файл стандартным устройством ввода stdin ([ -t 0 ]) или стандартным устройством вывода stdout ([ -t 1 ]).
-r файл доступен для чтения (пользователю, запустившему сценарий)
-w файл доступен для записи (пользователю, запустившему сценарий)
-x файл доступен для исполнения (пользователю, запустившему сценарий)

-g
  set-group-id (sgid) флаг для файла или каталога установлен
  Если для каталога установлен флаг sgid, то файлы, создаваемые в таком каталоге, наследуют идентификатор группы каталога, 
  который может не совпадать с идентификатором группы, 
  к которой принадлежит пользователь, создавший файл. Это может быть полезно для каталогов, в которых хранятся файлы, 
  общедоступные для группы пользователей.

-u
   set-user-id (suid) флаг для файла установлен
   Установленный флаг suid приводит к изменению привилегий запущенного процесса на привилегии владельца исполняемого файла. 
   Исполняемые файлы, владельцем которых является root, с установленным флагом set-user-id запускаются с привилегиями root, даже если их запускает обычный пользователь. 
   [1] Это может оказаться полезным для некоторых программ (таких как pppd и cdrecord), которые осуществляют доступ к аппаратной части компьютера. 
   В случае отсутствия флага suid, программы не смогут быть запущены рядовым пользователем, не обладающим привилегиями root.
                -rwsr-xr-t    1 root       178236 Oct  2  2000 /usr/sbin/pppd
   Файл с установленным флагом suid отображается с включенным флагом s в поле прав доступа.

-k 
   флаг sticky bit (бит фиксации) установлен
   Общеизвестно, что флаг "sticky bit" -- это специальный тип прав доступа к файлам. 
   Программы с установленным флагом "sticky bit" остаются в системном кэше после своего завершения, обеспечивая тем самым более быстрый запуск программы. 
   [2] Если флаг установлен для каталога, то это приводит к ограничению прав на запись. Установленный флаг "sticky bit" отображается в виде символа t в поле прав доступа.
                 drwxrwxrwt    7 root         1024 May 19 21:26 tmp/
    Если пользователь не является владельцем каталога, с установленным "sticky bit", но имеет право на запись в каталог, 
    то он может удалять только те файлы в каталоге, владельцем которых он является. 
    Это предотвращает удаление и перезапись "чужих" файлов в общедоступных каталогах, таких как /tmp.

-O  вы являетесь владельцем файла
-G  вы принадлежите к той же группе, что и файл
-N  файл был модифицирован с момента последнего чтения
f1 -nt f2 файл f1 более новый, чем f2
f1 -ot f2 файл f1 более старый, чем f2
f1 -ef f2 файлы f1 и f2 являются "жесткими" ссылками на один и тот же файл

! "НЕ" -- логическое отрицание (инверсия) результатов всех вышеприведенных проверок (возвращается true если условие отсутствует).


[ $# -eq 0 ] && directorys=`pwd` || directorys=$@

Операции сравнения:

Сравнение целых чисел:
-eq равно
    if [ "$a" -eq "$b" ]

-ne не равно
    if [ "$a" -ne "$b" ]

-gt больше
    if [ "$a" -gt "$b" ]

-ge больше или равно
    if [ "$a" -ge "$b" ]

-lt меньше
    if [ "$a" -lt "$b" ]

-le меньше или равно
    if [ "$a" -le "$b" ]

< меньше (внутри двойных круглых скобок )
    (("$a" < "$b"))

<= меньше или равно (внутри двойных круглых скобок)
    (("$a" <= "$b"))

> больше (внутри двойных круглых скобок)
    (("$a" > "$b"))

>= больше или равно (внутри двойных круглых скобок)
    (("$a" >= "$b"))


Сравнение строк:
= равно
   if [ "$a" = "$b" ]

== равно
   if [ "$a" == "$b" ]

Синоним оператора =.
    [[ $a == z* ]]    # истина, если $a начинается с символа "z" (сравнение по шаблону)
    [[ $a == "z*" ]]  # истина, если $a равна z*
    [ $a == z* ]      # имеют место подстановка имен файлов и разбиение на слова
    [ "$a" == "z*" ]  # истина, если $a равна z*

!= не равно
    if [ "$a" != "$b" ]

Этот оператор используется при поиске по шаблону внутри [[ ... ]].

< меньше, в смысле величины ASCII-кодов
    if [[ "$a" < "$b" ]]
    if [ "$a" \< "$b" ]
    Обратите внимание! Символ "<" необходимо экранировать внутри [ ].

> больше, в смысле величины ASCII-кодов
    if [[ "$a" > "$b" ]]
    if [ "$a" \> "$b" ]
Обратите внимание! Символ ">" необходимо экранировать внутри [ ].
См. Пример 25-6 относительно применения этого оператора сравнения.

-z строка "пустая", т.е. имеет нулевую длину
-n строка не "пустая".