Переменные среды Переменной набора в ударе (или другой)

Опция 1 состояла бы в том, чтобы изменить исходный код приложения вызова и вставить tee в вывод конвейерно обрабатывают для получения копии вывода для обзора на том этапе.

Опция 2 состояла бы в том, чтобы записать сценарий обертки вокруг рассматриваемого исполняемого файла. Быстрый сценарий, который передает stdin и аргументы реальному приложению, затем мишень вывод к местоположению для Вас для рассмотрения и также слюна, это отступает тот же путь приложение, был бы, должна быть просто пара строк, чтобы сделать на скорую руку. Поместите его где-нибудь особенный и сделайте, добавляют, что местоположение к передней стороне Вашей переменной ПУТИ, затем запустите свое приложение.

#!/bin/sh
cat - | /path/to/realapp $@ | tee /tmp/debug_output
9
23.05.2017, 14:33
4 ответа

export $key=$val должен работать просто великолепно в bash. Я подозреваю, что Вашей проблемой является канал (|). Все команды в конвейере выполняются в подоболочке. В Вашем примере, экземпляре bash это запускает Ваш скрипт, разветвится от 2 подоболочек: один для cat $1 и другой для while read .... Переменные присвоены и экспортированы в подоболочке, выполняющей цикл с условием продолжения, и затем все они быстро выводятся, когда подоболочка выходит. Один способ зафиксировать это не состоит в том, чтобы породить подоболочки вообще. Вместо бесполезного использования кошки попробуйте перенаправление вместо этого:

while read ...; do
   ...
done < "$1"

BashFAQ 24 объясняет это в намного больших деталях.

Альтернативный подход должен просто получить файл с добавленным экспортом:

. <(sed '/^export/!s/^/export /' "$1")

<( ) замена процесса.

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

10
27.01.2020, 20:06
  • 1
    я использовал перенаправление ранее; что-то еще, должно быть, не работало, когда я изменил сценарий для использования cat. Но, сценарий с перенаправлением работает теперь, Спасибо! –  palswim 16.02.2012, 01:44
  • 2
    Бесполезное использование кошки, которую рассматривают вредной! –  Scott 23.06.2014, 18:36

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

Правая сторона конвейера работает в его собственной подоболочке в ударе (а также большинство других оболочек, при этом исключениями является ATT ksh и zsh). Таким образом, Вы устанавливаете переменные среды в подоболочке, которая выполняет цикл, но не в основном процессе оболочки.

Здесь существует легкая фиксация, которая должна заменить бесполезное использование cat перенаправлением:

while read …; do …; done <"$1"

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

grep '^foo_' "$1" | {
  while read …; do …; done
  do_something
}

Отметьте это в целом, while read line; do … действительно не совсем выполняет итерации по входным строкам. Посмотрите, Почему while IFS= read используемый так часто, вместо IFS=; while read..? для объяснения. Корректная идиома для итерации по входным строкам

while IFS= read -r line; do …

Здесь, удаление продвижения и запаздывающего пробела не имеет значения, так как не должно быть никого, учитывая Ваш демонстрационный вход, но Вам, возможно, понадобится -r избегать расширения обратной косой черты. Это возможно это while read line на самом деле корректный способ считать Ваш вход (но я подозреваю, только если значения переменных не содержат новых строк). Также возможно, что Ваш формат ввода неоднозначен или более сложен для парсинга. Проверьте то, что происходит, если одно из значения переменных содержит символ новой строки, двойную кавычку или обратную косую черту.

Одна точка, где Вы определенно искажаете вход, - при извлечении значения:

val=`echo ${kv#*=} | sed 's/^"\|"$//g'`

Во-первых, необходимо использовать двойные кавычки вокруг подстановки переменных: echo "${kv#*=}"; иначе оболочка выполняет разделение слова и поколение имени файла (т.е. globbing) на нем. Во-вторых, echo надежный путь не состоит в том, чтобы распечатать строку, потому что некоторые строки, которые начинаются с a - рассматриваются как опции, и некоторые оболочки выполняют расширение обратной косой черты на аргументе. Надежный и портативный способ распечатать строку printf %s "${kv#*=}". Кроме того, если значение охватит несколько строк, то sed программа будет действовать на каждого отдельно, который неправ. Это является закрепляемым, но существует более легкий метод, который должен использовать средства обработки строк оболочки: val=${kv#*=}; val=${val#\"}; val=${val%\"}.

Предположение, что вход правильно анализируется с плоскостью read, вот более простой способ проанализировать его, используя в своих интересах IFS установка для разделения каждой строки:

while read name value; do
  value=${value#\"}; value=${value%\"}
  export name="$value"
done <"$1"
2
27.01.2020, 20:06

Другой хороший вариант может быть размещать экспорт в файл и источник:

export XAUTHLOCALHOSTNAME="localhost"
export DISPLAY=":0"
export XAUTHORITY="/tmp/some-XAuthority"

, а затем:

. "$1"
0
27.01.2020, 20:06

/env

EXPORT=value
#NOTEXPORT=notvalue

script

#!/bin/sh

for entry in $(cat /env)
do
  if [[ ! $entry == \#* ]]
  then
    export $entry
  fi
done
0
27.01.2020, 20:06

Теги

Похожие вопросы