Как posix-совместимый способ, который работает с несколькими реализациями, как я могу напечатать список в настоящее время определенной переменной среды без их значений?
В некоторых реализациях (mksh, freebsd / bin / sh) простое использование export
подойдет:
$ export
FOO2
FOO
Но для некоторых других реализаций (bash, zsh, dash) export
также показано значение. С bash, например:
$ export
export FOO2='as df\
asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd kjasdf:\
asdkj=fkajdsf:\
:askjfkajsf=asdfkj:\
safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd kjasdf:\$
asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
safdkj$
Другие опции, такие как env
или printenv
не имеют возможности печатать только имена переменных без значений, по крайней мере, не на платформах linux и freebsd, которые я пробовал.
Трубопровод к awk / sed / etc. или урезание списка методами расширения параметров (например, ${foo%%=*}
) приемлемо, но оно должно работать со значениями, которые могут занимать строки и иметь =
пробел в значении (см. пример выше).
Интересны ответы, специфичные для конкретных реализаций оболочки, но я в первую очередь ищу что-то совместимое для всех реализаций.
export -p
который указан в POSIX, чтобы сгенерировать вывод, который также подходит для ввода в оболочке.export -p
для этого?export -p
потому что это даст вам согласованный вывод для всех оболочек POSIX, что вы сказали, что вы хотели.export -p
не соответствует первому требованию - печать только имен переменных без значений.export -p
. Я не собираюсь писать этот разбор, потому что в общем случае он должен был бы также выполнить правильный разбор кавычек, если у вас есть переменная, значение которой является чем-то вродеhello\nexport var=value
. Одной из немногих других команд, которая даст вам согласованный вывод во всех оболочках POSIX, являетсяenv
, но этот вывод сложнее проанализировать, поскольку в нем отсутствуетexport =
бит.Ответы:
Это довольно легко в awk.
Однако остерегайтесь некоторых реализаций AWK добавить переменные окружения своих собственных (например , GNU AWK добавляет
AWKPATH
иAWKLIBPATH
кENVIRON
).Вывод будет неоднозначным, если имя переменной среды содержит символ новой строки, что крайне необычно, но технически возможно. Чистое решение будет трудно. Лучше всего начать с того, что
export -p
массировать его в чистом виде сложно. Вы можете использовать sed, чтобы массировать выводexport -p
, а затем использовать,eval
чтобы получить оболочку, чтобы удалить то, что она цитирует. Bash и Zsh печатают нестандартные префиксы.Обратите внимание, что в зависимости от оболочки
export -p
может отображаться или не отображаться переменная, имя которой недопустимо в оболочке, а если нет, то она может указывать или не указывать имена должным образом. Например, переменные dash, mksh и zsh опускают переменные, имя которых включает символ новой строки, BusyBox dash и ksh93 печатают их в необработанном виде, а bash печатает их в необработанном виде без их значения. Если вам нужно защитить от ненадежного ввода, не полагайтесь на чисто POSIX-решение и определенно не вызывайтеeval
ничего, полученного из выводаexport -p
.источник
exit
это необходимо).FOO<newline>BAR
, вы не знаете, будет ли этоFOO<newline>BAR
переменная окружения (котораяexport -p
не будет отображаться в большинстве оболочек, см.env $'FOO\nBAR=test' awk 'BEGIN{for (v in ENVIRON) print v}'
) ИлиFOO
иBAR
переменная окружения, и переменная окружения.awk
s устанавливает собственные переменные окружения (AWKPATH
иAWKLIBPATH
в моей системе)Мне нравятся простые вещи; это будет работать для систем POSIX:
источник
export AAA=$'multi\nBBB=line'
compgen -e
. Это не помогает для моего переносимого скриптинга (например, когда bash недоступен), но это интересно.dash
в Debian, я получаю те же результаты с помощью команды выше или, модифицированнойprintenv | sed 's;*=.;;' | sort
для получения значений. Я экспортировал переменнуюyo
и назначил ей ваш первый комментарий выше; он напечатан, как и ожидалось, с несколькими строками. не уверен, что вы испытываете, но не должно быть усеченного вывода. запустить команду в оболочке; что бы он ни выводил, он должен работать; не ожидайте усечения. Затем в контексте TERMCAP / screen / iirc; должно быть таким же. Если выходные данные не совпадают, то это, вероятно, проблема с одной из этих программ.