LINUX.ORG.RU

Bash цикл чтения из файла прерывается непонятным образом

 


1

2

Есть файл commands.sh

rabbitmqctl list_exchanges
echo "--------------------"
rabbitmqctl list_exchanges
echo "--------------------"

Затем я в cmd запускаю цикл

while read c; do eval "$c"; done < commands.sh

отрабатывает первый rabbitmqctl list_exchanges, а до echo уже дело не доходит. Это что за магия? Подобное наблюдается только с rabbitmqctl.

В оригинале мне нужно было удалить кучу очередей через rabbitmqctl delete_queue. Я сгенерировал несколько десятков строчек с этой командой с разными названиями очередей и вставил в терминал. Выполнилась только первая. Потом решил вот попробовать через такой цикл и выполняется тоже только первая. А вот bash commands.sh работает нормально.

Напомни, когда это я тебя покусала, я тоже люблю извращения. Там, скорее всего, вызывается новый экземпляр баша для каждой строки в цикле и не закрывается.

Irma ★★
()

Тэги: bash

да. дело именно в нём. Надо срочно забагрепортить!!111

а имевших дело с самой тулзой правильно не позвал. ну их. Вдруг сразу скажут, где дураг.

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

shell

#!/bin/sh
##  The contents of this file are subject to the Mozilla Public License
##  Version 1.1 (the "License"); you may not use this file except in
##  compliance with the License. You may obtain a copy of the License
##  at http://www.mozilla.org/MPL/
##
##  Software distributed under the License is distributed on an "AS IS"
##  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
##  the License for the specific language governing rights and
##  limitations under the License.
##
##  The Original Code is RabbitMQ.
##
##  The Initial Developer of the Original Code is GoPivotal, Inc.
##  Copyright (c) 2007-2017 Pivotal Software, Inc.  All rights reserved.
##

# Exit immediately if a pipeline, which may consist of a single simple command,
# a list, or a compound command returns a non-zero status
set -e

# Each variable or function that is created or modified is given the export
# attribute and marked for export to the environment of subsequent commands.
set -a

# shellcheck source=/dev/null
#
# TODO: when shellcheck adds support for relative paths, change to
# shellcheck source=./rabbitmq-env
. "${0%/*}"/rabbitmq-env

run_escript rabbitmqctl_escript "${ESCRIPT_DIR:?must be defined}"/rabbitmqctl "$@"
Olegymous ★★★
() автор топика

Есть мнение, что команда, которую ты запускаешь через eval, интерактивная. Такие команды не смогут работать вместе с циклом while

Потому, что они сами работают с STDIN. Команда, запущенная через eval, самостоятельно прочитала весь STDIN, и цикл while завершился раньше и не так, как ты думаешь

bash, к сожалению, набор костылей. Очень полезный и при навыках работы с ним - надёжный. Но нужно знать все его многочисленные подводные камни :/

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

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

Хорошая идея. Ну ввода она на вид не ожидает. Может конечно в неблокирующем режиме читает stdin зачем то. Интересно как это проверить кроме как через strace?

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

Предположение от router было похоже верным. Оно зачем-то читает stdin в неблокирующем режиме. Я запустил такое:

strace -f sh -c 'echo testtesttest | rabbitmqctl list_queues' 2> /tmp/trace

и среди прочего увидел

[pid  4995] epoll_ctl(4, EPOLL_CTL_ADD, 0, {EPOLLIN|EPOLLONESHOT, {u32=0, u64=0}} <unfinished ...>
[pid  4995] <... epoll_ctl resumed> )   = 0
...
[pid  4995] read(0,  <unfinished ...>
[pid  4995] <... read resumed> "testtesttest\n", 65536) = 13
Olegymous ★★★
() автор топика
Последнее исправление: Olegymous (всего исправлений: 1)
Ответ на: комментарий от Olegymous

Непонятно одно: чем тебя не устраивает обычный запуск скрипта?

bash commands.sh

Зачем именно через eval и весь сопутствующий геморрой и гадания окружающих насчет работы конкретной командушки rabbitmqctl?)) Никому и никогда это в жизни не пригодится!)

Если уж так хочется докопаться до причины, то замени строчки:

rabbitmqctl list_exchanges

на

rabbitmqctl list_exchanges < /dev/null
vinvlad ★★
()
Последнее исправление: vinvlad (всего исправлений: 1)