ip netns monitor не работает в скрипте
Я пытаюсь использовать ip netns monitor
в сценарии для реагирования на создание новых сетевых пространств имен, например:
ip netns monitor | while read ACTION NETNS; do
echo 'handling it!'
done
Однако я никогда не вижу выход из ip netns monitor
в этом случае использования. Дальнейшие эксперименты показывают, что я никогда не вижу результатов от ip netns monitor
если он перенаправлен или передан по трубопроводу.
Вот простой пример того, что дает ожидаемый результат:
$ ip netns monitor &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
add dummy
delete dummy
А вот еще один пример использования, который дает нулевой вывод:
$ ip netns monitor >/tmp/ip-netns-monitor.log 2>&1 &
$ ip netns monitor | cat &
$ touch /var/run/netns/dummy ; sleep 2 ; rm /var/run/netns/dummy
$ cat /tmp/ip-netns-monitor.log
# no results
Я отследил свою версию ip
Назад к этой реализации монитора: http://git.kernel.org/cgit/linux/kernel/git/shemminger/iproute2.git/tree/ip/ipnetns.c?id=3c61c01a666d9f4dbb871305ab6791e19ede7d4a#n462
Я не вижу в источнике ничего очевидного, что могло бы привести к изменению поведения в зависимости от того, на что указывает STDOUT, - но я все еще новичок во всем этом.
Есть ли способ, которым я должен использовать ip netns monitor
чтобы он работал в скрипте? Или я должен где-нибудь поднять ошибку?
Если это действительно сломано, я могу попробовать обходной путь с inotifywait
вместо.
Моя система:
$ ip -Version
ip utility, iproute2-ss131122
$ lsb_release --description
Description: Ubuntu 14.04.2 LTS
$ uname -rvm
3.13.0-45-generic #74-Ubuntu SMP Tue Jan 13 19:36:28 UTC 2015 x86_64
Обновить
Я запустил интерактивные и перенаправленные варианты с strace
и результаты следуют.
Метод:
while true; do touch /var/run/netns/dummy ; sleep 2; rm /var/run/netns/dummy; sleep 2; done &
strace -ivy ip netns monitor
strace -ivy ip netns monitor | cat
Помимо некоторых адресов и дескрипторов, strace показывает одинаковую инициализацию для обоих. То, где они различаются, следует за первым прочитанным от inotify.
Интерактивный (т.е. без | cat
) производит:
[00007ffe9274c767] inotify_init() = 4
[00007ffe9274c737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007ffe9273d3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\1\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007ffe9273cd84] fstat(1</dev/pts/0>, {st_dev=makedev(0, 12), st_ino=3, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 0), st_atime=2015/04/05-20:55:28, st_mtime=2015/04/05-20:55:36, st_ctime=2015/04/05-04:17:42}) = 0
[00007ffe9274655a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffe92e3a000
[00007ffe9273d400] write(1</dev/pts/0>, "add dummy\n", 10add dummy) = 10
[00007ffe9273d3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007ffe9273d400] write(1</dev/pts/0>, "delete dummy\n", 13delete dummy) = 13
Перенаправленный (т.е. с | cat
) производит:
[00007f607d90e767] inotify_init() = 4
[00007f607d90e737] inotify_add_watch(4<anon_inode:inotify>, "/var/run/netns", IN_CREATE|IN_DELETE) = 1
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007f607d8fed84] fstat(1<pipe:[154785]>, {st_dev=makedev(0, 8), st_ino=154785, st_mode=S_IFIFO|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2015/04/05-21:04:54, st_mtime=2015/04/05-21:04:54, st_ctime=2015/04/05-21:04:54}) = 0
[00007f607d90855a] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f607dffc000
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\1\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
[00007f607d8ff3a0] read(4<anon_inode:inotify>, "\1\0\0\0\0\2\0\0\0\0\0\0\20\0\0\0dummy\0\0\0\0\0\0\0\0\0\0\0", 4096) = 32
Итак, при перенаправлении fstat
имеет разные результаты (как и ожидалось), но write
никогда не называется. Результат read
показать, что уведомления приходят, как и ожидалось. А также ip netns monitor
должен быть счастлив, что нет ошибки, потому что он продолжает цикл.
1 ответ
Я предполагаю, что это, возможно, вы столкнулись с проблемой, когда stdout на трубе буферизует на 4K. См. https://unix.stackexchange.com/a/25378 для некоторых идей по ее исправлению. Чтобы подтвердить, что это ваша конкретная проблема, попробуйте изменить имя вашего фиктивного файла на что-то намного большее или несколько раз вызвать touch / rm, чтобы получить достаточно выходных данных, чтобы достичь размера буфера по умолчанию.