Corte dinamicamente a largura da linha stdout no Bash

9

Ultimamente, tenho experimentado o pscomando e, às vezes, caminhos longos são agrupados na próxima linha (ou duas) e dificultam a leitura. Quero canalizar a pssaída para outro programa para limitar a saída ao xnúmero de caracteres.

Aqui está o que tenho até agora, mas não funciona muito bem:

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

$(stty size | cut -d' ' -f2)é avaliado como 167, mas não parece ser uma entrada válida para cut.

Existe uma maneira de obter esse tipo de sintaxe para trabalhar no bash?

lentilhas
fonte
Este trabalho para mim. Você pode fornecer alguma saída?
cuonglm
onde está a parte dinâmica? Você quer um comprimento diferente para certas condições? Parece que você quer limitar todas as saídas para um comprimento máximo
@awk_FTW Dependendo da situação, tenho diferentes configurações de janela. Em tela cheia, minha largura é 167. Mas em outros tamanhos, precisarei ser menor. É por isso que quero chamar de instável para obter o tamanho.
Lentils
Tentetput rmam; ps aux
Stéphane Chazelas
Alguns escudos gosto zsh, ksh93ou basharmazenar a largura terminal$COLUMNS
Stéphane Chazelas

Respostas:

5

Os seguintes trabalhos:

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

Isso também funciona:

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

O problema parece ser que sttyprecisa ter o tty em sua entrada padrão para funcionar. As duas abordagens acima resolvem isso.

Ainda existe outra opção. Enquanto sttystdin e stdout são redirecionados nos comandos acima, seu stderr não é: ainda aponta para um terminal. Estranhamente, sttytambém funcionará se receber stderr como entrada:

ps aux | cut -c1-$(stty size <&2 | cut -d' ' -f2)
John1024
fonte
De fato, sim! Era exatamente isso que eu estava procurando. Apenas curioso, por que você adicionou a camiseta no final?
Lentils
@ Lentils Ops, o teefoi adicionado quando eu estava depurando. Agora se foi.
John1024
A que <& 2 se refere? Eu nunca vi essa notação antes.
lentilhas
@ lentils No shell, os arquivos são numerados. Zero refere-se à entrada padrão, um à saída padrão e dois ao erro padrão. A expressão <&2significa obter sua entrada do erro padrão.
precisa saber é o seguinte
1
sttyabre as configurações do terminal em seu stdin (você faz stty < /dev/other-ttypara obter as configurações de outro terminal, por exemplo). Portanto, não é estranho que não funcione se o seu stdin for um cachimbo ou se <&2funcionar.
Stéphane Chazelas
8

Alguns escudos gosto zsh, bashou mkshautomaticamente definir a $COLUMNSvariável para a largura do terminal, para que você não precisa invocar sttyaqui.

Todas as implementações de psque tentei que suportam essa sintaxe não padrão (tipo BSD) consultam a largura do terminal por si próprias. Estou surpreso que o seu não. Espero que ele analise o conteúdo da variável de COLUMNS ambiente .

Então você poderia fazer:

export COLUMNS; ps aux

Se não,

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

Você também pode dizer ao seu terminal para não quebrar as linhas:

tput rmam
ps aux
Stéphane Chazelas
fonte
4

Você também pode lidar com a pssaída um pouco melhor.

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

ps -ww ${opts} #no word wrap

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

Isso indicará pspara analisar sua saída com suas especificações, conforme necessário.

É claro que, se você não usar quebra de linha, terá o problema de perder informações. Você realmente precisa de tudo isso para todos os processos? Abra-o em um pager, se houver:

ps ww ${opts} | $PAGER

Caso contrário, especifique o que você deseja ver:

ps -o args= -p $pid

Como alternativa, você pode informar explicitamente sobre o psseu terminal --width:

man ps

...

w Ampla saída. Use esta opção duas vezes para largura ilimitada.

-w Ampla saída. Use esta opção duas vezes para largura ilimitada.

--width n Defina a largura da tela.

A --widthcoisa funciona exatamente com as especificações solicitadas, sem a necessidade de envolver filtros adicionais ou processos auxiliares (o que provavelmente sobrecarregará -auxainda mais a sua saída). E com $COLUMNScomo mostrado acima e como Stephane aponta, ele funcionará dinamicamente.

Provavelmente é importante notar, porém, que acho que as pessoas muitas vezes tentam adicionar estes tipos de filtros desnecessários para que possam acomodar um |pipeatravés de outro filtro para a saída de análise que é também bastante provável que seja desnecessário. Claro, pelas pessoas eu principalmente me refiro .

O -ooperando utput que mencionei acima permite filtrar quais colunas são psexibidas e, quando você adiciona a =atribuição, pode até nomear a coluna como desejar. Deixo a atribuição vazia e entregá-lo um alvo -process $pidentão a única saída psem tudo é o $pidnome do comando e sua argsa invocação. E -omal arranha a superfície de como você pode definir o que psserá ou não exibido. Esta é a direção que eu recomendo que você tome, especialmente via:

man ps

... 

Para ver todos os processos no sistema usando a sintaxe BSD:

ps ax

ps axu

Para imprimir uma árvore de processo:

ps -ejH

ps axjf

Para obter informações sobre tópicos:

ps -eLf

ps axms

Para obter informações de segurança:

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

ps axZ

ps -eM

Para ver todos os processos em execução como raiz (ID real e efetivo) no formato do usuário:

ps -U root -u root u

Para ver todos os processos com um formato definido pelo usuário:

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

Imprima apenas os IDs do processo de syslogd:

ps -C syslogd -o pid=

Imprima apenas o nome do PID 42:

ps -p 42 -o comm=

mikeserv
fonte