задайте переменную внутри heredoc и используйте их снаружи

Я пытаюсь установить переменную «count» во время выполнения команды внутри heredoc вместе с таймаутом, но я не могу получить переменную «count» вне heredoc.

Как я могу это достичь?

  • Мой сценарий более сложный, но я думал, что получить ответ для этого будет достаточно.

    timeout 10 bash << EOC count=$(ls -l /tmp/ | wc -l) EOC echo "count: $count" 

3 Solutions collect form web for “задайте переменную внутри heredoc и используйте их снаружи”

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

Сделайте это вместо этого:

 count=$(timeout 10 ls -l /tmp/ | wc -l) echo "count: $count" 

Я не думаю, что вы можете это достичь. Большая проблема заключается в том, что у вас есть процесс bash оценивающий конвейер, а затем сохраняя значение этого конвейера в count переменных оболочки. timeout сам по себе не является оболочкой, встроенной в мой ноутбук Arch, поэтому есть третий уровень процесса. Поскольку timeout выдает команду, на которую он ждет, есть третий уровень процесса.

Это shell-that-invokes-timeout -> timeout -> bash-invoked-by-timeout -> value-of- count

Мне кажется, что вам нужно перестроить сценарий оболочки, чтобы иметь возможность использовать значение count (или то, что вы хотите выполнить).

Если вам действительно нужен timeout в команде, вы должны, вероятно, отправить вывод команды в файл, а затем прочитать этот файл:

 if timeout ls -l /tmp > /tmp/some.well.known.name then VAR=$(wc -l /tmp/some.well.known.name) else : handle timeout fi 

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

Использование здесь-документа вместо bash -c не изменяет этот факт. Ваш пример эквивалентен timeout 10 bash -c "count=$(ls -l /tmp/ | wc -l)" . (Кстати, это запускает ls -l /tmp/ | wc -l во внешней оболочке, а не в случае bash который вы порождаете: если вы хотите сделать эквивалент timeout 10 bash -c "count=$(ls -l /tmp/ | wc -l)" , вам нужно использовать <<\EOF или <<'EOF' или тому подобное.)

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

 count=$(timeout 10 bash -c '…') 

Если вам нужно задать множество переменных или массив, вам нужно будет сделать некоторую кодировку и декодирование. Вы можете получить bash, чтобы сделать это для вас: declare -p foo bar печатает способ определения foo и bar который правильно указан для вызывающей оболочки.

 eval "$(bash -c '…; declare foo bar')" 

Обратите внимание, что это объявляет переменные локально, поэтому, если вы запустите его в функции, переменные не будут доступны, когда функция вернется. Если вам нужны переменные, которые будут доступны при возврате, вам нужно снова назначить их с declare -g ; это работает только для скаляров:

 f () { eval "$(bash -c '…; declare foo bar')" declare -g foo="$foo" bar="$bar" } 

В качестве альтернативы, если вы знаете, что значения переменных не могут содержать новые строки, strip declare -… с начала каждой строки на выходе declare -p .

  • Трубы и переменные
  • Когда выполняется .profile?
  • Чтение из файла с разделителями символов и назначение в переменные | для электронной почты
  • Как получить часть имени пути и присвоить его переменной?
  • Определение переменной в 'sh -c'
  • Создание переменных командной строки с помощью PATH
  • используя переменную «файл», полученную из «for» файла «in», и перейти к другому скрипту не удалось
  • Получить номер предыдущей недели в bash
  • Переменные оболочки в цикле for
  • объединение имен файлов в переменную
  • Создать текст, соответствующий нескольким назначениям переменных из одной переменной
  • Interesting Posts

    автоподключение зашифрованного USB

    как настроить имя пользователя и пароли для разных git-репозиций?

    Создание сетевого сервера хранения данных, компромиссы с различными конфигурациями RAID?

    Двойная загрузка Ubuntu и Windows 8. w8 загружается через оболочку grub, но не из меню

    Существует ли методика загрузки и загрузки пакета R без его установки?

    Неразрешенные зависимости при установке AceStream

    Есть ли способ добавить некоторую информацию о времени / дате в приглашение TTY?

    Как извлечь данные из XML-файла

    Почему sudo -E не поддерживает переменную среды $ HOME?

    Запуск приложения X из сценария оболочки через системный таймер

    используя awk для создания нового файла, приводит к проблемам с использованием одного конкретного столбца, не может понять, что не так

    Изменяется ли индекс при переименовании или перемещении файла?

    Различные типы копий в Emacs под X

    Предупреждения ACPI в Debian 8 о сбоях питания ASUS EEEPC 1018P

    Могут ли аналоговые и SPDIF-каналы на звуковой микросхеме Realtek ALC887-VD использоваться для одновременного воспроизведения каждого другого сигнала?

    Linux и Unix - лучшая ОС в мире.