В моем скрипте на bash много переменных, и мне нужно что-то сделать, чтобы сохранить их в файл. Мой вопрос в том, как перечислить все переменные, объявленные в моем скрипте, и получить такой список:
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
set
выводит переменные, но, к сожалению, также выводит определения функций.
К счастью, режим POSIX выводит только переменные:
( set -o posix ; set ) | less
Подключение по конвейеру less
или перенаправление туда, где вам нужны параметры.
Итак, чтобы получить переменные, объявленные только в скрипте:
( set -o posix ; set ) >/tmp/variables.before
source script
( set -o posix ; set ) >/tmp/variables.after
diff /tmp/variables.before /tmp/variables.after
rm /tmp/variables.before /tmp/variables.after
(Или хотя бы что-то на этом основании :-))
-o posix
now a diff будет содержать только переменные.VARS="`set -o posix ; set`"; source script; SCRIPT_VARS="`grep -vFe "$VARS" <<<"$(set -o posix ; set)" | grep -v ^VARS=`"; unset VARS;
. Это также выведет вары в формате, готовом к сохранению. В список будут включены переменные, которые скрипт изменил (source
, вы должны иметь возможность сделать это с помощью выводаdeclare -p
.before=$(set -o posix; set); dosomestuff; diff <(echo "$before") <(set -o posix; set)
В нем перечислены все переменные, включая локальные. Я узнал его из списка переменных, имя которых соответствует определенному шаблону , и использовал его в своем скрипте .
источник
compgen -v
перечислены также глобальные переменные, которые не были установлены локально. Не уверен, что это давняя ошибка или желаемое поведение.Это должно напечатать все имена переменных оболочки. Вы можете получить список до и после получения вашего файла, как и с помощью «set», чтобы определить, какие переменные являются новыми (как описано в других ответах). Но имейте в виду, что такая фильтрация с помощью diff может отфильтровать некоторые переменные, которые вам нужны, но присутствовали до источника вашего файла.
В вашем случае, если вы знаете, что имена ваших переменных начинаются с «VARIABLE», вы можете создать свой скрипт и сделать:
ОБНОВЛЕНИЕ: для чистого решения BASH (внешние команды не используются):
источник
eval "printf '%q\n' $(printf ' "${!%s@}"' _ {a..z} {A..Z})"
Основываясь на некоторых из приведенных выше ответов, это сработало для меня:
исходный файл :
источник
Если вы можете
set
выполнить пост-обработку (как уже упоминалось), вы можете просто разместить вызов в начале и в конце вашего скрипта (каждый для другого файла) и провести различие между двумя файлами. Поймите, что это все еще будет содержать некоторый шум.Вы также можете сделать это программно. Чтобы ограничить вывод только вашей текущей областью, вам нужно будет реализовать оболочку для создания переменной. Например
Что дает
источник
Вот что-то похожее на ответ @GinkgoFr, но без проблем, выявленных @Tino или @DejayClayton, и более надежное, чем умный
set -o posix
бит @DouglasLeeder :Разница в том, что это решение ОСТАНАВЛИВАЕТСЯ после первого неизменяемого отчета, например, первой функции, о которой сообщает
set
Кстати: проблема "Тино" решена. Несмотря на то, что POSIX отключен, а функции передаются через
set
,sed ...
часть решения разрешает только отчеты с переменными (например,VAR=VALUE
строки). В частности,A2
он не попадает в выходные данные ложным образом.И: Проблема "DejayClayton" решена (встроенные символы новой строки в значениях переменных не нарушают вывод - каждый
VAR=VALUE
выводит одну строку):ПРИМЕЧАНИЕ. Решение, предоставленное @DouglasLeeder, страдает от проблемы «DejayClayton» (значения со встроенными символами новой строки). Ниже показано
A1
неправильное изображение, котороеA2
вообще не должно отображаться.НАКОНЕЦ: Я не думаю, что версия имеет
bash
значение, но может. Я провел тестирование / разработку на этом:POST-SCRIPT: Учитывая некоторые другие ответы на OP, я на <100% уверен, что
set
всегда преобразует символы новой строки в пределах значения\n
, на которое полагается это решение, чтобы избежать проблемы "DejayClayton". Может, это современное поведение? Или вариация времени компиляции? Или параметрset -o
илиshopt
параметр? Если вам известны такие варианты, оставьте комментарий ...источник
Попробуйте использовать скрипт (назовем его "ls_vars"):
chmod + x it и:
источник
С точки зрения безопасности, либо @ akostadinov - х ответ или @ JuvenXu - х ответ предпочтительнее полагаться на неструктурированной выходе
set
команды из - за следующего потенциального недостатка безопасности:Вышеупомянутая функция
doLogic
используетсяset
для проверки наличия переменной,PS1
чтобы определить, является ли сценарий интерактивным или нет (неважно, если это лучший способ достичь этой цели; это всего лишь пример).Однако вывод
set
неструктурирован, а это означает, что любая переменная, содержащая новую строку, может полностью испортить результаты.Это, конечно, потенциальная угроза безопасности. Вместо этого используйте либо поддержку Bash для косвенного раскрытия имени переменной, либо
compgen -v
.источник
Попробуйте это:
set | egrep "^\w+="
(с| less
трубопроводом или без него )Первое предложенное решение
( set -o posix ; set ) | less
работает, но имеет недостаток: оно передает управляющие коды на терминал, поэтому они не отображаются должным образом. Так, например, если есть (вероятно)IFS=$' \t\n'
переменное, мы можем видеть:…вместо.
Мое
egrep
решение отображает это (и, в конечном итоге, другие похожие) правильно.источник
bash -c $'a() { echo "\nA=B"; }; unset A; set | egrep "^\w+="' | grep ^A
отображениеA=B"
-> Ошибка!Я, наверное, украл ответ какое-то время назад ... во всяком случае, немного отличается от функции:
источник
Команда
printenv
:printenv
печатаетenvironment variables
вместе со своими значениями.Удачи...
источник
Простой способ сделать это - использовать строгий режим bash , установив системные переменные среды перед запуском вашего скрипта, и использовать diff для сортировки только тех из вашего скрипта:
Теперь вы можете получить переменные вашего скрипта в /tmp/script_vars.log. Или хотя бы что-то на этом основании!
источник
Немного поздно на вечеринку, но вот еще одно предложение:
Diff + СЭД командной строка трубопроводов выводит весь сценарий определенных переменные в нужном формате (как указано в посте ОП в):
источник