Ответы пользователя по тегу bash
  • Как в bash из массива удалить элемент c с конкретным значением?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    lngList=("${lngList[@]/none/}")
    Ответ написан
    Комментировать
  • Как передать массив в Bash-скрипт?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    test.sh
    #!/usr/bin/env bash
    
    Langs=($@)
    
    for lang in "${Langs[@]}"; do
      echo "lang[$((i++))]=$lang"
    done


    $ ./test.sh ru en de
    lang[0]=ru
    lang[1]=en
    lang[2]=de
    Ответ написан
    2 комментария
  • Как добавить имя текстового файла в сам файл первой строчкой?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    awk -i inplace 'BEGIN{getline;print FILENAME"\n"$0}{print}' ФАЙЛ
    Ответ написан
    Комментировать
  • Как отформатировать вывод из json?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    $ echo '{ "exitcode" : 0, "exited" : 1, "out-data" : "Filesystem Size Used Avail Use% Mounted on\nudev 2.3G 0 2.3G 0% /dev\ntmpfs 479M 672K 478M 1% /run\n/dev/mapper/pmg-root 28G 2.7G 24G 11% /\ntmpfs 2.4G 1.1M 2.4G 1% /dev/shm\ntmpfs 5.0M 0 5.0M 0% /run/lock\n" }' | jq -r '."out-data"' | column -t
    
    Filesystem            Size  Used  Avail  Use%  Mounted    on
    udev                  2.3G  0     2.3G   0%    /dev       
    tmpfs                 479M  672K  478M   1%    /run       
    /dev/mapper/pmg-root  28G   2.7G  24G    11%   /          
    tmpfs                 2.4G  1.1M  2.4G   1%    /dev/shm   
    tmpfs                 5.0M  0     5.0M   0%    /run/lock
    Ответ написан
    Комментировать
  • Как в bash создать динамический select?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    можно как вариант использовать jless, там тебе и json-меню и копирование данных, хотя с копированием там у некоторых наблюдаются проблемы.

    другой вариант, это вместо баш-партянки взять тот же fzf и скормить ему одноранговое меню доступных вариантов что позволит легко отсортировать и выделить необходимое
    cat sites.json | jq -r '.sites[] | "\(.title)\tadmin\t\(.admin[])\n\(.title)\tfront\t\(.front[])"' | sort -u | fzf -m --delimiter "\t" --nth 1,2 | awk '{print $3}'

    мультивыделение срабатывает по табу
    довольно удобно для небольших меню
    в целом это будет выглядеть примерно так
    zDboUomqo5lzjUJrHf2Lcsaqr.svg
    Ответ написан
    1 комментарий
  • Скрипт который прерывается если в директории есть 2 файла с похожим названием?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Пример, в /home/user лежат файлы test14 test12 test123 test1234. Необходимо чтобы скрипт проверил директорию, и в случае если в ней лежит только один файл test14 завершился успешно, а если в ней находятся файлы указанные выше, то прерывался.


    случайный набор цифр после слова test


    скрипт, строчка, вставить
    (( $(ls /home/user |grep -c ^test) > 1 )) && exit
    Ответ написан
    Комментировать
  • Как добавить параметр OK/NOTOK в конце вывода?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Есть команда показывающая кол-во подключенных ЮСБ к серверу и их наименование

    у вас лишь немного модифицированная команда lsusb, а она выводит
    lsusb is a utility for displaying information about USB buses in the system and the devices connected to them.

    то есть помимо самих подключенных usb-устройств выводит и шины на которых они висят.
    Не знаю по какому принципу вы будете определять где ставить OK а где NO в выводе lsusb, но если вам нужно в цвете плюс вставить внешний параметр в awk то будет выглядеть примерно так:
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    NORMAL='\033[0m'
    
    OK="${GREEN}OK${NORMAL}"
    NO="${RED}NO${NORMAL}"
    
    lsusb |awk -v ok="$OK" -v no="$NO" '{print $3" "$4" - "$7" "$8" "$9" "no}'
    Ответ написан
    Комментировать
  • Как сгруппировать каталоги и подсчитать их размер?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    примерно так
    $ du -sb * |awk '{cmd="stat -c %z "$2" |cut -d\" \" -f1";cmd |getline z;close(cmd);print z" "$1}' |awk '{sum[$1]+=$2}END{for(i in sum)print i,sum[i]}' |sort |numfmt --to=iec --field 2 --padding=10
    2022-01-21        13M
    2022-11-02        17G
    2022-12-13       4,7G
    2023-01-15       388M
    2023-03-06       1,6G
    2023-04-01       1,6G
    2023-04-03       2,2G
    2023-04-04        13G
    2023-04-11       7,6G
    Ответ написан
    1 комментарий
  • Как изменить вывод баш скирпта?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    если у вас там команды с многострочным выводом, по типу файлов, то для того чтобы это вывести обычно нужно пройти два этапа:
    первый, это построчное объединение файлов/переменных с нужным разделителем
    второе, это уже непосредственный отформатированный вывод по указанному выше разделителю.
    рассмотрим ваш пример с командой hostnamectl
    для построчного объединения можно использовать стандартную утилиту paste
    paste file1 file2
    где вместо файлов подставим вывод наших команд
    paste <(hostnamectl) <(hostnamectl)
    но в таком виде оно просто сольёт строки, а нам их нужно как-то различать в одной строке, если внутри вывода команд не используется символ ';' то возьмём его в качестве разделителя, то есть нам нужно в конец file1(ну или вывода команды) добавить окончание в виде точки с запятой ';'
    делается это просто с помощью того же awk
    hostnamectl |awk '{print $0";"}'
    в общем виде будет выглядеть так:
    paste <(hostnamectl |awk '{print $0";"}') <(hostnamectl)


    то есть, по сути, мы получили структурированный текстовый формат по типу CSV/TSV с разделителем в виде ';'
    а вывести подобное довольно просто, так как для этого есть много разных консольных утилит, начиная от стандартной линуксовой column
    paste <(hostnamectl |awk '{print $0";"}') <(hostnamectl) | column -t -s';'

    и заканчивая внешней утилитой csview с рамочками и блэкджеком:
    paste <(hostnamectl |awk '{print $0";"}') <(hostnamectl) | csview -H -d';'

    хотя в последнем варианте можно сократить до
    paste <(hostnamectl) <(hostnamectl) | csview -H --tsv

    так как paste добавляет еще табуляцию как разделитель
    Ответ написан
    1 комментарий
  • Как в bash добавить строку в конце файла но перед определенной строке?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    если упростить, то нужно перед одной строкой вставить другую
    если делать через sed то
    STR1="echo get_template_part('template-parts/$1/$2')"
    STR2="<?php get_footer(); ?>"
    sed -i "/$STR2/i $STR1" FILE
    Ответ написан
    3 комментария
  • Как записать вводимые данные в определенном формате?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    while [[ $(wc -c <<< $MAC_IN) != 13 ]]; do
    	read -p "Please input MAC address : " # XX_XX:XX  XX-XX/XX
    	MAC_IN=$(echo -n "$REPLY"|sed 's/[^0-9a-fA-F]//g')
    done
    
    MAC=$(echo -n "$MAC_IN"|fold -w2 |tr '\n' ':')
    echo $MAC  # XX:XX:XX:XX:XX:XX:XX
    Ответ написан
    Комментировать
  • Как записывать в файл до тех пор пока есть место в нем?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Он как видно на 100049 байт.

    Мне нужно записывать в него строки ew=`cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 76` до тех пор пока он не заполнится полностью.

    то есть, у нас есть символы от A-Z a-z 0-9 каждый из которых занимает 1 байт
    нужно записывать строки с 76 символами + 1 символ перевода строки
    по итогу получим

    100049/77 = 1299 полных строк и немного хвоста
    размер хвоста
    100049-1299*77 = 26 символов

    если всё это перевести в bash-код то получим следующее
    #!/usr/bin/env bash
    
    #вводные
    FILE=file.txt
    S=100049 # общий размер в байтах
    s=76   # максимальное количество однобайтовых символов на строку
    
    N=$[S/(s+1)]
    n=$[S-N*(s+1)]
    
    echo "Cтрок + хвост = $N + $n"
    
    rm -rf $FILE
    for (( i = 0; i < $N; i++ )); do
    	cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c $s >> $FILE
    	echo >> $FILE
    done
    cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c $n >> $FILE
    
    echo "Файл записан"
    echo "Размер файла $FILE = $(stat -c %s $FILE) байт"

    по итогу получим файл с необходимым объёмом данных
    Ответ написан
    Комментировать
  • Как объединить скрипты и сделать вывод таблицей?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    вы конечно мастер путанных вопросов, но в принципе понятно чего вы добиваетесь, поэтому просто приведу маленький пример, а там уже переделаете под свои нужды
    допустим у нас есть несколько файлов с результатами в виде одной строки
    как пример
    echo "ОК" > {biosinfo,meminfo,cpuinfo}.result
    создадим три файла которые содержат значение "OK"

    там же создадим скрипт results_table.sh
    #!/usr/bin/env bash
    
    FILEPATH_BIOSINFO_RESULT="biosinfo.result"
    FILEPATH_MEMINFO_RESULT="meminfo.result"
    FILEPATH_CPUINFO_RESULT="cpuinfo.result"
    
    BIOSINFO_RESULT=$(cat "$FILEPATH_BIOSINFO_RESULT")
    MEMINFO_RESULT=$(cat "$FILEPATH_MEMINFO_RESULT")
    CPUINFO_RESULT=$(cat "$FILEPATH_CPUINFO_RESULT")
    
    TABLE="TEST;RESULTS
    BIOS ver;$BIOSINFO_RESULT
    Memory;$MEMINFO_RESULT
    CPU;$CPUINFO_RESULT"
    
    echo "$TABLE" | csview -d";"

    здесь мы прописываем в переменную TABLE нужную нам информацию в виде текстового CSV формата, а затем с помощью утилиты csview выводим в виде таблицы

    результат работы скрипта
    ┌──────────┬─────────┐
    │ TEST     │ RESULTS │
    ├──────────┼─────────┤
    │ BIOS ver │ ОК      │
    │ Memory   │ ОК      │
    │ CPU      │ ОК      │
    └──────────┴─────────┘
    Ответ написан
    Комментировать
  • Как удалить все строки до n через sed?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    awk "NR>3" FILE
    вывести строки что больше 3

    awk -i inplace "NR>3" FILE
    где -i inplace перезаписывает файл, то есть по итогу в файле останутся строки начиная с четвертой

    N=3
    awk -i inplace "NR>$N"

    то же что и предыдущее, но с указанием номера строки через внешнюю переменную
    Ответ написан
    Комментировать
  • Как отловить пропажу интернета?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Единственное ли решение запускать bash скрипт через n количество времени, который пингует гугл и в зависимости от результата совершает действие?

    если интернет это обязательное наличие гугла то стучимся в их dns
    fping -r1 -q 8.8.8.8 && echo OK || echo NO
    ну и закинуть это в планировщик

    можно вместо гугла подобрать какой-то другой глобально доступный и более быстрый dns
    $ fping -e -r 1 -a -q 1.1.1.1 8.8.8.8 77.88.8.8 208.67.220.220
    1.1.1.1 (1.31 ms)
    8.8.8.8 (14.3 ms)
    208.67.220.220 (16.9 ms)
    77.88.8.8 (51.5 ms)

    которые соотвецтвуют
    CloudflareDNS
    GoogleDNS
    OpenDNS
    YandexDNS

    при желании можно простучать сразу по нескольким ресурсам
    fping -r1 -q 1.1.1.1 8.8.8.8 77.88.8.8 208.67.220.220 && echo OK || echo NO
    Ответ написан
    Комментировать
  • Как сравнить вывод скрипта с файлом?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    cmp -s <(./test.sh) test && echo 1||echo 0
    Ответ написан
    Комментировать
  • Почему не заменяет перенос строки на пробел?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    speedtest --simple |awk 'BEGIN{RS="";FS="\n"}{print $2" "$3}'

    где
    RS - разделитель строк
    FS - разделитель полей
    Ответ написан
    Комментировать
  • Как найти имя процесса НЕ содержащее в названии заданную строку при помощи bash?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    ps -ef |grep '^user1' |tr -s ' ' |cut -d ' ' -f 8- |grep -v user1

    а так как нам нужна тока первая и последняя колонки то
    ps -eo user,cmd |grep '^user1' |tr -s ' ' |cut -d ' ' -f 2- |grep -v user1

    хотя тут может возникнуть проблема c tr -s ' ' которая сокращает последовательность пробельных символов до одного пробела, а вдруг кто-то в имени додумается использовать больше одного пробела идущего в подряд или даже табуляцию ? хотя это визуально может и не важно, но всё же

    ps -eo user,cmd |grep '^user1' |cut -d ' ' -f 2- |sed 's/^[ \t]*//' |grep -v user1
    Ответ написан
    Комментировать
  • Как заменить нижнее подчеркивание на пробел в имени файла?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    find . -type f -name '*_*' -exec sh -c 'x="{}";mv "$x" "${x//_/ }"' \;
    Ответ написан
    Комментировать
  • Как переименовать файлы в bash используя регулярные выражения?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    если в папке только картинки то можно сделать просто
    for i in `ls`;do mv "$i" $[x++].jpg ;done
    Ответ написан
    7 комментариев