Трубы в цепях броска `Операция не разрешена`
Симптом очень прост. Например:
ls | grep a | grep b | grep c | grep d
бросает
-bash: child setpgid (8948 to 8943): Operation not permitted
-bash: child setpgid (8950 to 8943): Operation not permitted
-bash: child setpgid (8952 to 8943): Operation not permitted
-bash: child setpgid (8953 to 8943): Operation not permitted
-bash: child setpgid (8954 to 8943): Operation not permitted
-bash: child setpgid (8955 to 8943): Operation not permitted
-bash: child setpgid (8962 to 8957): Operation not permitted
-bash: child setpgid (8964 to 8957): Operation not permitted
-bash: child setpgid (8966 to 8957): Operation not permitted
-bash: child setpgid (8967 to 8957): Operation not permitted
-bash: child setpgid (8968 to 8957): Operation not permitted
-bash: child setpgid (8969 to 8957): Operation not permitted
-bash: child setpgid (8976 to 8971): Operation not permitted
-bash: child setpgid (8978 to 8971): Operation not permitted
-bash: child setpgid (8980 to 8971): Operation not permitted
-bash: child setpgid (8981 to 8971): Operation not permitted
-bash: child setpgid (8982 to 8971): Operation not permitted
-bash: child setpgid (8983 to 8971): Operation not permitted
-bash: child setpgid (8990 to 8985): Operation not permitted
-bash: child setpgid (8992 to 8985): Operation not permitted
-bash: child setpgid (8994 to 8985): Operation not permitted
-bash: child setpgid (8995 to 8985): Operation not permitted
-bash: child setpgid (8996 to 8985): Operation not permitted
-bash: child setpgid (8997 to 8985): Operation not permitted
Номер grep
s и используемые трубы не имеют значения. Иногда ls | grep a
также выдает ошибку.
НАСКОЛЬКО МНЕ ИЗВЕСТНО, ls
объявление grep
не требует привилегий root. Таким образом, мне интересно, как решить эту проблему.
Текущая машина - Cent OS 5 (ядро 2.6.18). Если вам нужна более подробная информация, пожалуйста, дайте мне знать.
Добавлено: след ls
а также grep
type ls
ls is aliased to `ls -hF --color=auto'
which ls
/bin/ls
type grep
grep is /bin/grep
which grep
/bin/grep
Добавлено 2
В этот момент я обнаружил, что это не ограничивается ls и grep. Кажется, что это относится ко всем командам, использующим каналы. например, echo 'Hello' | tee outfile
выдает ту же ошибку.
Добавлено 3: в ответ на @Argonauts'
Поскольку журналы слишком длинные, обратитесь по https://gist.github.com/anonymous/5459fa0322d178f85b0cd2d5ee2add53.
Короче,
ulimit -a
- размер трубы (512 байт, -p) 8
- максимальное количество пользовательских процессов (-u) 129094
type log
говорит-bash: type: log: not found
ОКtrap -p
:trap -- 'history_to_syslog' DEBUG
, Это вызовет проблемы?- Пробная версия с очищенной средой: иногда без ошибок, но иногда с ошибками.
- Нужно исследовать
- Отладочный вывод Bash
- Strace
1 ответ
Вот несколько вещей, которые можно попробовать, которые в лучшем случае помогут решить вашу проблему, в худшем - выяснить, что это "не так". В некоторых случаях вы можете захотеть объединить шаги (например, strace и "попробовать с очищенной средой").
ULIMIT
Проверьте, нет ли у вас необычно низких пределов, установленных для числа разрешенных процессов в максимальном размере оболочки или конвейера, с помощью следующей команды:ulimit -a
Если можете, добавьте вывод этой команды к вашему вопросу.
логирование
В старых версиях bash конвейеры могли сломаться из-за включенных функций ведения журнала (bash < 4.1).
type log
Это должно вернуть что-то вроде "log: not found". Если вместо этого он возвращает определение функции, очистите его с помощью команды unset log
,
Отладочная ловушка
trap -p
Посмотрите, выводятся ли какие-либо ловушки, связанные с DEBUG или журналированием. Если они есть и / или определена функция журнала, вам нужно выяснить, где они определены и (хотя бы временно) удалить их.
Они могут быть определены в.bashrc,.bash_profile и любых других связанных файлах инициализации. Так как он, похоже, также влияет на root, его, скорее всего, можно найти в файле системного уровня, таком как / etc / bashrc или / etc / profile.
По крайней мере, вы можете удалить функцию trap и log из вашей текущей среды и посмотреть, решит ли она проблему.
Попробуйте с очищенной средой
Еще один способ проверить это, запустив переданные по каналу команды, используя (исправлено)
env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d
очистить окружающую среду (для этой последовательности команд). Возможно, вам придется изменить ваши команды, чтобы включить полные пути. Было бы целесообразно увидеть, если значения из ulimit -a
различны и в этой среде.
Отладочный вывод Bash
Перед запуском вашей последовательной передачи cmd введите set -x
в командной строке, которая включит отладку bash - все команды "за кадром" будут выведены на экран. Возможно, вы можете увидеть что-то странное - зацепку за другую вызываемую функцию, похожую на проблему журнала, рассмотренную выше - или другую странность.
Strace
Запустите команду с помощью strace:strace ls | grep a | grep b | grep c | grep d
и посмотрим, что именно происходит. Если вы хотите опубликовать эти результаты, вам, вероятно, нужно разместить их на pastebin или аналогичном сайте и опубликовать ссылку. Это наиболее вероятный подход к решению проблемы, но выходные данные могут быть трудно декодировать.
Обновить
После просмотра ваших журналов:
При использовании env -i каждый этап канала должен использовать его - каждый этап фактически является отдельным экземпляром оболочки. Виноват.
env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d
Функция журналирования, которая вызывается между каждым вызовом в сочетании с ловушкой DEBUG, почти наверняка является ошибкой, о которой я говорил. К сожалению, ошибка недоступна для просмотра даже с моей подпиской RHEL. Это https://bugzilla.redhat.com/show_bug.cgi?id=720464
Эта ошибка привела к состоянию гонки, когда ведение журнала происходило в сочетании с отладочными ловушками, и это именно то, что у вас происходит - набор -x четко показывает довольно обширное ведение журнала (для syslog) каждой команды, которая была выполнена.
Поскольку канал создает вложенные оболочки, вы не можете просто очистить его в оболочке верхнего уровня и выполнить команды по конвейеру. Следующая стадия будет определена. Повторное тестирование с изменением в пункте 1 выше покажет, что оно работает без этих хуков.
Отчет об ошибке указывает на отсутствие обратного порта исправления. Я поместил некоторые детали от rhel здесь: http://pastebin.com/dymenY7e
Вам нужно очистить ловушку и / или удалить определение функции ведения истории history_to_syslog. Если у вас есть root-доступ, вы определенно можете удалить это навсегда. В своем первоначальном ответе я дал несколько советов о том, где искать.
Вы можете попробовать проверить наличие обновлений для bash для centos 5, но в информации, которую я привел выше, указано, что обратный порт для rhel 5 не создан, поэтому вряд ли он был для centos 5.
Краткое обновление:
Чтобы немного прояснить связь между ошибкой и режимом сбоя - происходит то, что вызовы взаимодействия с идентификаторами процессов, связанными с функцией протоколирования и ловушкой DEBUG, происходят не по порядку - условие гонки - приводят к вызовам, таким как getppid, которые ссылаются на процессы которые были только что закрыты, что приводит к ошибке, которую вы видите.
С другой стороны, это агрессивная возможность ведения журнала. Сисадмин явно не верит в круг доверия.