Я думаю, вы спрашиваете о двух разных вещах.
Есть ли способ заставить bash печатать эту информацию без цикла?
Да, но они не так хороши, как просто использование цикла.
Есть ли более чистый способ получить/распечатать только часть вывода, состоящую из ключей и значений?
Да, цикл for
. Его преимущества заключаются в том, что он не требует внешних программ, прост и позволяет довольно легко контролировать точный формат вывода без сюрпризов.
Любое решение, которое пытается обработать вывод declare -p
(typeset -p
)
должен иметь дело с а) возможностью того, что сами переменные содержат круглые скобки или квадратные скобки, б) цитирование, которое declare -p
должно добавить, чтобы его вывод был действительным вводом для оболочки.
Например, ваше расширение b="${a##*(}"
съедает часть значений, если какой-либо ключ/значение содержит открывающую скобку. Это потому, что вы использовали # #
, который удаляет префикс самый длинный. То же самое для c="${b%% )*}"
. Хотя вы, конечно, могли бы более точно сопоставить шаблон, напечатанный с помощью declare
, вам все равно было бы трудно, если бы вы не хотели цитировать все, что он делает.
Это выглядит не очень красиво, если только вам это не нужно.
$ declare -A array=([abc]="'foobar'" [def]='"foo bar"')
$ declare -p array
declare -A array='([def]="\"foo bar\"" [abc]="'\''foobar'\''" )'
С помощью цикла for
проще выбрать формат вывода по своему усмотрению:
# without quoting
$ for x in "${!array[@]}"; do printf "[%s]=%s\n" "$x" "${array[$x]}" ; done
[def]="foo bar"
[abc]='foobar'
# with quoting
$ for x in "${!array[@]}"; do printf "[%q]=%q\n" "$x" "${array[$x]}" ; done
[def]=\"foo\ bar\"
[abc]=\'foobar\'
Отсюда также просто изменить формат вывода в противном случае (убрать скобки вокруг ключа поместите все пары ключ/значение в одну строку...).Если вам нужно цитировать что-то помимо самой оболочки, вам все равно придется сделать это самостоятельно, но, по крайней мере, у вас есть необработанные данные для работы. (Если у вас есть символы новой строки в ключах или значениях, вам, вероятно, понадобятся кавычки.)
С текущим Bash (я думаю, 4.4) вы также можете использовать printf "[%s]=% s" "${x@Q}" "${array[$x]@Q}"
вместо printf "%q=%q"
. Он производит несколько более приятный формат кавычек, но, конечно, немного больше работы, чтобы не забыть написать. (И он заключает в кавычки угловой регистр @
как ключ массива, который %q
не заключает в кавычки.)
Если цикл for кажется слишком утомительным для записи, сохраните его как функцию где-нибудь (без кавычек):
printarr() { declare -n __p="$1"; for k in "${!__p[@]}"; do printf "%s=%s\n" "$k" "${__p[$k]}" ; done ; }
А затем просто используйте это:
$ declare -A a=([a]=123 [b]="foo bar" [c]="(blah)")
$ printarr a
a=123
b=foo bar
c=(blah)
Работает и с индексированными массивами:
$ b=(abba acdc)
$ printarr b
0=abba
1=acdc
NetBSD использует уровни безопасности ядра для определения того, какие операции можно выполнять в работающей системе. Из ссылки:
-1 Постоянно небезопасный режим
- Не повышать уровень безопасности при загрузке
0 Небезопасный режим
- Процесс
init
(PID 1) не может быть отслежен или доступенptrace(2)
,systrace(4)
, илиprocfs
.- Флаги файлов Immutable и Append-only могут быть изменены
- Все устройства могут быть прочитаны или записаны в соответствии с их разрешениями
Примечание: Вы не можете запускать X11 выше этого безопасного уровня
Попробуйте
sysutils/aperture
, если вам это действительно нужно.1 Безопасный режим
- Все эффекты безопасного уровня 0
/dev/mem
и/dev/kmem
не могут быть записаны- Необработанные дисковые устройства смонтированных файловых систем доступны только для чтения
- Неизменяемые и доступные только для добавления флаги файлов не могут быть удалены
- Модули ядра не могут быть загружены или выгружены
- The net.inet.ip. sourceroute
sysctl(8)
переменная не может быть изменена- Добавление или удаление
sysctl(9)
узлов запрещено- Смещение RTC не может быть изменено
- Настройки set-id coredump не могут быть изменены
- Присоединение IP-отладчика ядра,
ipkdb(4)
, запрещено- Запросы на проход устройства, которые могут быть использованы для выполнения необработанного доступа к диску и/или памяти, запрещены
Вызовы iopl
иioperm
запрещены- Доступ к неуправляемой памяти запрещен
2 Режим повышенной безопасности
- Все эффекты уровня безопасности 1
- Необработанные дисковые устройства всегда доступны только для чтения, независимо от того, смонтированы они или нет
- Новые диски не могут быть смонтированы, а существующие могут быть только переведены из режима чтения-записи в режим только чтения
- Системные часы не могут быть установлены назад или близки к переполнению
- Запрещено изменять имя coredump для каждого процесса
- Запрещено изменять правила фильтрации пакетов и NAT
Моя система работала на уровне безопасности 1, поэтому "модули ядра не могут быть загружены или выгружены". Кроме того, установка npf=YES
в rc.conf
не приводит к автоматической загрузке соответствующего модуля ядра. Нельзя понизить уровень безопасности ядра во время выполнения, поэтому возможны следующие варианты:
Очевидно, что последний вариант лучше. Чтобы загрузить модуль ядра при загрузке, необходимо убедиться, что rc.conf
содержит:
modules=YES
Затем отредактируйте (или создайте) /etc/modules.conf
, чтобы он содержал список модулей для загрузки, по одному в строке. В данном случае:
# echo npf >> /etc/modules.conf