2016-02-08 2 views
2

Я работаю с растущим скриптом bash, и внутри этого скрипта у меня есть ряд функций. Одна из этих функций должна возвращать значение переменных, но я сталкиваюсь с некоторыми проблемами с синтаксисом. Ниже приведен пример кода.возвращающие значения в функции bash

ShowTags() { 
    local tag=0 
    read tag 
    echo "$tag" 
} 

selected_tag=$(ShowTags) 
echo "$selected_tag" 

вытащил этот код из статьи Linux Journal, но проблема в том, что, кажется, не работает, или, возможно, он делает, и им не хватает что-то. По сути, всякий раз, когда функция вызывается, скрипт зависает и ничего не выводит, мне нужно CTRL + C вернуться к CLI.

Данная статья приведена ниже.

http://www.linuxjournal.com/content/return-values-bash-functions

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

EDIT:

Поведение это действительно становится для меня сейчас. Я использую следующий скрипт.

ShowTags() { 

    echo "hi" 
    local tag=0 
    read tag 
    echo "$tag" 
}    

selected_tag=$(ShowTags) 
echo "$selected_tag 

В основном то, что происходит, баш будет действовать, как если команда чтения происходит перед эхо-тега в верхней части функции. Как только я передаю что-то, чтобы прочитать, хотя он будет запускать верхнее эхо и завершить оставшуюся часть скрипта. Я не знаю, почему это происходит. Это именно то, что происходит в моем основном скрипте.

+0

Почему вы отредактировали код в этом вопросе? Теперь это точно так же, как в ответе, поэтому ответ не имеет смысла. Это была ошибка копирования при написании вопроса? – Barmar

+0

Я отредактировал код, чтобы он отражал его, что он появляется в моем скрипте. Проблема не в синтаксисе. Сценарий просто зависает, когда я пытаюсь вызвать функцию посредством подстановки команд. – barefly

+0

Команда 'read tag' ждет ввода типа. – Barmar

ответ

2

Изменить echo "hi"echo "hi" >/dev/tty.

Причина, по которой вы не видите это немедленно, состоит в том, что $(ShowTags) захватывает весь стандартный выход функции и присваивается selected_tag. Поэтому вы не видите ничего, пока не повторите эту переменную.

Переадресовывая запрос на /dev/tty, он всегда отображается сразу же на терминале, а не отправляется на stdout функции, поэтому он не получает захвата подстановкой команды.

+0

Спасибо! Я так рад, что, наконец, понял эту проблему. Твоя жизнь. – barefly

0

Вы пытаетесь определить функцию с помощью Name { ... ]. Вы должны использовать name() { ... }:

ShowTags() { # add() 
local tag=0 
read tag 
echo "$tag" 
}    # End with } 

selected_tag=$(ShowTags) 
echo "$selected_tag" 

В настоящее время она позволяет пользователю ввести в строку и она записывается обратно:

$ bash myscript 
hello world  # <- my input 
hello world  # script's output 

Вы можете добавить подсказку с read -p "Enter tag: " tag, чтобы сделать его более очевидным, когда писать ваш вход.

+0

Я просто бросил это в новый скрипт и запустил его, скрипт просто зависает, не спрашивая ввода пользователя. Я выбросил эхо в начале функции, чтобы проверить, не проходит ли она, и она не появляется, потому что она не отображается. Может быть, это связано с тем, как мой bash настроен? – barefly

+0

@barefly Все, что функция echoes будет помещена в '$ selected_tag', вы не увидите ее на экране. – Barmar

+0

@barefly вывод 'echo' будет захвачен' $ (ShowTags) 'вместе с другим выходом. Вы можете использовать stderr ('echo" start function "> & 2'), чтобы обойти это (это в значительной степени то, что stderr для). –

0

Как указано @thatotherguy, синтаксис объявления функции отключен; но я подозреваю, что это ошибка транскрипции, как будто это было неправильно в скрипте, у вас возникли другие проблемы. Я думаю, что происходит то, что команда read tag в функции пытается прочитать значение со стандартного ввода (по умолчанию это терминал) и приостанавливается до тех пор, пока вы не введете что-нибудь. Я не уверен, что он намеревался сделать, но как написано, я ожидал, что он остановится на неопределенный срок, пока что-то не набирается.

Решение: введите что-нибудь или используйте что-то другое, кроме read. Вы также можете добавить приглашение (read -p "Enter a tag: " tag), чтобы было более ясно, что происходит.

BTW, у меня есть несколько возражений против связанного вами linux journal article. Это не относится к вашему сценарию, но о том, о чем вы должны знать.

Во-первых, ключевое слово function является нестандартным багизмом, и я рекомендую не использовать его. myfunc() ... достаточно, чтобы ввести определение функции.

Во-вторых, и более серьезный, статья рекомендует использовать eval небезопасным способом.На самом деле, действительно безопасно использовать eval (см. BashFAQ #48). Вы можете улучшить его много раз, меняя цитирование, и даже больше, не используя eval вообще:

eval $__resultvar="'$myresult'" # BAD, can evaluate parts of $myresult as executable code 
eval $__resultvar='"$myresult"' # better, is only vulnerable to executing $__resultvar 
declare $__resultvar="$myresult" # better still 

См BashFAQ #6 больше вариантов и обсуждения.

Смежные вопросы