verkettete Pfeifen in Bash wirft `Operation nicht erlaubt`

1119
Jeon

Das Symptom ist sehr einfach. Zum Beispiel:

ls | grep a | grep b | grep c | grep d 

wirft

-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 

Die Anzahl der verwendeten greps und Pipes spielt keine Rolle. Manchmal ls | grep awirft auch der Fehler.

AFAIK, lsanad grepbenötigt kein Root-Privileg. Daher wundere ich mich, wie ich dieses Problem lösen kann.

Die aktuelle Maschine ist Cent OS 5 (Kernel 2.6.18). Wenn Sie genauere Informationen benötigen, lassen Sie es mich wissen.

Hinzugefügt: Spur von lsundgrep

type ls ls is aliased to `ls -hF --color=auto' which ls /bin/ls type grep grep is /bin/grep which grep /bin/grep 

Hinzugefügt 2

In diesem Moment habe ich festgestellt, dass dies nicht auf ls und grep beschränkt ist. Es scheint, dass es für alle Befehle gilt, die Pipes verwenden. zB echo 'Hello' | tee outfilewirft den gleichen Fehler.

3 hinzugefügt: als Antwort auf @Argonauts '

Da Protokolle zu lang sind, wenden Sie sich bitte an https://gist.github.com/anonymous/5459fa0322d178f85b0cd2d5ee2add53 .

Zusamenfassend,

  • ulimit -a
    • Pipe-Größe (512 Byte, -p) 8
    • maximale Benutzerprozesse (-u) 129094
  • type logsagt -bash: type: log: not found: OK
  • trap -p: trap -- 'history_to_syslog' DEBUG. Würde es Probleme verursachen?
  • Test mit gelöschter Umgebung: manchmal kein Fehler, aber manchmal Fehler.
  • Müssen untersucht werden
    • Bash-Debug-Ausgabe
    • Strace
5
Haben Sie "ls" oder "grep" an etwas anderes gebunden? DavidPostill vor 7 Jahren 0
@DavidPostill, siehe meine bearbeitete Frage. Jeon vor 7 Jahren 0
Entfernen Sie den Alias ​​von 'ls' und sehen Sie, ob das Problem dadurch behoben wird ... DavidPostill vor 7 Jahren 0
Immer noch das gleiche. Ich habe kein Backtick gesetzt. Ich denke, es ist die Art und Weise, dass das System das Ergebnis von "type" anzeigt. Nach dem Entfernen des Alias ​​erhalte ich das Ergebnis von `type ls`:` ls ist ein Alias ​​von \ `ls --color = tty'`. Ich weiß nicht, welches Skript dieses Alias ​​genannt hat. nicht ".bashrc", ".bash_profile", ".profile" oder "/ etc / bashrc" Jeon vor 7 Jahren 0
Hmm. Dann gibt es noch etwas, was 'ls' modifiziert. Eine Funktion vielleicht? DavidPostill vor 7 Jahren 0
In diesem Moment habe ich festgestellt, dass dies nicht auf "ls" und "grep" beschränkt ist. Es scheint, dass es für alle Befehle gilt, die Pipes verwenden. zB `echo 'Hello' | tee outfile` wirft den gleichen Fehler. Ich werde das auf die Frage stellen. Jeon vor 7 Jahren 0
Haben Sie versucht, Ihren Computer neu zu starten? DavidPostill vor 7 Jahren 0
Ich habe kein Abonnement, um es zu lesen, aber wenn Sie ein RHEL-Abonnement haben, scheint dieser Link hilfreich zu sein: https://access.redhat.com/solutions/410333 Eric Renouf vor 7 Jahren 1
Ist es nur "bash" oder geben andere Shells ("sh", "csh", "zsh" usw., je nachdem, welche Sie installiert haben) auch das Problem an? Es ist sicherlich kein generisches `bash'-Problem. AFH vor 7 Jahren 0
@Eric Renouf, ja, ich habe diesen Artikel gefunden. Ich habe Angst, dass ich auch kein Abonnement habe. @AFH, Getestet mit Dutzenden von Versuchen auf 'sh', bis jetzt keine Fehler. Nicht getestet auf "csh" oder "zsh". Demnach ist `bash` falsch konfiguriert? Jeon vor 7 Jahren 0
Es hört sich an, als ob eine Ressource zur Neige geht und @ DavidPostills Vorschlag für einen Neustart scheint ein guter zu sein: Zumindest leeren Sie das `/ tmp`-Verzeichnis. Da dies jedoch ein Berechtigungsfehler ist, sollten Sie auch versuchen, unter `sudo -s` auszuführen. AFH vor 7 Jahren 0
Läuft Ihr System in einem Container? Julie Pelletier vor 7 Jahren 0
Funktionieren `ls` und` grep` in Ordnung, wenn Sie sie separat eingeben, dh wenn Sie die Ausgabe von ls nicht in grep leiten? ZB erzeugen "ls / etc" und "grep localhost / etc / hosts" die erwartete Ausgabe? Haben Sie ein anderes Benutzerkonto, von dem Sie testen können, und zeigt das gleiche Problem? Wenn Sie sich beim Root-Konto anmelden und dieselben Befehle ausführen, erhalten Sie die Fehlermeldung oder die erwartete Ausgabe? moonpoint vor 7 Jahren 0
Entschuldigung für spät 1. Die Ausführung von Befehlen mit `sudo -s` löst ebenfalls den gleichen Fehler aus. Und jeder getrennte Befehl läuft fehlerfrei. Jeon vor 7 Jahren 0
@EricRenouf hast du es genannt Argonauts vor 7 Jahren 0

1 Antwort auf die Frage

1
Argonauts

Hier sind ein paar Dinge, die Sie ausprobieren sollten, um Ihr Problem am besten zu lösen, im schlimmsten Fall, um herauszufinden, was es "nicht" ist. In einigen Fällen möchten Sie möglicherweise die Schritte kombinieren (z. B. strace und 'try with cleared environment').

Ulimit

Überprüfen Sie mit dem folgenden Befehl, ob ungewöhnlich niedrige Grenzwerte für die Anzahl der zulässigen Prozesse in Ihrer Shell oder Pipeline festgelegt sind: ulimit -a

Wenn Sie können, hängen Sie die Ausgabe dieses Befehls an Ihre Frage an.

Protokollierung

Bei älteren Versionen von Bash konnten Pipelines aufgrund von aktivierten Protokollierungsfunktionen brechen (Bash <4.1).

type log
Das sollte etwas wie 'log: not found' zurückgeben. Wenn stattdessen eine Funktionsdefinition zurückgegeben wird, löschen Sie sie mit dem Befehl unset log.

Debug-Falle

trap -p

Prüfen Sie, ob Traps ausgegeben werden, die mit DEBUG oder der Protokollierung verknüpft sind. Wenn sie definiert sind und / oder eine Protokollfunktion definiert ist, müssen Sie herausfinden, wo sie definiert sind, und sie (zumindest vorübergehend) entfernen.

Sie können in .bashrc, .bash_profile und anderen zugehörigen Initialisierungsdateien definiert werden. Da es sich scheinbar auch auf root auswirkt, wird es wahrscheinlich in einer Datei auf Systemebene wie / etc / bashrc oder / etc / profile gefunden .

Zumindest können Sie die Trap- und Log-Funktion aus Ihrer aktuellen Umgebung löschen und sehen, ob das Problem dadurch gelöst wird.

Versuchen Sie es mit einer gelöschten Umgebung

Eine andere Methode, um dies zu überprüfen, ist die Ausführung der übergebenen Befehle mit (fix).

env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d

um die Umgebung (für diese Befehlsfolge) zu löschen. Möglicherweise müssen Sie Ihre Befehle so ändern, dass sie vollständige Pfade enthalten. Es lohnt sich zu sehen, ob die Werte ulimit -ain dieser Umgebung auch anders sind.

Bash-Debug-Ausgabe

Bevor Sie Ihre gepipste cmd-Sequenz ausführen, geben Sie set -xin die Befehlszeile ein. Dadurch wird das Bash-Debugging aktiviert. Alle Befehle hinter den Kulissen werden auf dem Bildschirm gedruckt. Es ist möglich, dass Sie etwas Ungewöhnliches sehen - ein Haken an einer anderen Funktion, die ähnlich wie das oben diskutierte Protokollproblem genannt wird - oder eine andere Ungewöhnlichkeit.

Strace

Führen Sie den Befehl mit strace aus:
strace ls | grep a | grep b | grep c | grep d

und sehen was genau los ist. Wenn Sie diese Ergebnisse veröffentlichen möchten, müssen Sie sie wahrscheinlich auf Pastebin oder einer ähnlichen Website veröffentlichen und einen Link posten. Dies ist der wahrscheinlichste Ansatz, um das Problem zu lösen, die Ausgabe kann jedoch schwierig zu decodieren sein.

Aktualisieren

Nachdem Sie Ihre Protokolle überprüft haben:

  1. Bei der Verwendung von env -i muss jede Stufe der Pipe verwendet werden - jede Stufe ist tatsächlich eine separate Shell-Instanz. Mein Fehler. env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d

  2. Die Protokollierungsfunktion, die zwischen jedem Aufruf und dem DEBUG-Trap aufgerufen wird, ist fast definitiv der Fehler, auf den ich mich bezogen habe. Leider kann der Fehler auch mit meinem RHEL-Abonnement nicht angezeigt werden. Es ist https://bugzilla.redhat.com/show_bug.cgi?id=720464

Dieser Fehler führte zu einer Wettlaufsituation, als die Protokollierung in Verbindung mit Debug-Traps auftrat. Genau das, was Sie gerade gemacht haben - das set -x zeigt deutlich die ziemlich umfangreiche Protokollierung (in syslog) jedes Befehls, der ausgegeben wird.

Da eine Pipe Sub-Shells erstellt, können Sie sie nicht einfach in der Shell der obersten Ebene löschen und Pipe-Befehle ausgeben. In der nächsten Pipeline-Stufe wird es definiert. Das erneute Testen mit der Änderung in Punkt 1 oben zeigt, dass es ohne diese Haken funktioniert.

Der Fehlerbericht zeigt keinen Rückport des Fixes an. Ich habe hier einige Details von Rhel eingefügt: http://pastebin.com/dymenY7e

Sie müssen den Trap löschen und / oder die Definition der Protokollierungsfunktion history_to_syslog entfernen. Wenn Sie über Root-Zugriff verfügen, können Sie diese definitiv entfernen. Ich habe in meiner ursprünglichen Antwort einige Tipps gegeben, wo ich suchen muss.

Sie könnten versuchen, nach einem Update für basos 5 für centos 5 zu suchen, aber die Informationen, die ich oben verlinkt habe, besagen, dass kein rückseitiger Port für rhel 5 erstellt wurde. Es ist also unwahrscheinlich, dass man für centos 5 war.

Kurzes Update:

Um die Verbindung zwischen dem Fehler und dem Fehlermodus ein wenig zu verdeutlichen, werden Aufrufe zur Interaktion mit Prozess-IDs, die der Protokollierungsfunktion und dem DEBUG-Hook zugeordnet sind, außerhalb der Reihenfolge - der Race-Bedingung - ausgeführt, was zu Aufrufen wie beispielsweise getppid führt, die auf Referenzprozesse verweisen die gerade geschlossen wurden, was zu dem Fehler führt, den Sie sehen.

Nebenbei bemerkt ist dies eine aggressive Protokollierungsfunktion. Der Sysadmin glaubt eindeutig nicht an den Vertrauenskreis.

Danke, dass Sie mir einen Weg gegeben haben. Ich habe alle obigen Befehle ausprobiert und als Protokolldateien hinterlegt. Ich habe sie im OP hinzugefügt und ich werde mich darum kümmern. Jeon vor 7 Jahren 0