5

Симптом очень прост. Например:

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 и каналов не имеет значения. Иногда ls | grep a также выдает ошибку.

AFAIK, ls anad 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 ответ1

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 или аналогичном сайте и опубликовать ссылку. Это наиболее вероятный подход к решению проблемы, но выходные данные могут быть трудно декодировать.

Обновить

После просмотра ваших журналов:

  1. При использовании env -i каждый этап канала должен использовать его - каждый этап фактически является отдельным экземпляром оболочки. Виноват. env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d

  2. Функция ведения журнала, которая вызывается между каждым вызовом в сочетании с ловушкой 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, ссылаются на процессы которые были только что закрыты, что приводит к ошибке, которую вы видите.

С другой стороны, это агрессивная возможность ведения журнала. Сисадмин явно не верит в круг доверия.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .