Некоторые картинки не загружаются из РФ и РК, используйте VPN.
Показаны сообщения с ярлыком bash. Показать все сообщения
Показаны сообщения с ярлыком bash. Показать все сообщения

суббота, 11 мая 2024 г.

RPi подключаем модем для обработки USSD и SMS

Ниже описан полный путь. В какой то момент я купил новый модем, но у него оказался API без поддержки USSD и я вернулся к старому. Поэтому не взыщите за столь длинный эпос

yser@rpi02:~ $ lsusb
Bus 001 Device 007: ID 12d1:1001 Huawei Technologies Co., Ltd. E161/E169/E620/E800 HSDPA Modem
Bus 001 Device 004: ID 0d9f:00a7 Powercom Co., Ltd   UPS  KIN-2200AP       FW3.A7
Bus 001 Device 005: ID 0d9f:0002 Powercom Co., Ltd Black Knight PRO / WOW Uninterruptible Power Supply (Cypress HID->COM RS232)
Bus 001 Device 006: ID 0424:7800 Microchip Technology, Inc. (formerly SMSC)
Bus 001 Device 003: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
user@rpi02:~ $ cat lsusb_ext.sh
#!/bin/bash

for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
    (
        syspath="${sysdevpath%/dev}"
        devname="$(udevadm info -q name -p $syspath)"
        [[ "$devname" == "bus/"* ]] && exit
        eval "$(udevadm info -q property --export -p $syspath)"
        [[ -z "$ID_SERIAL" ]] && exit
        echo "/dev/$devname - $ID_SERIAL"
    )
done

user@rpi02:~ $ ./lsusb_ext.sh
/dev/ttyUSB2 - HUAWEI_Technology_HUAWEI_Mobile
/dev/ttyUSB3 - HUAWEI_Technology_HUAWEI_Mobile
/dev/ttyUSB1 - HUAWEI_Technology_HUAWEI_Mobile
/dev/ttyUSB0 - POWERCOM_CO.__LTD._USB_to_Serial

Исполнить правила devrul без перезапуска/перевыдергивания

sudo udevadm control --reload-rules && sudo udevadm trigger

Чего то с тем модемом не взлетело. Купил E3372h-153, вроде как с ним должно быть проще, но нет

пятница, 23 февраля 2024 г.

Bash скрипт заметка

Заметка скрипт.

Интересный моменты в скрипте:

  1. Вызов функции из себя как вариант цикличности, а не рекурсии
  2. $EUID -ne 0
    Проверка на наличие root прав у текущего пользователя
  3. echo -e "[User]\nSystemAccount=true"> /var/lib/AccountsService/users/$AdminName
    Скрытие учетки в *nix-подобных системах (сервисный аккаунт)
  4. logname
    Получение имени залогинившегося пользователя, даже если он под sudo
  5. eval getent passwd {$UID_MIN..$UID_MAX} 
    eval - преобразует текст в команду
  6. getent passwd {1000..6000} | cut -d: -f1
    получение списка пользователей с UID между 1000-6000, все сервисные аккаунты имеют UID < 1000
  7. blkid -U "$(grep -vE "^#|^$" /etc/crypttab | tail -n1 | cut -d" " -f1 | cut -d"-" -f2-)"
    LUKS иногда создает устройство с именем равным LUKS-UUID_source_block_device, но вот получить именно адрес в виде /dev/sda3 не так просто
Задачи скрипта:
  1. Проверить наличие определенного пользователя
  2. Создать администратора, при его отсутствии
  3. Переименовать выбранного пользователя
  4. Сбросить ID Anydesk
  5. Изменить passphrase для шифрованного раздела
  6. Переименовать ПК
Для чего такое надо?, для клонирования подготовленной системы

среда, 24 мая 2023 г.

"/bin/bash^M: bad interpreter: No such file or directory"

 Данная ошибка связана с форматом переноса строк, лично у меня первый раз возникла, ибо я редко переношу свои скрипты на сервер файлом, чаще копипастом. Если формируете скрипт SH на Mikrotik, то получите такую же ошибку, так как он использует формат конца строк CR LF


понедельник, 27 февраля 2023 г.

Bash вывод строк ниже опеределенной

Банальная задача - вывести строки из файла от N до конца, но tail такое не может. Можно конечно заморочиться примерно так:

num_line=550
current_count_lines=`cat $file | wc -l`
let tail_count=$x-$num_line
tail -n $tail_count $file

Вполне рабочий вариант, если бы не одно но - мне надо вызывать его раз в 3-15 сек для обработки лога, который быстро растет и какова вероятность, что к моменту проведения всех рассчетов, количество строк в файле изменится?, а если измениться, то $tail_count выведет не те строки

И тут выясняется, что awk может решить поставленную задачу, дык еще и в одну строку:

awk "NR>$num_line" $file

Собственно вместо знака больше/меньше можно поставить равно, тогда такая конструкция

awk "NR=2" $file

Дает такой же результат как и эта:

head -n 2 $file | tail -n 1

четверг, 9 февраля 2023 г.

Bash заметки по даты-время

Получить разницу дат в секундах

user@server:~$ old_time=$(date +%s)
user@server:~$ new_time=$(date +%s)
user@server:~$ echo $old_time $new_time
1675929074 1675929084
user@server:~$ date -d @${old_time}
Чт фев  9 10:51:14 MSK 2023
user@server:~$ date -d @${new_time}
Чт фев  9 10:51:24 MSK 2023
user@server:~$ let diff_date=$new_time-$old_time
user@server:~$ echo $diff_date
10

Если разница укладывается в 24 часа, то секунды можно перевести в удобочитаемый вид

user@server:~$  date -u -d @${diff_date} +"%T"
00:00:10

Стоит обратить внимание на параметр -u, который определяет что зона у нас UTC, иначе ответ будет считать плюс текущую зону, т.е. в мое случае +3 часа

user@server:~$ date -d @${diff_date} +"%T"
03:00:10

А вот разницу мы ранее считали без параметра -u, но можно и с.

Если же разница более суток и нужен красивый вывод, то можно представить в следующем варианте

user@server:~$ date -u -d @${diff_date} +"%j day %T"
001 day 00:00:10

Или просто в часах:

user@server:~$ diff_time=15654
user@server:~$ hours=$(echo "scale=0; $diff_time/3600" | bc);
user@server:~$ minute=$(echo "scale=0; ($diff_time-($hours*3600))/60" | bc); 
user@server:~$ sec=$(echo "$diff_time-($hours*3600)-($minute*60)" | bc);
user@server:~$ printf "%s:%0*d:%0*d\n" $hours 2 $minute 2 $sec
4:20:54

вторник, 7 февраля 2023 г.

Sendmail cat пустое тело или нет первой строки

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


Не обращаем внимание на косяк с CURRENT_TIME_FORMATE

вторник, 3 января 2023 г.

Bash script WOL для списка

На одном из объектов бэкап построен на базе bash скриптов, списком копируемых к нему выступает файл с таким содержимым:
user@server:~$ head -n 2 /opt/scripts/backup/compoff.txt
#Номер;Имя ПК;имя пользователя;айпи (не обязательно);мак адрес;выключать или нет
1;AIVANOV;aivanov;10.21.2.140;D8:BB:C1:5B:6E:5D;1

Собственно сам скрипт обходит список, шлет WOL, ожидает и проверяет по пингу включился ли ПК, если да, то помещается в массив для обработки, иначе репорт на почту. Хорошо работает вот уже лет 7. Но иногда есть потребность во включении определенного ПК из этого списка, и дабы автоматизировать поиск, отправку WOL и проверку, написал скрипт. Также нужно учесть то, что компьютеры находятся в разных сегментах сети, поэтому посыл будет с двух серверов.

Bash script обход аргументов скрипта/функции

Ранее такой фокус провернул на Mikrotik, там проблема была в том, что неизвестно количество входящих аргументов. В bash есть специальная переменная $#, которая содержит количество параметров. Кстати, правильной проверкой будет именно:

if [ $# -ne 0 ]
then
	echo "Run script"
else
	exit
fi

а не:

# -n "$1" - вернет истина, если длина более 0
if [ -n "$1" ]
then
	echo "Run script"
else
	exit
fi

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

if [ $# -gt 2 ]
then
	echo "Run script"
else
	echo "less than 2 arguments"
	exit
fi

Собственно знание количества аргументов позволяет описать обход так:

if [ $# -ne 0 ]
then
	echo "Set is $# arg"
    for (( a = 1; a <= $#; a++ ))
    	arg=$(eval echo \$$a)
        echo $arg
    done
else
	exit
fi

Пример выше обработает только 9 параметров, для обработки большего количества необходимо номер поместить в фигурные скобки

if [ $# -ne 0 ]
then
	echo "Set is $# arg"
    for (( a = 1; a <= $#; a++ ))
    	arg=$(eval echo \${$a})
        echo $arg
    done
else
	exit
fi

Такую конструкцию можно использовать например в скрипте с поиском шаблона/шаблонов

Также не стоит забывать о наличии $* - все аргументы строкой и $@ - все аргументы "массивом"

if [ $# -ne 0 ]
then
	echo "Set is $# arg"
    count=1
	for param in "$@"
	do
		echo "\$@ Parameter #$count = $param"
		count=$(( $count + 1 ))
	done
else
	exit
fi

Подглядел на хабре

пятница, 16 декабря 2022 г.

Bash Console Script Фигурные скобки

"А так можно было?" - подумал я увидя такую конструкцию:

user@server:~$ mv /etc/postfix/{canonical,sender_relay,sasl_passwd} /etc/postfix/private/

Или так (переимновать без ввода полного пути)

user@server:~$ mv /etc/postfix/main.cnf{,.back}

Или так (создать копию без повторного ввода всего пути)

user@server:~$ cp /etc/postfix/main.cnf{,.back}
user@server:~$ ls /etc/postfix/main*
/etc/postfix/main.cf  /etc/postfix/main.cf.back  /etc/postfix/main.cf.db  /etc/postfix/main.cf.proto  /etc/postfix/main.cf.proto.db  /etc/postfix/main.cf.save

С того момента я каждый раз тратил много времени на попытку вспомнить конструкцию и вот решил устаканить в своей голове фигурные скобки в консоли линукс-подобных систем. При повседневных операциях бывает необходимо повторить одно действие несколько раз и как же бесит когда не можешь упростить. Перейдем к примерам - скопировать из каталогов несколько разных файлов можно разными способами:

user@server:~$ ls ~/test
folder_1 folder_2 file_1 file_2 file_1_bak file_2_bak

user@server:~$ cp ~/test/file_1 ~/test/file_1_bak /new_folder
user@server:~$ ls /new_folder
file_1 file_1_bak

user@server:~$ rm /new_folder/*
user@server:~$ cp ~/test/file_1* /new_folder
user@server:~$ ls /new_folder
file_1 file_1_bak

user@server:~$ rm /new_folder/*
user@server:~$ cp ~/test/file_{1,1_bak} /new_folder
user@server:~$ ls /new_folder
file_1 file_1_bak

user@server:~$ rm /new_folder/*
user@server:~$ cp ~/test/file_1{,_bak} /new_folder
user@server:~$ ls /new_folder
file_1 file_1_bak

четверг, 1 декабря 2022 г.

Bash script аналог удаления файлов видеорегистратора

Удаление N старых файлов если объем занятого пространства на диске больше n

#!/bin/bash
# проверка наличия другого запущенного экземпляра
nameScript=$(basename "$0")
if [ "$(pgrep -c "$nameScript")" -gt 1 ]
then
	echo  "Script is run"
	exit
fi
# переменные, можно переделать в параметры
# каталог из которого удаляем файлы
directory=/home/tmk/testrm
# диск у которого проверяем объем
disk=/dev/sda
# глубина поиска файлов в каталоге (избавляемся от рекурсии)
depth=1
# количество файлов к удалению за один проход
amount=10
# лимит занятого простратнства (триггер)
MaxLimit="70"

# вариант IF EXIST, если перети не удалось, значит каталог или не существует или доступа туда нет, и выходим
cd "$directory" || exit
# Пока занятоно места больше $MaxLimit, удаляем старые данные в папке.
while [ "$(df -m | grep $disk | awk '{print $5}' | sed 's/%//g'))" -lt "$MaxLimit" ] 
do
# Если в каталоге, при необъходимой глубине, нет файлов, то на выход
	if [ "$(find "$directory" -type f -maxdepth $depth | head -n $amount)" != "" ]
	then
		# Ищем в той самой папке файлы, выводим с датой, сортируем по дате и удаляем первые в списке (самые старые) по $amount штук
        # т.к. перевод строки = \n, то использовать -0 для xargs не имеет смысла
		find "$directory" -maxdepth $depth -type f -printf "%T@ %p\n" | sort -n | cut -d" " -f2- | sed 's/ /\\ /g' | head -n $amount | xargs rm
	else
		echo "Free space is low, but directory is empty" 
		break
	fi
done


Bash script проверить наличие другого экземпляра и выйти

Самопроверка скрипта на наличие в процессах

#!/bin/bash
nameScript=$(basename "$0")
if [ "$(pgrep -c "$nameScript")" -gt 1 ]
then
	echo  "Script is run"
	exit
fi

Или (случайно нашел в интернетах 12/04/2024)

#!/bin/bash
instances=`lsof -t "$0" | wc -l`
if (( $instances > 1 )); then exit 1; fi

Вариант для mikrotik