Ответы пользователя по тегу bash
  • Как сложить числа от x до y на bash?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    9 класс, арифметическая прогрессия
    # b >= a
    read -p "число 1: " a
    read -p "число 2: " b
    echo $[(a+b)*(b-a+1)/2]
    Ответ написан
    2 комментария
  • Bash - как вывести только первое слово?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    изначально строка очень длинная, но мне из нее нужно выдернуть только значение 674256, 674262 и т.д. чтобы они были без знака # и каждая с новой строки - в оригинале они со знаком #

    $ echo "#674256 10745127/2 name #674262 10745127/3 name #674268 10745127/4 name #674274 10745127/5 name #674280 10745127/6 name" | awk 'BEGIN{RS="#"}{print $1}'
    
    674256
    674262
    674268
    674274
    674280
    Ответ написан
    Комментировать
  • Как правильно составить небольшой bash скрипт по созданию пользователей?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    такое ощущение что условие неполное, поэтому немного усложню, а при желании вы легко можете упростить скрипт до нужного результата
    Предположим что нужно создать N пользователей(от 1 до N) и задать пароль к ним и всё это с соответствующей числовой приставкой . То есть, написать скрипт который на вход получает базовое имя и пароль, а также количество пользователей которых нужно создать.
    допустим имя скрипта будет luser.sh
    #!/usr/bin/env bash
    
    USER=$1 # базовая часть имени пользователя
    PASS=$2 # базовая часть пароля
    N=$3    # количество пользователей
    for (( i = 1; i <= $N; i++ )); do
    	useradd "${USER}_$i" && $(echo "${USER}_$i:${PASS}_$i" |chpasswd)
    	echo "User ${USER}_$i added!"
    done

    пример работы скрипта:
    $ sudo ./luser.sh user pass 3
    User user_1 added!
    User user_2 added!
    User user_3 added!

    проверим что пользователи с основанием в имени user действительно создались:
    $ grep -e "^user" /etc/passwd
    user_1:x:1314:1314::/home/user_1:/bin/bash
    user_2:x:1315:1315::/home/user_2:/bin/bash
    user_3:x:1316:1316::/home/user_3:/bin/bash
    Ответ написан
    Комментировать
  • Как слайсить массив на баше?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    for ((i=0;i<${#array[@]};i=i+6));do echo ${array[@]:i:6};done
    Ответ написан
    Комментировать
  • Как локализовать скрипт на BASH?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    sk ( skim )
    get_lang=$(grep -rh папка/где/искать -e '^language=' | awk -F'=' '{print $2}' | sk)
    Ответ написан
    Комментировать
  • Получить для обработки цикла файлы по маске из папки отсортированые по дате?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    $LS="ls -t | grep database"
    for li in $LS
    do
    echo $li
    done


    первое
    неправильно указанна переменная при присвоении ей значения:
    $LS=...
    правильно будет:
    LS=...

    второе
    LS="ls -t | grep database"
    здесь вы переменной LS присваиваете строку, а нужно результат выполнения
    LS="$(ls -t | grep database)"

    в итоге должно получится как-то так:
    LS="$(ls -t | grep database)"
    for li in $LS
    do
    	echo $li
    done
    Ответ написан
  • Как получить распарсить и вернуть строку из функции bash?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    ох и запутанно вы объясняете, пол часа медитировал прежде чем примерно понять что вам нужно, хотя и то не уверен

    как написать функцию в bash, чтобы она принимала один аргумент, а внутри можно было этот аргумент (строку) распарсить и вернуть из неё число

    foo() {
    	foo_arg1="$1"
    	echo "$foo_arg1" | awk -F- '/^p-[[:digit:]]{1,}$/{printf $2}'
    }
    foo p-4 # вернет 4

    сделал регуляркой с проверкой на число после p-

    потом вызвать уже в блоке if при соответствующем условии myFunc $1
    код в if
    elif [[ $1 == 'p-"${2}"' ]]; then
      ...прочий конфиг --mark myFunc $2

    во первых, 'p-"${2}"' это будет именно строка p-"${2}" а не p-чтототам, так как тут обрамлено в одинарные кавычки, правильнее было бы условие написать так:
    [[ "$1" == "p-$2" ]]

    то есть примерно будет такой скрипт:
    #!/usr/bin/env bash
    
    arg1="$1"
    arg2="$2"
    
    foo() {
    	foo_arg1="$1"
    	echo "$foo_arg1" | awk -F- '/^p-[[:digit:]]{1,}$/{printf $2}'
    }
    
    if [[ "$arg1" == "p-$arg2" ]]; then
    	echo --mark $(foo $arg1)
    fi
    exit

    допустим назовем скрипт 0.sh, тогда
    ./0.sh p-4 4
    --mark 4
    ./0.sh p-4 5 # ничего не выведет так как p-4 неравно p-5
    Ответ написан
    6 комментариев
  • Как реализовать парсинг параметров, введённых в произвольном порядке?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    https://devhints.io/bash
    Getting options
    while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
      -V | --version )
        echo $version
        exit
        ;;
      -s | --string )
        shift; string=$1
        ;;
      -f | --flag )
        flag=1
        ;;
    esac; shift; done
    if [[ "$1" == '--' ]]; then shift; fi

    пример когда опции передаются в скрипт с параметром(-s | --string) и без(-V | --version и -f | --flag), правим под себя
    Ответ написан
    Комментировать
  • Можно ли вывести значение переменной http?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    x=$(awk -F'[ "]' '$1=="DocumentRoot"{print $3}' /etc/httpd/conf/httpd.conf)

    записали в переменную x нужное значение, а теперь выводим:
    $ echo $x
    /var/www/html
    Ответ написан
    Комментировать
  • Как сравнить значения в строках вывода и по условию выполнить скрипт?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    [[ $(sensors | awk '/Core/{i+=$3}END{print i/NR}') > 60 ]] && ./script.sh

    немного сократил ваш изначальный поиск температуры сделав всё через один awk + сделал через среднюю температуру всех ядер а не одного конкретного, думаю так будет правильнее.

    если вам всё же нужно не средняя а температура любого из ядер, то это довольно просто:
    [[ $(sensors | awk '/Core/{print $3}') > 60 ]] && ./script.sh

    при первом совпадении скрипт сработает
    Ответ написан
    Комментировать
  • Как сделать возможным вывод программы в консоль?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    если нужно в динамике - одновременно выводить на консоль, писать в файл и тут же сразу построчно анализировать поступающую информацию, то тут чуть сложнее, хоть и не немного, вот небольшой пример:
    работа через файл
    #!/usr/bin/env bash
    
    # функции бот1 и бот2 которые постоянно выводят рандомно числа от 0 до 9 с интервалом в 2 секунды
    bot1(){
    	while true; do
    		echo "Bot1: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    bot2(){
    	while true; do
    		echo "Bot2: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    # путь к лог-файлу куда будем писать логи от ботов
    LOG=/tmp/botsLog.txt
    
    # удаляем лог-файл (если ненужно то закоментирвоать)
    rm -rf $LOG
    
    # запускаем ботов в фоновом(&) режиме, 
    # а также начинаем выводит поступающую от них информацию на консоль и писать в общий лог-файл
    bot1 | tee -a $LOG &
    sleep 1
    bot2 | tee -a $LOG &
    
    # функция анализа лог-файла (потока)
    analysisLogs() {
    	# запускаем постоянное построчное чтение поступающих данных в функцию
    	while read -r data; do
    		# здесь мы задаём фильтры и то что выполнить если совпадёт условие
    		case "$data" in
    			"Bot1: 0" ) echo "Бот 1 выдал ноль"
    				;;
    			"Bot2: 0" ) echo "Бот 2 выдал ноль"
    				;;
    		esac
    	done
    }
    
    # tail выводит поступающие данные по мере роста лог-файла (мониторит)
    # в данном случае мы передаём появляющиеся данные из файла в функцию analysisLogs
    tail -f $LOG | analysisLogs 
    
    # это необходимо чтобы главная программа преждевременно не завершилась 
    # пока не завершаться запущенные в ней фоновые(&) потоки
    wait
    
    exit

    с комментариями думаю будет понятней
    ctrl+c завершить скрипт

    можно конечно и через переменную сделать но это будет не так красиво да и не по феншую, кстати здесь мы пишем в ОЗУ так как /tmp у большинства дистрибутивов примонтирован в оперативной памяти.

    Если же не хочется вообще писать данные на диск или в озу, так как логи обычно склонны к накоплению если их не чистить да или просто ненужны, то можно просто использовать именованный канал(FIFO-файлы) с которым можно работать как с файлом(читать/писать) но при этом он будет выступать просто в роли промежуточного буфера, для этого в нашей программе нужно поменять всего две строчки(создать именованный канал и вместо tail использовать обычный cat )
    работа через fifo-файл
    #!/usr/bin/env bash
    
    # бот1 и бот2 просто постоянно выводят рандомно числа от 0 до 9 с интервалом в 2 секунды
    bot1(){
    	while true; do
    		echo "Bot1: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    bot2(){
    	while true; do
    		echo "Bot2: $[RANDOM%10]"
    		sleep 2
    	done
    }
    
    # путь к лог-файлу куда будем писать логи от ботов
    LOG=/tmp/botsLog.txt
    
    # удаляем лог-файл
    rm -rf $LOG
    
    # создаём именованный канал (FIFO-файл)
    mkfifo $LOG
    
    # запускаем ботов в фоновом(&) режиме, 
    # а также начинаем выводит поступающую от них информацию на консоль и писать в общий fifo-файл
    bot1 | tee -a $LOG &
    sleep 1
    bot2 | tee -a $LOG &
    
    # функция анализа поступающих данных
    analysisLogs() {
    	# запускаем постоянное построчное чтение поступающих данных в функцию
    	while read -r data; do
    		# здесь мы задаём фильтры и то что выполнить если сработает условие
    		case "$data" in
    			"Bot1: 0" ) echo "Бот 1 выдал ноль"
    				;;
    			"Bot2: 0" ) echo "Бот 2 выдал ноль"
    				;;
    		esac
    	done
    }
    
    # читаем файл(FIFO-файл) и передаём появляющиеся данные в функцию analysisLogs
    cat $LOG | analysisLogs 
    
    # это необходимо чтобы главная программа преждевременно не завершилась 
    # пока не завершаться запущенные в ней фоновые(&) потоки
    wait
    
    exit
    Ответ написан
    1 комментарий
  • Как и куда bash убирает элемент массива?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    в простом случае:
    $ x='test1 test2'
    $ y=($x)
    $ echo ${y[0]} И ${y[1]}
    test1 И test2


    если же, например, у нас разделитель перевод строки то:
    $ x='test 1
    test 2'
    $ q="$IFS";IFS=$'\n';y=($x);IFS="$q"
    $ echo ${y[0]} И ${y[1]}
    test 1 И test 2
    Ответ написан
  • Как присвоить значение элемента строкового массива в bash?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    можно загнать строки из файла в массив намного проще:
    x="$IFS";IFS=$'\n';array=(`cat array.list`);IFS="$x"


    если брать конкретно ваш вариант то можно использовать опцию lastpipe чтобы выполнить последнюю команду конвейера в текущей оболочке:
    i=1
    shopt -s lastpipe
    cat array.list | while read str
    do
       array["$i"]="$str"
       i=$(($i+1))
    done
    shopt -u lastpipe
    echo ${array[@]}
    Ответ написан
    Комментировать
  • Awk, как объединить столбцы при передаче в shell?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    $ echo "a1 a2 a3 15-Aug-2019 00:24:38 a6 ..." | awk '{z="date -d \""$4" "$5"\" \"+%s\""; z | getline z; print z}'
    1565817878

    ну или вывести в самой строке
    $ echo "a1 a2 a3 15-Aug-2019 00:24:38 a6 ..." | awk '{z="date -d \""$4" "$5"\" \"+%s\""; z | getline z; $4=z;$5="";print}'
    a1 a2 a3 1565817878  a6 ...

    немного покороче
    $ echo "a1 a2 a3 15-Aug-2019 00:24:38 a6 ..." | awk '{"date -d \""$4" "$5"\" \"+%s\""|getline $4;$5="";print}'
    a1 a2 a3 1565817878  a6 ...


    upd. (исправление)
    $ echo "a1 a2 a3 15-Aug-2019 00:24:38 a6 ..." | awk '{"date -d \""$4" "$5"\" \"+%s\"" | getline z; $4=z;$5="";print}'
    a1 a2 a3 1565817878  a6 ...
    Ответ написан
    4 комментария
  • Как использовать регулярные выражения в цикле консоли Линукс?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Или есть более простой способ, чтобы сохранить картинки в новой папке?

    cp $(cat images_file) --target-directory="new_path/"
    Ответ написан
    Комментировать
  • Как найти файлы, у которых в содержимом встречаются 2 слова?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    grep --max-count=1 -z -l "СЛОВО1.*СЛОВО2" ФАЙЛ1 ФАЙЛ2 ...
    Ответ написан
    1 комментарий
  • Нужно открыть youtube в плеере VLC, в чём ошибка?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    погляжу народ обожает трудности
    x=($(youtube-dl -g https://www.youtube.com/watch?v=yfHQCNPTios)) && vlc ${x[0]} --input-slave ${x[1]}


    Чтобы открыть youtube 1080p в плеере VLC

    для этого нужно выставить нужные параметры в ключе --format
    x=($(youtube-dl -g --format="bestvideo[height<=?1080]+bestaudio" https://www.youtube.com/watch?v=yfHQCNPTios)) && vlc ${x[0]} --input-slave ${x[1]}

    подробнее об этом написал тебе в твоём предыдущем вопросе

    для mpv будет проще:
    mpv --ytdl-format="bestvideo[height<=?1080]+bestaudio" https://www.youtube.com/watch?v=yfHQCNPTios
    Ответ написан
    23 комментария
  • Как удалить файл в FTP хранилище с помощью bash?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    Как удалить одной командой файл из FTP хранилища с помощью bash? Или предложите свой способ.

    думаю для этого лучше подойдёт lftp
    HOST="192.168.1.1"
    USER="root"
    PASS="12345"
    DATE=$(date +%y%m%d)
    
    CMD="\
    echo 'Начинаю очищать хранилище';\
    ls /;\
    echo 'Очищаю .. rm -rf lalala';\
    echo 'Хранилище очищено '$DATE;\
    exit"
    
    lftp -e "$CMD" --user $USER --password $PASS $HOST


    ну или одной командой

    lftp -e "ls /;rm -rf file.txt;exit" --user root --password 12345 192.168.1.1
    Ответ написан
    Комментировать
  • Bash, head и tail: Невозможно открыть для чтения?

    xotkot
    @xotkot
    хорошо есть и хорошо весьма
    осталась одна ошибка в 7 строке: ./analiz.sh: строка 7: *1: синтаксическая ошибка: ожидается операнд (неверный маркер «*1»)

    cpuload=$(($var*1))
    во первых можно визуально немного упростить
    cpuload=$[var*1]
    во вторых, ругается из за того что переменная var пустая
    можно задать значение для var если она будет пуста
    cpuload=$[${var:=999}*1]
    здесь если переменная var не заданна то её значение для этого выражение станет равным 999
    Ответ написан
    Комментировать