Маленькие хитрости BASH

useradd by list tricks directory list file read bash пакетное добавление пользователей openssl password

Как получить имя файла без расширения и расширение без имени файла

# FILE=example.tar.gz

# echo "${FILE%%.*}"
example

# echo "${FILE%.*}"
example.tar

# echo "${FILE#*.}"
tar.gz

# echo "${FILE##*.}"
gz

Остановка bash скрипта до нажатия любой клавиши

$ read -sn1 -p "Press any key to continue..."; echo

Обозначить группу при назначении прав при помощи точки (ставит ту-же группу, что и хозяин)

chown -R www-data. /home/webdav

Считываем файл построчно

Вариант 1.

#!/bin/bash
file="data.lst"
while IFS= read -r line
do
  echo "$line"
done <"$file"

Вариант 2.

#!/bin/bash
file="data.lst"
while read line
do
  echo "$line"
done < $file

Как вывести только чистый список каталогов?

find /home -maxdepth 1 -type d -printf '%fn'

или более тривиальное решение:

ls -l | grep drw | awk {'print $9'}

Пакетное добавления пользователей FTP по списку

Здесь применен пример организации счетчика, работа со списком из файла, выполнение арифметических операций и вычисления хэша пароля linux.

#!/bin/bash
users="users.lst"
count=0
while read users
do
   count=$[$count+1]
   curpass=`openssl passwd -crypt -quiet m2b-es6$count`
   echo $count $users $curpass
   useradd -d /ftp/cat/clients/crimea -g 1004 -s /usr/sbin/nologin -M -p $curpass $users
done < $users

Генерация MAC-адреса

Вариант 1:

function generate_mac ()  {
  hexchars="0123456789abcdef"
  echo "24:df:86$(
    for i in {1..6}; do
      echo -n ${hexchars:$(( $RANDOM % 16 )):1}
    done | sed -e 's/(..)/:1/g'
  )"
}

Вариант 2:

openssl rand -hex 6 | sed 's/(..)/1:/g; s/:$//'

Генерация пароля

openssl rand -base64 12

Удаление файлов старше N-дней

Будьте осторожны - все отобранные поиском файлы будут удалены!

Вариант 1:

find /somewhere -type f -mtime +7 -exec _rm  -f {} \;
В рабочем примере _rm надо заменить на rm

Вариант 2:

find /somewhere -type f -mtime +7 -print0 | xargs -0 _rm -f

Вариант 3 (prod):

echo "Чистим файлы с дневными архивами старше 10-ти дней"
/usr/bin/find ${syst_dir}${bkp_dir_1}/current/ -maxdepth 1 -type f -mtime +10 -exec rm -rf {} \;
/usr/bin/find ${syst_dir}${bkp_dir_2}/current/ -maxdepth 1 -type f -mtime +14 -exec rm -rf {} \;

Выбрать 2-ую строку из файла

awk 'BEGIN { RS = "" ; FS = "n" } {print $2}' ~/sh/.chklist

Суммирование строк в файле

sum=0
while read n; do
    sum=$(( $sum + n ))
done < numbers.list
echo $sum

Пример рекурсии (вызов функции из самой себя)

#!/bin/bash
printstr(){
  echo "hello world"
  printstr
}

  printstr

Происходит бесконечный цикл. Для выхода Ctrl+C

Локальные переменные

Если вы объявите обычную переменную в функции, то она будет доступной во всем скрипте, это удобно для возврата значения функции, но иногда может понадобиться сделать локальную переменную.

#!/bin/bash
printstr(){
local VAR=$1
echo ${VAR}
}

printstr $1

Простой интерактивный калькулятор

#!/bin/bash
read -p "Enter the first  value: " x
read -p "Enter the second value: " y

add() {
    arg1=$1 #arg1 gets to be the first  assigned argument (note there are no spaces)
    arg2=$2 #arg2 gets to be the second assigned argument (note there are no spaces)

    echo $(($arg1 + $arg2))
}

add x y #feeding the arguments

Повтор последнего аргумента

Например, переход в только-что созданный каталог

mkdir /var/www/htdocs
cd !$

Повтор команды history по ее номеру

!23

Проверка задания аргумента и соответствия значению

if [ $# -eq 0 ] ; then
    RESF=$BASEP/.savelist;
    #exit 1;
else
     if [ $1 = "1" ]; then
        RESF=$BASEP/.savelist_single
        echo "Savior launched in single job mode "
      else
       RESF=$BASEP/.savelist
     fi
fi

Если аргумент задан и равен 1, то программы работает по файлу .savelist_single, 

в противном случае - по файлу .savelist.

Сформировать случайную строку заданной длины (например,  salt)

head -c 32 /dev/random | base64
s2Qu2IVjSsAIVUSUjP0lpOMjiI3JTWgt4hDc7ZlM6mA=

Работает долго.

Экспорт функций/exec

Вы можете сделать функцию доступной вне скрипта с помощью команды declare:

!/bin/bash
printstr(){
echo "hello world"
}
declare -x -f printstr

Затем запустите скрипт с помощью команды source:

source function.sh
$ printstr

Проверка, установлен ли пакет в системе

if  [[ -z $(dpkg -l | grep xemacs21-bin) ]]; then
    apt-get -y install xemacs21-bin
  else
    echo 'package present in system'
fi

Вычислить длину строки

myvar="some string"
echo ${#myvar}  
# 11

Пакетное переименование файлов в bash

for ff in *.jpe; do mv $ff ${ff%.*}.jpg ; done

Разделение файла на имя и расширение

filename=$(basename -- "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"

Выделение подстроки (срез)

В bash можно легко выделить подстроку, используя оператор среза : Например, убрать из имени интерфейса все символы, кроме первых 14-ти:

port_id=$(openstack port list --device-owner network:dhcp --network provider -f value | awk '{ print $1}')
interface_long="tap$port_id"
interface=${interface_long:0:14}
echo $interface_long
echo $interface

На выходе получим:

tap1b089682-83e1-4b57-8135-d40ea85d4d0f b20b6df7-9273-448f-8450-afc0e5e253c5 f60f45c7-bc97-46a2-9b47-ec4d39d795de
tap1b089682-83

Обновлено: 29.02.2024