Эта переменная извлекается из colors
автозагружаемой функции.
Вам нужно загрузить и запустить эту функцию:
autoload colors
colors
Обратите внимание, что вы также можете использовать подсказку, которая не требует этой функции colors
:
print -P %F{red}
Или:
echo ${(%):-%F{red}}
В любом случае, это переменная ассоциативного массива оболочки , а не то, что можно или нужно экспортировать в среду. Если вы хотите увидеть его объявление, используйтеtypeset -p fg_bold
(обратите внимание, что переменная имеет атрибут-H
(скрыть значение ), поэтому typeset -p
будет отображать значения, вы можете удалить этот атрибут с помощью typeset +H fg_bold
или посмотреть значения с помощьюtypeset fg_bold
).
Обратите внимание, что /var/run
является символической ссылкой на /run
и должна быть «разрешена» заранее, иначе /mnt/var/run
может указывать на /run
с помощью различных команд.
На первый взгляд этой более простой команды (, а не OP, которая никогда не может работать, как объяснено в последнем примечании в конце )из начального пространства имен, должно быть достаточно, чтобы позволить ip netns exec
работать из chrooted pid пространство имен:
mount --bind /run/netns/test1 /mnt/run/netns/test1
но это не так. Это связано не с пространством имен pid , а с chroot . На самом деле вся проблема такая же, когда вообще не переключаешься на новое пространство имен pid .
ip netns exec
не манипулирует только сетевыми пространствами имен, но также должен манипулировать mount пространствами имен и использовать mount (2)системные вызовы по причинам, которые я объяснил в этот SF Q/A:Невозможно создать вложенное сетевое пространство имен .
/proc
должен быть смонтирован внутри chroot для корректной работы. По крайней мере, /proc
, смонтированный из chroot, используя strace
, можно увидеть, что ip netns exec test1...
войдет в новое пространство имен монтирования и не сможет перемонтировать/
:
getuid() = 0
openat(AT_FDCWD, "/run/netns/test1", O_RDONLY|O_CLOEXEC) = 3
setns(3, CLONE_NEWNET) = 0
close(3) = 0
unshare(CLONE_NEWNS) = 0
mount("", "/", 0x5595a749373f, MS_REC|MS_SLAVE, NULL) = -1 EINVAL (Invalid argument)
write(2, "\"mount --make-rslave /\" failed: "..., 49) = 49
exit_group(-1) = ?
+++ exited with 255 +++
Ошибка повторного монтирования сEINVAL
:из-за того, что chroot , /
больше не является точкой монтирования.
Обратите внимание, что часть пространства имен network сама по себе не вызывает проблем. Так, например, делая это со стороны chroot:
nsenter --net=/run/netns/test1 ip link
завершится успешно и отобразит test1 сетевые интерфейсы, но, например, не будет переключать соответствующие записи, доступные в /sys/
, как сделал бы ip netns exec
(, как описано в моей предыдущей ссылке ), если те быть нужным.
Исправление :bind -монтирует цель chroot к себе, чтобы принудительно превратить ее в точку монтирования, желательно в приватном режиме, чтобы избежать взаимодействий (, особенно когда systemd превратил /
общий )перед выполнением chroot .
Ниже я воспроизвожу рабочую установку с командами оболочки.
Я опускаю некоторые шаблоны, например, монтирование/run
(ака init/mnt/run
)из tmpfs и т. д., но монтирование /proc
из chroot действительно должно быть выполнено.
первый в семестре1:
~# unshare --fork --pid bash
~# echo $$
1
~# mount --bind --make-private /mnt /mnt
~# chroot /mnt bash
/# mount -t proc proc /proc
затем в несвязанном термине2:
~# ip netns add test1
~# mkdir -p /mnt/run/netns
~# touch /mnt/run/netns/test1
~# mount --bind /run/netns/test1 /mnt/run/netns/test1
снова в срок1:
/# ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Примечания:
, как было сказано ранее, не имеет отношения к пространству имен pid . Удаление команды unshare --fork --pid bash
решит ту же проблему при использовании только chroot без пространства имен pid .
команда монтирования никогда не должна запускаться из команды ip netns exec
.Помните, что ip netns exec
сам по себе создает временное пространство имен монтирования. Какое бы ездовое животное ни было сделано внутри, оно исчезнет, когда ip netns exec
закончится. Это также объясняется в моей предыдущей ссылке. Вместо этого все равно будет нормально:
nsenter --net=/run/netns/test1 mount --bind /proc/self/ns/net /mnt/var/run/netns/test1
но, конечно, не требуется, так как это точно такой же объект, который можно проверить, имея тот же индекс в виртуальной файловой системе nsfs :
~# stat -f -c %T /run/netns/test1; stat -c %i /run/netns/test1
nsfs
4026533129
~# nsenter --net=/run/netns/test1 sh -c 'stat -f -L -c %T /proc/self/ns/net; stat -L -c %i /proc/self/ns/net'
nsfs
4026533129