Schneiden Sie die Standardlinienbreite in Bash dynamisch ab

9

In letzter Zeit habe ich mit dem psBefehl experimentiert , und manchmal werden lange Pfade zur nächsten Zeile (oder zu zwei) umgebrochen, was das Lesen erschwert. Ich möchte die psAusgabe in ein anderes Programm leiten, um die Ausgabe auf die xAnzahl der Zeichen zu beschränken.

Folgendes habe ich bisher, aber es funktioniert nicht ganz richtig:

ps aux | cut -c1-$(stty size | cut -d' ' -f2)

$(stty size | cut -d' ' -f2)ergibt 167, scheint aber keine gültige Eingabe für zu sein cut.

Gibt es eine Möglichkeit, diese Art von Syntax in Bash zum Laufen zu bringen?

Linsen
quelle
Diese Arbeit für mich. Können Sie eine Ausgabe liefern?
Cuonglm
Wo ist der dynamische Teil? Sie möchten für bestimmte Bedingungen eine andere Länge? Es scheint, als ob Sie alle Ausgaben auf eine maximale Länge beschränken
@awk_FTW Je nach Situation habe ich unterschiedliche Fenstereinstellungen. Im Vollbildmodus beträgt meine Breite 167. Bei anderen Größen muss ich jedoch kleiner sein. Deshalb möchte ich ssty anrufen, um die Größe zu erhalten.
Linsen
Versuchen Sietput rmam; ps aux
Stéphane Chazelas
Einige Muscheln mögen zsh, ksh93oder bashspeichern Sie die Anschlussbreite in$COLUMNS
Stéphane Chazelas

Antworten:

5

Folgendes funktioniert:

ps aux | cut -c1-$(stty size </dev/tty | cut -d' ' -f2)

Dies funktioniert auch:

v=$(stty size | cut -d' ' -f2) ; ps aux | cut -c1-$v

Das Problem scheint zu sein, dass sttydas tty auf seinem Standardeingang sein muss, um zu funktionieren. Die beiden oben genannten Ansätze lösen das.

Es gibt noch eine andere Option. Während sttysowohl stdin als auch stdout in den obigen Befehlen umgeleitet werden, ist es stderr nicht: Es zeigt immer noch auf ein Terminal. Seltsamerweise sttyfunktioniert es auch, wenn es stderr als Eingabe erhält:

ps aux | cut -c1-$(stty size <&2 | cut -d' ' -f2)
John1024
quelle
In der Tat! Genau das habe ich gesucht. Nur neugierig, warum hast du das Tee am Ende hinzugefügt?
Linsen
@linsen Ups, das teewurde hinzugefügt, als ich debuggte . Es ist jetzt weg.
John1024
Worauf bezieht sich <& 2? Ich habe diese Notation noch nie gesehen.
Linsen
@linsen In der Shell sind die Dateien nummeriert. Null bezieht sich auf die Standardeingabe, eins auf die Standardausgabe und zwei auf den Standardfehler. Der Ausdruck <&2bedeutet, dass Sie Ihre Eingabe vom Standardfehler erhalten.
John1024
1
sttyRuft die Einstellungen des Terminals auf seinem Standard auf (Sie können beispielsweise stty < /dev/other-ttydie Einstellungen eines anderen Terminals abrufen). Es ist also nicht seltsam, dass es nicht funktioniert, wenn sein Standard eine Pipe ist oder das <&2funktioniert.
Stéphane Chazelas
8

Einige Shells mögen zsh, bashoder mkshautomatisch die eingestellte $COLUMNSVariable auf die Breite des Anschlusses, so dass Sie nicht aufrufen brauchen sttyhier.

Alle Implementierungen von psI, die versucht haben, diese nicht standardmäßige (BSD-Typ) Syntax zu unterstützen, fragen die Terminalbreite selbst ab. Ich bin überrascht, dass deine es nicht tut. Ich gehe jedoch davon aus, dass der Inhalt der COLUMNS Umgebungsvariablen berücksichtigt wird.

So könnten Sie tun:

export COLUMNS; ps aux

Wenn nicht,

ps aux | cut -c"1-$COLUMNS"

Sie können Ihrem Terminal auch mitteilen, dass keine Zeilen umbrochen werden sollen:

tput rmam
ps aux
Stéphane Chazelas
quelle
4

Sie können die psAusgabe auch etwas besser handhaben .

ps --width ${n:-$COLUMNS} ${opts} #set ps terminal width

ps -ww ${opts} #no word wrap

ps -o ${only_interesting_output} ${opts} #trim output

Dadurch wird die psAusgabe nach Bedarf nach Ihren Vorgaben analysiert.

Wenn Sie jedoch keinen Zeilenumbruch verwenden, besteht natürlich das Problem, dass Informationen fehlen. Benötigen Sie wirklich alles für alle Prozesse? Öffnen Sie es in einem Pager, wenn ja:

ps ww ${opts} | $PAGER

Wenn nicht, geben Sie an, was Sie sehen möchten:

ps -o args= -p $pid

Alternativ können Sie psIhr Terminal explizit informieren --width:

man ps

...

w Breite Ausgabe. Verwenden Sie diese Option zweimal für unbegrenzte Breite.

-w Breite Ausgabe. Verwenden Sie diese Option zweimal für unbegrenzte Breite.

--width n Bildschirmbreite einstellen.

Das --widthDing funktioniert genau nach Ihren Anforderungen, ohne dass zusätzliche Filter oder Zusatzprozesse erforderlich sind (was Ihre -auxAusgabe wahrscheinlich nur noch mehr überladen wird ). Und mit $COLUMNSwie oben gezeigt und wie Stephane betont, wird es sogar dynamisch funktionieren.

Es ist jedoch wahrscheinlich erwähnenswert, dass ich finde, dass Leute oft versuchen, diese Art von unnötigen Filtern hinzuzufügen, damit sie einen |pipedurch einen anderen Filter aufnehmen können, um die Ausgabe zu analysieren, was wahrscheinlich auch unnötig ist. Natürlich meine ich mit Leuten meistens mich.

Mit dem -ooben erwähnten Utput-Operanden können Sie filtern, welche Spalten psangezeigt werden, und wenn Sie die =Zuordnung hinzufügen, können Sie die Spalte sogar nach Belieben benennen. Ich lasse die Zuweisung leer und übergebe ihr einen -pZielprozess, $pidsodass die einzige Ausgabe psüberhaupt der $pidBefehlsname und dessen argsAufruf ist. Und -okratzt kaum an der Oberfläche, wie Sie definieren können, was psangezeigt wird oder nicht. Dies ist die Richtung, die ich Ihnen empfehlen würde, insbesondere über:

man ps

... 

So zeigen Sie jeden Prozess auf dem System mithilfe der BSD-Syntax an:

ps ax

ps axu

So drucken Sie einen Prozessbaum:

ps -ejH

ps axjf

So erhalten Sie Informationen zu Threads:

ps -eLf

ps axms

So erhalten Sie Sicherheitsinformationen:

ps -eo euser,ruser,suser,fuser,f,comm,label

ps axZ

ps -eM

So sehen Sie jeden Prozess, der als Root (echte und effektive ID) im Benutzerformat ausgeführt wird:

ps -U root -u root u

So zeigen Sie jeden Prozess mit einem benutzerdefinierten Format an:

ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm

ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm

ps -Ao pid,tt,user,fname,tmout,f,wchan

Drucken Sie nur die Prozess-IDs von syslogd:

ps -C syslogd -o pid=

Drucken Sie nur den Namen von PID 42:

ps -p 42 -o comm=

mikeserv
quelle