Чтобы не использовать под-оболочку или под-процесс, когда вывод составного списка {}
передается по трубопроводу >
, оболочка сохраняет дескриптор STDOUT до запуска составного списка и восстанавливает его после. Таким образом, exec >
в составном списке не переносит свое действие дальше точки, где старый дескриптор восстанавливается как STDOUT.
Давайте посмотрим на соответствующую часть strace bash -c '{ exec >/dev/null; } >/dev/null; echo hi' 2>&1 | cat -n
:
132 open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
133 fcntl(1, F_GETFD) = 0
134 fcntl(1, F_DUPFD, 10) = 10
135 fcntl(1, F_GETFD) = 0
136 fcntl(10, F_SETFD, FD_CLOEXEC) = 0
137 dup2(3, 1) = 1
138 close(3) = 0
139 open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
140 fcntl(1, F_GETFD) = 0
141 fcntl(1, F_DUPFD, 10) = 11
142 fcntl(1, F_GETFD) = 0
143 fcntl(11, F_SETFD, FD_CLOEXEC) = 0
144 dup2(3, 1) = 1
145 close(3) = 0
146 close(11) = 0
147 dup2(10, 1) = 1
148 fcntl(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
149 close(10) = 0
Вы видите, как в строке 134 дескриптор 1
(STDOUT
) копируется на другой дескриптор с индексом не ниже 10
(это то, что делает F_DUPFD
; он возвращает наименьший доступный дескриптор, начиная с заданного номера, после дублирования на этот дескриптор). Также посмотрите, как в строке 137 результат open("/dev/null")
(дескриптор 3
) копируется на дескриптор 1
(STDOUT
). Наконец, в строке 147
старый STDOUT
, сохраненный на дескрипторе 10
, копируется обратно на дескриптор 1
(STDOUT
). Чистый эффект заключается в изоляции изменения в STDOUT
в строке 144
(что соответствует внутреннему exec >/dev/null
).
Решение было предложено после этого руководства для установки ядра 4.4.0 на Mint. И переустановка докера (много раз, поскольку у меня была поврежденная предыдущая конфигурация), потому что я установил его с помощью однострочника и скрипта и, как мне кажется, не следовал инструкциям по установке на официальном сайте Docker.
Теперь я мог запустить его с помощью:
$ uname -r
4.4.0-040400-generic
$ docker version
Client:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
Не совсем решение проблемы, так как я не мог понять, почему это не работает, но это сейчас работает (протестировано с изображениями ubuntu и сонара, оба работали нормально).