Couper dynamiquement la largeur de la ligne standard dans Bash

9

Dernièrement, j'ai expérimenté avec la pscommande, et parfois de longs chemins passent à la ligne suivante (ou deux) et la rendent difficile à lire. Je veux diriger la pssortie vers un autre programme pour limiter la sortie au xnombre de caractères.

Voici ce que j'ai jusqu'à présent, mais cela ne fonctionne pas très bien:

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

$(stty size | cut -d' ' -f2)évalue à 167, mais ne semble pas être une entrée valide pour cut.

Existe-t-il un moyen de faire fonctionner ce type de syntaxe en bash?

Lentilles
la source
Ce travail pour moi. Pouvez-vous fournir une sortie?
cuonglm
où est la partie dynamique? Vous souhaitez une longueur différente pour certaines conditions? Il semble que vous souhaitiez limiter toutes les sorties à une seule longueur maximale
@awk_FTW Selon la situation, j'ai différents paramètres de fenêtre. En plein écran, ma largeur est de 167. Mais pour les autres tailles, je devrai être plus petit. C'est pourquoi je veux appeler ssty pour obtenir la taille.
lentilles
Essayeztput rmam; ps aux
Stéphane Chazelas
Certains coques aiment zsh, ksh93ou bashstockent la largeur du terminal dans$COLUMNS
Stéphane Chazelas

Réponses:

5

Les oeuvres suivantes:

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

Cela fonctionne également:

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

Le problème semble être qu'il sttydoit avoir le tty sur son entrée standard pour fonctionner. Les deux approches ci-dessus résolvent cela.

Il y a encore une autre option. Alors que sttystdin et stdout sont tous deux redirigés dans les commandes ci-dessus, son stderr ne l'est pas: il pointe toujours vers un terminal. Curieusement, sttycela fonctionnera également si on lui donne stderr comme entrée:

ps aux | cut -c1-$(stty size <&2 | cut -d' ' -f2)
John1024
la source
En effet, c'est le cas! C'était exactement ce que je cherchais. Juste curieux, pourquoi avez-vous ajouté le tee tt à la fin?
lentilles
@lentils Oups, l'a teeété ajouté lors du débogage. C'est parti maintenant.
John1024
À quoi <& 2 fait-il référence? Je n'ai jamais vu cette notation auparavant.
lentilles du
@lentils Dans le shell, les fichiers sont numérotés. Zéro fait référence à l'entrée standard, un à la sortie standard et deux à l'erreur standard. L'expression <&2signifie obtenir votre entrée d'erreur standard.
John1024
1
sttyobtient les paramètres du terminal ouverts sur son stdin (vous faites stty < /dev/other-ttypour obtenir les paramètres d'un autre terminal par exemple). Il n'est donc pas étrange que cela ne fonctionne pas si son stdin est un tuyau ou que cela <&2fonctionne.
Stéphane Chazelas
8

Quelques coquilles aiment zsh, bashou mkshrèglent automatiquement la $COLUMNSvariable à la largeur du terminal, de sorte que vous n'avez pas besoin d'invoquer sttyici.

Toutes les implémentations de psJ'ai essayé de prendre en charge cette syntaxe non standard (type BSD) interrogent la largeur du terminal par elles-mêmes. Je suis surpris que le vôtre ne le fasse pas. Je m'attends cependant à ce qu'il examine le contenu de la variable d' COLUMNS environnement .

Vous pourriez donc faire:

export COLUMNS; ps aux

Si non,

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

Vous pouvez également dire à votre terminal de ne pas boucler les lignes:

tput rmam
ps aux
Stéphane Chazelas
la source
4

Vous pouvez également gérer psun peu mieux la sortie.

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

ps -ww ${opts} #no word wrap

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

Cela indiquera psd'analyser sa sortie selon vos spécifications si nécessaire.

Bien sûr, si vous ne faites pas de retour à la ligne, vous avez le problème de manquer d'informations. Avez-vous vraiment besoin de tout cela pour tous les processus? Ouvrez-le dans un pager si c'est le cas:

ps ww ${opts} | $PAGER

Sinon, spécifiez ce que vous voulez voir:

ps -o args= -p $pid

Alternativement, vous pouvez explicitement informer psde votre terminal --width:

man ps

...

w Large sortie. Utilisez cette option deux fois pour une largeur illimitée.

-w Large sortie. Utilisez cette option deux fois pour une largeur illimitée.

--width n Définissez la largeur de l'écran.

La --widthchose fonctionne exactement selon les spécifications demandées sans avoir à impliquer de filtres supplémentaires ou de processus auxiliaires (ce qui ne fera qu'encombrer -auxencore plus votre sortie). Et $COLUMNScomme indiqué ci-dessus et comme le souligne Stéphane, cela fonctionnera même de manière dynamique.

Il est probablement intéressant de noter, cependant, que je trouve des gens essaient souvent d'ajouter ces types de filtres inutiles afin qu'ils puissent accueillir un |pipepar un autre filtre à la sortie parse qui est aussi très susceptible d'être inutile. Bien sûr, par les gens, je veux surtout dire moi.

L' -oopérande utput que je mentionne ci-dessus vous permet de filtrer les colonnes à psafficher, et lorsque vous ajoutez l' =assignation, vous pouvez même nommer la colonne à votre guise. Je laisse l'affectation vide et lui -premets un processus cible $pidafin que la seule sortie du pstout soit le $pidnom de la commande et son argsà l'invocation. Et -ogratte à peine la surface de la façon dont vous pouvez définir ce psqui sera affiché ou non. C'est la direction que je vous recommanderais de prendre, notamment via:

man ps

... 

Pour voir tous les processus du système à l'aide de la syntaxe BSD:

ps ax

ps axu

Pour imprimer un arbre de processus:

ps -ejH

ps axjf

Pour obtenir des informations sur les threads:

ps -eLf

ps axms

Pour obtenir des informations sur la sécurité:

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

ps axZ

ps -eM

Pour voir chaque processus exécuté en tant que root (ID réel et efficace) au format utilisateur:

ps -U root -u root u

Pour voir chaque processus avec un format défini par l'utilisateur:

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

Imprimez uniquement les ID de processus de syslogd:

ps -C syslogd -o pid=

N'imprimez que le nom du PID 42:

ps -p 42 -o comm=

mikeserv
la source