Como remover quebra de linha dos comandos DNF e YUM?

4

Ao usar dnf e yum em distribuições Linux baseadas em rpm (RHEL / Red Hat, Fedora, CentOS, etc), o utilitário quebrará linhas automaticamente para torná-lo mais amigável para o usuário ler. Isso é problemático, pois torna extremamente irritante trabalhar com os dados por meio de pipelining.

Por exemplo:

$ dnf search jenkins-ssh-credentials-plugin-javadoc
Last metadata expiration check: 6 days, 15:30:08 ago on Thu Sep  1 21:09:10 2016.
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc =============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin
$ dnf search jenkins-ssh-credentials-plugin-javadoc | grep ssh
====== N/S Matched: jenkins-ssh-credentials-plugin-javadoc =======
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for
                                              : jenkins-ssh-credentials-plugin

Você pode ver que, uma vez que a saída para DNF é passada por grep , ela decide agrupar os dados de uma maneira completamente diferente de quando normalmente exibidos ao usuário.

Várias questões foram arquivadas sobre esse comportamento ( # 584525 , #986740 ) e consistentemente os problemas são fechados como CLOSED NOTABUG porque "Yum é uma interface de usuário interativa baseada em texto que não é adequada, nem destinado à tubulação ". A solução dos desenvolvedores da Red Hat é "usar uma ferramenta diferente para o trabalho".

Parece irrazoável ter que fazer isso, especialmente quando os métodos fornecidos (instale repoquery por exemplo) nem mesmo existam dentro dos utilitários dnf e exijam a instalação de mais uma dúzia de pacotes apenas para analisar a saída desses dados.

Idealmente, um usuário seria capaz de usar apenas os dados no pipeline. Em vez disso, seria bom ter um simples one-liner que poderia ser usado para tornar os dados utilizáveis.

    
por Brian Redbeard 08.09.2016 / 22:07

2 respostas

2

yum e dnf gravam mensagens de progresso, superando uma linha usando retornos de carro. Essas mensagens não estão envolvidas . grep não foi criado para isso, supondo que as linhas não possuam caracteres de controle incorporados. grep faz algumas suposições sobre terminais, mas isso é uma história diferente .

Eu uso um script sed para filtrar as linhas de sobrecorrente para uma linha "final" (excluindo toda a parte do overstruck). No exemplo script2log.sed ,

# $Id: script2log.sed,v 1.3 2015/02/04 23:50:12 tom Exp $
#
# Trim ordinary ANSI sequences, then OSC sequences, then backspace
# sequences, then trailing CR's and finally overstruck sections of
# lines.
#
# There are still several interesting cases which cannot be handled
# with a script of this sort.  For example:
#       CSI K (clear line)
#       cursor movement within the line
s/␛[[][<=>?]\{0,1\}[;0-9]*[@-~]//g
s/␛[]][^␛]*␇//g
s/␛[]][^␛]*␛\//g
:loop
s/[^␈]␈\(.\)//g
t loop
s/␍␍*$//g
s/^.*␍//g
s/␛[^[]//g

Isso é feito com esses dois comandos, que primeiro remove qualquer número de retornos de carro à direita em uma linha e, em seguida, remove qualquer seção da linha incluindo um retorno de carro. O que resta é apenas a última cópia da linha a ser escrita (aquela que você quer):

s/␍␍*$//g
s/^.*␍//g

(e sim, esses são caracteres de retorno de carro literais no script).

Quando eu capturar a saída de yum (ou dnf ), eu não tento canalizar para grep (que é garantido para produzir resultados ruins). Em vez disso, eu uso script para capturar a saída e pós-processamento que usa sed , por exemplo,

script -c "yum upgrade"
sed -f script2log.sed typescript >upgrade.log
    
por 08.09.2016 / 22:17
1

Há uma ótima lista de comandos / encantamentos de "exemplo" para sed que foram selecionados por um longo tempo usando o nome sed1line.txt ( link ). Neste arquivo, há um ótimo exemplo que é útil neste caso:

# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'

No caso de nossa saída dnf / yum , sabemos que as linhas quebradas começarão com uma ou mais instâncias de espaço em branco, seguidas por dois pontos (:), seguidas por mais espaço em branco. Usando esse conhecimento, podemos modificar nosso exemplo de sed para considerar isso e unir as linhas:

sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D'

Nesse caso, temos uma decisão a tomar, porque o + faz parte do conjunto de expressões regulares "estendidas", precisamos adicionar o -r para usar o símbolo + ou voltar a usar * em seu lugar (que corresponderá a zero ou mais instâncias de espaço em branco). Ou vai funcionar, o exemplo acima foi fornecido para ser pedanticamente correto.

O resultado é o seguinte:

$ dnf search jenkins-ssh-credentials-plugin-javadoc | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D'  | grep ssh
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc ==============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin

Como você pode ver, agora grep funciona como esperado. Além disso, isso permite que você faça uma formatação mais criativa da saída para facilitar a digitalização pela lista de pacotes:

$ dnf search ssh | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D' | sort  | awk -F: '!($1~/^====/) {printf "%-40s : %s\n", $1, substr($0, index($0, $2))}'
ansible.noarch                           :  SSH-based configuration management, deployment, and task execution system
apache-sshd-javadoc.noarch               :  API documentation for apache-sshd
apache-sshd.noarch                       :  Apache SSHD
autossh.x86_64                           :  Utility to autorestart SSH tunnels
bareftp.x86_64                           :  File transfer client supporting the FTP, FTP over SSL/TLS (FTPS) and SSH
belier.noarch                            :  Generates scripts allowing you to chain many ssh connections
btrfs-sxbackup.noarch                    :  Incremental btrfs snapshot backups with push/pull support via SSH
...
trilead-ssh2.noarch                      :  SSH-2 protocol implementation in pure Java
WebShell.noarch                          :  SSL server for web-based SSH access from browsers and mobile devices
x11-ssh-askpass.x86_64                   :  A passphrase dialog for X and not only for OpenSSH
    
por 08.09.2016 / 22:07