LINUX.ORG.RU

Помогите разобраться с баш-скриптом

 , ,


0

1

Hello Is there anybody in there? Just nod if you can hear me Is there anyone home?

Взялась тут из любопытства изучать bash. Но совета спросить не у кого - нашла группу 29чел в телеге, но там все молчат. Написала скрипт. Но он не работает так, как надо. https://github.com/N0vum/Signals Может кто глянет и подскажет..)



Последнее исправление: novum (всего исправлений: 1)
Ответ на: комментарий от slowpony

Спасибо) Но с логикой вроде все норм. Суть скрипта - сравнить введенные ответы со списком из текстового файла построчно. Я не понимаю (не могу найти инфу) как это можно сделать.

novum
() автор топика
Ответ на: комментарий от novum

Я не понимаю (не могу найти инфу) как это можно сделать.

Это два разных вопроса. У вас есть алгоритм вообще без отношения к bash в частности? У вас есть кокретные вопросы по реализации этого алгоритма на bash? А то получается, что вы не можете найти готовую реализацию на блюдечке и возмущаетесь.

vodz ★★★★★
()

Вообще у тебя проблема ещё и в том, что в keys.txt не строки, а регекспы… Причём ещё и регекспы кривые — ^ заэкранирован, \i в конце. Можно, конечно, и с этим работать, но сложнее будет, чем просто =. Если keys.txt не берётся откуда-то, а является частью, поставляемой со скриптом, проще его переписать под формат, с которым работать просто, нежели парсить вот это вот.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от novum

Я бы заменил эти недорегулярки на списки с разделителем, а в цикле выкусывал бы нужную строчку из файла keys.txt при помощи head+tail и просовывал ее сквозь xargs, где сверял бы со введенным текстом. Сверку и инкремент счетчика успехов вынес бы в функцию.

thesis ★★★★★
()
Ответ на: комментарий от CrX

Я, конечно, подозревала, что мои регексы никуда не годятся)) Поэтому пробовала просто по 1 слову 9 строк - не работает. Ну, я сама себе придумала эту задачку, чтобы потренироваться, поэтому можно и переписать. Просто останется непонятным - как брать работать с данными, которые откуда-то взялись?

novum
() автор топика
Ответ на: комментарий от novum

Просто останется непонятным - как брать работать с данными, которые откуда-то взялись?

Как-как… Парсить, в голове тихонько матеря того, кто их так оформил ¯_(ツ)_/¯

Небольшое «философское», тем не менее, важно отступление: Тут дело в том, что задачу надо разбить на подзадачи. Сначала написать всю логику так, чтобы она работала (хотя бы тупо со строками), а потом уже заменить одну строку скрипта, где пока сравнение строк, на логику работы с регэкспами или этими квази-регэкспами, парсинг и прочее. Или наоборот, сначала реализовать сравнение одной строки ответа с этими квази-регекспами, а потом вокруг этого городить всякие циклы, показы картинок и прочее. Divide et impera очень важно в кодинге, даже для шелл-скриптов.

CrX ★★★★★
()
Ответ на: комментарий от CrX

Сам скрипт, так чтобы в keys.txt были просто строки правильных ответов я бы написал как-то так:

#!/bin/sh

# Показать картинку на секунду
show_pic() {
    fim "$1.jpg" &
    jpg_pid=$!
    sleep 1
    kill $jpg_pid
}


sudo apt-get install fim
[ -z $(which fim) ] && exit


echo "Введите названия сигналов"
sleep 1

# счётчик очков, в начале 0
correct=0

for i in $(seq 9); do
    # показываем картинку
    show_pic "$i"

    # берём правильный ответ из файла, с i-той строки, отрезаем ненужные символы перевода строки
    right_answer="$(sed -n ${i}p keys.txt | tr -d '\n' | tr -d '\r')"

    # запрашиваем ответ юзера
    read answer

    # если совпадает, начисляем очко
    [ "$answer" = "$right_answer" ] && correct=$(($correct+1))
done

echo "Вы дали $correct правильных ответов"

А вот для парсинга квази-регэкспов придётся написать ещё с десяток строк. Если заменить на настоящие регэкспы, можно будет обойтись grep или sed.

P.S. | tr -d '\n' | tr -d '\r' добавлено исключительно из-за того, что у тебя keys.txt почему-то в \r\n (DOS) формате. Если перевести в человеческий (dos2unix keys.txt), то эта часть не требуется.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 5)

Взялась тут из любопытства изучать bash.

Читать Advanced Bash Scripting Guide. Это лучшее что есть, показывает всю красоту bash.

Вот версия - не последняя, но на русском. https://www.opennet.ru/docs/RUS/bash_scripting_guide/ (лучше сразу качать Архив руководства в html-формате (~380Кб))

Или на английском легко гуглится.

Когда этого станет мало (а это случится не скоро), то велкам на http://wiki.bash-hackers.org/

Это 120% от того, что тебе нужно.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от slackwarrior

Хы. И правда. Не вчитывался, если честно.

Как изевстно, кодга начала и окноачния слов напиасны праиьлвно, осатьлное счиывтается как-бы бессонзаетльно. :)

Сомневаюсь, впрочем, что дело в орфографии, ведь в самом сообщении написано правильно. Скорее просто незамеченная опечатка.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от CrX

Спасибо большое! Я сделала через пайп head | grep, но сама вижу, что кривое решение. А тут - красота! С форматом файла - посмотрю, что за такое, спасибо. Я Убунту неделю назад установила только, ещё не разобралась.

novum
() автор топика
#!/usr/bin/env bash

ok_answ="0"
err_answ="0"
question="0"

check_answ () {
    if [ "${ANSW}" = "${o}" ]; then
        ((ok_answ+=1))
    else
        ((err_answ+=1))
    fi
}

read_in () {
    ((question+=1))
    read -p "ques ["${question}"]: " ANSW
}

IFS=$'\n'
for o in $(cat "${1:?}"); do
    read_in
    check_answ
done

echo " ok = ${ok_answ}, err = ${err_answ}"

Топорно конечно, но как-то так..

./signal.sh keys.txt

Breaking
()

Если go.sh прогнать через shellcheck.net, то пишет:

Line 18:
if [[ !(-z $key) ]]
       ^-- SC1035 (error): You are missing a required space here.


SC1035

p.s. Я не «настоящий скриптописатель (c)», поэтому всегда проверяюсь на этом ресурсе. )

krasnh ★★★★
()