LINUX.ORG.RU
решено ФорумAdmin

Неприятный и неожиданный сбой при выполнении bash-скрипта

 ,


0

1

Сочиняю я, значится, скрипт. Опыта нет, поэтому постоянно его запускаю - чтоб проверять как всё работает. И вот такая распрекрасная ошибка вылетела:

# ...
# ... тут всякое разное происходит:
Processing triggers for systemd (241-7~deb10u2) ...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10) ...
Connection to 192.168.122.157 closed. # <--- последняя строка всякого разного
./lr.sh: строка 385: $'ncer\nfi\n\n# Если были выбраны нули - значит происходит продолжение прерванного ранее процесса\n# и устанавливать ничего не нужно\necho ': команда не найдена
./lr.sh: строка 388: На: команда не найдена

Настраиваем мастер # <--- тут нормально пошло
ALTER SYSTEM
Connection to 192.168.122.157 closed.
...
...

А вот как это выглядит в виде скрипта:

if [ ${MASTER_VERSION} -eq 0 ]
then echo "Выбран 0, пропускаем."
elif [ ${MASTER_VERSION} -eq 1 ]   # PostgreSQL 9.4
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG94_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 2 ] # PostgreSQL 9.5
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG95_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 3 ] # PostgreSQL 9.6
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG96_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 4 ] # PostgreSQL 10
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG10_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 5 ] # PostgreSQL 11
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG11_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 6 ] # PostgreSQL 12
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG12_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 7 ] # Postgres Pro Standard 9.6
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPS96_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 8 ] # Postgres Pro Standard 10
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPS10_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 9 ] # Postgres Pro Standard 11
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPS11_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 10 ] # Postgres Pro Standard 12
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPS12_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 11 ] # Postgres Pro Enterprise 9.6
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPE96_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 12 ] # Postgres Pro Enterprise 10
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPE10_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 13 ] # Postgres Pro Enterprise 11
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPE11_PKG} pgbouncer"
elif [ ${MASTER_VERSION} -eq 14 ] # Postgres Pro Enterprise 12
### ниже как раз начинается 385 строка:
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPE12_PKG} pgbouncer"
fi

# Если были выбраны нули - значит происходит продолжение прерванного ранее процесса
# и устанавливать ничего не нужно
echo "
На реплике:"
if [ ${REPLICA_VERSION} -eq 0 ]
then echo "Выбран 0, пропускаем."
elif [ ${REPLICA_VERSION} -eq 1 ] # PostgreSQL 11
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGDG11_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 2 ] # PostgreSQL 12
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGDG12_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 3 ] # Postgres Pro Standard 11
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGPS11_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 4 ] # Postgres Pro Standard 12
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGPS12_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 5 ] # Postgres Pro Enterprise 10
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGPE10_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 6 ] # Postgres Pro Enterprise 11
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGPE11_PKG} pgbouncer"
elif [ ${REPLICA_VERSION} -eq 7 ] # Postgres Pro Enterprise 12
then ssh -t $RUSERNAME@${REPLICA} "sudo apt-get install ${PGPE12_PKG} pgbouncer"
fi

То есть баш взял и начал читать команды не с начала строки после fi, а до неё, с конца строки

#                                        Он начал с символа под точкой -> .
then ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGPE12_PKG} pgbouncer"

Вот ссылка на картинку, я там выделил ту часть скрипта, которую bash посчитал одной командной строкой: https://yadi.sk/i/nHKSZ4rat_HZlQ

При повторном запуске всё пошло уже без ошибок. Это я к чему - как сделать так, чтоб подобное не повторялось? Как-то не очень приятно осознавать, что bash может взять и пропустить произвольное число команд, начать читать команду с середины строки и, как ни в чём не бывало, идти дальше. Ладно я при отладке это увидел, а если не увидел бы?

К тому же bash также не счёл командой второй по счету then в блоке относящемся к реплике. Два раза на десяти строчках споткнулся.

elif

Ненормально. Нормально case ... esac.

$MUSERNAME@${MASTER}

Ненормально. Нормально проверить сначала на валидность.

anonymous
()

в современном дебиане надо все решать с помощью системды… bash на свалку истории!

anonymous
()

Первый комментарий приму к сведению - спасибо большое!

Выяснил в чём дело: просто я привык к SQL и всему транзакционному…

В общем в процессе выполнения скрипта я внес в него изменения и, пока выполнялась долгая команда установки Postgrespro, сохранил изменения. Полагаю указатель следующей строки стал указывать не туда в результате такого вандализма.

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

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

нельзя менять содержимое запущенных скриптов, пока не убедился в том, что они остановлены.

Аллилуйя.

anonymous
()
Ответ на: комментарий от dhaenoor

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

Тоже был удивлён этому факту.
Непонятно почему так сделано.

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

Ненормально. Нормально case ... esac.

Да ладно, тут вообще массив напрашивается. Команды одинаковы, есть индекс и есть значение ${PGDGXXX_PKG} , которое в массиве и править приятнее, чем по всему скрипту.

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

Непонятно почему так сделано.

Ну приплыли! А Вы хотите, чтоб вся эта шняга в памяти висела с вполне очевидными в этом случае утечками? Сами себе враги, чтоле?

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

Ну приплыли! А Вы хотите, чтоб вся эта шняга в памяти висела с вполне очевидными в этом случае утечками? Сами себе враги, чтоле?

Какие утечки, вы о чём?! Это интерпретатор, он может, сюрьприз, поменять сам свой текст скрипта из этого же скрипта.

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

Я опять подозресаю всяких piрептилоидов, пора принять микстуру.

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

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

Добро пожаловать в прекрасный старый мир интерпретаторов.
ЗЫ Но вы молодец, быстро сообразили. :)

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

он может, сюрьприз, поменять сам свой текст скрипта из этого же скрипта.

Запросто. Никакого сюрприза у тя не получилось. В памяти хочешь? В «переменную» скрипт считывай и с неё выполняй.

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

Запросто. Никакого сюрприза у тя не получилось. В памяти хочешь?

Как не получилось, если получилось. Я могу и так и этак. А у вас как обычно, сморозили чушь с какими-то утечками и давай разводить детсад с «сам дурак».

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

Как не получилось, если получилось.

Да не получилось! И реально «сам дурак»!

anonymous
()
Ответ на: комментарий от anc

Добро пожаловать в прекрасный старый мир интерпретаторов.

Даже точнее — правильных интерпретаторов, в чём и есть их моща — самоперепрограммируемости, AI во всей красе. :)

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

QBasic

Задачка: «Угадай возраст анона?» :)

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

AI на интерпретаторе?

Именно так. Саморазвивающийся AI не весь, но часть имеет внутри себя именно интерпретатор. Самое смешное, что когда он решит выкристализовавшийся алгоритм таки вкомпилить в себя даже предсказать не всегда возможно.

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

Да, я думал о массиве, но решил не делать - потом будет неудобно читать.

Странные представления у вас о удобстве. Тем более, что в bash все массивы ассоциативные, потому при чтении получается самодокументируемость.

PGDG=(
[1]=GDG94_PKG 
[1]=GDG95_PKG 
[2]=GDG96_PKG 
[3]=GDG10_PKG
...
)
if [[ -z ${PGDG[MASTER_VERSION]} ]]; then 
      echo "Выбран ${PGDG[MASTER_VERSION]}, пропускаем."
else 
      ssh -t $MUSERNAME@${MASTER} "sudo apt-get install ${PGDG[MASTER_VERSION]} pgbouncer"
fi
Красиво и понятно.

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

Подобные задачи идеологически верно решать ансиблом. Ну или по вкусу - puppet/chef/saltstack/cfengine.

MumiyTroll ★★★
()

Что за скрипт?

anonymous
()
Ответ на: комментарий от dhaenoor

нельзя менять содержимое запущенных скриптов

На самом деле можно, если «правильно» – писать в новый файл и переименовывать. Те, кто так не делает – слишком большие оптимисты, их компы никогда не испытывали нехватку стабильности, места, электричества.

DonkeyHot ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.