Quem faz o linewrap e como desativar?

2

Se eu me conectar a um dispositivo linux via adaptador serial (não importa se pyserial, screen ou minicom), e não importa como eu altero configurações como stty quando eu insiro um comando longo ele recebe line wrap (especificamente um espaço e um retorno de carro é inserido). Meu conhecimento nesta área é tão pequeno que eu não poderia nem mesmo me chamar de iniciante, mas é possível que a ferramenta que lê linhas ou o interpretador de shell esteja envolvendo as linhas?

Mais uma vez, a alteração do tamanho de stty para 60 100 não alterou o ponto em que ocorreu a quebra de linha.

Informações da shell:

root@4020-1-00007:~# echo $SHELL
/bin/sh
root@4020-1-00007:~# ls -al /bin/sh 
lrwxrwxrwx    1 root     root             9 Jul 31 18:09 /bin/sh -> /bin/bash
root@4020-1-00007:~# bash --version
GNU bash, version 4.3.0(1)-release (arm-angstrom-linux-gnueabi)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

(não tenho ideia de como descobrir quais opções de compilação foram escolhidas)

    
por erikbwork 31.07.2014 / 09:59

2 respostas

4

O shell e o terminal estão envolvidos: a maioria dos terminais que você usará faz o envolvimento automático de linha. Na inicialização, bash (em lib / readline / terminal.c ) verifica dois flags termcap relacionados a isso:

  _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");

qual (refira terminfo (5) ) diga se o terminal envolve linhas em a maneira especial que os VT100s (e terminais relacionados) fazem:

   auto_right_margin         am     am   terminal has automatic
                                         margins
   eat_newline_glitch        xenl   xn   newline ignored
                                         after 80 cols (concept)

Esse é o caso do console Linux e do xterm. Quando o bash vir isto, ele será útil quando decidir que seu cursor está na margem direita (para evitar problemas com a falha da nova linha), como pode ser visto em display.c :

  /* If we're at the right edge of a terminal that supports xn, we're 
     ready to wrap around, so do so.  This fixes problems with knowing 
     the exact cursor position and cut-and-paste with certain terminal 
     emulators.  In this calculation, TEMP is the physical screen 
     position of the cursor. */

Ao mesmo tempo, o terminal entrará em vigor (por padrão) quando it atingir a margem direita. Usar stty para aumentar o tamanho do terminal para 100 colunas não ajudará, se o seu terminal não tiver 100 colunas (e o terminal não souber o que você disse stty ). bash sabe (ou deve, a menos que você tenha definido a variável de ambiente COLUMNS ).

Mas supondo que sua janela de terminal tenha realmente 100 colunas ...

Se o bash estiver confuso sobre o tamanho da linha, ele se comportará mal de forma que corresponda ao comentário do OP

And the minimal example is open a serial connection and enter some keys until the line is full, then it gets broken and either continues on the next line or the same line just in the front.

Este é o assunto de vários relatórios de bugs (que devem fazer parte do FAQ do bash , mas o único aspecto mencionado ali é o problema com caracteres não imprimíveis em um prompt).

Dado esse comentário, parece que a conexão "dispositivo linux via serial adaptador" usado não pode dizer ao shell de forma confiável quão largo o terminal é, então ele é 80 colunas.

O comentário sobre busybox parece estar fora do alvo, dada a seguinte edição mostrando que o shell atual é bash. Mas o comentário sobre "adaptador serial" implica que você não obterá eventos de tamanho de janela passados para o shell. Lendo o código-fonte do bash, parece que nessa situação, ele só terá um tamanho de tela útil quando for inicializado pela primeira vez (o bash somente executa _ rl_get_screen_size inicialmente, ou em resposta a um SIGWINCH ).

Mas você pode fazer uma descrição do terminal com o tamanho real da tela, e usá-la em um subshell (que o bash usaria no caso em que o sistema não pode fornecer um tamanho adequado):

#!/bin/sh                                                           
infocmp -1 | \
sed     -e 's/^[^[:space:]].*|/fixed|/' \
        -e '/lines#/d' \
        -e '/cols#/d' \
        >foo
resize -u | awk '
/COLUMNS=/{ sub("COLUMNS=","cols#"); }
/LINES=/{ sub("LINES=","lines#"); }
/export/{ next; }
        { sub(";",","); printf "\t%s\n", $0; }
' >>foo
tic foo
TERM=fixedsize bash
    
por 13.10.2016 / 01:45
1

É o emulador de terminal que faz o linewrap. Você pode desativá-lo enviando ao emulador de terminal alguma seqüência de controle :

desativar o linewrap:

$ printf %b '3[?7l'

ativar o linewrap:

$ printf %b '3[?7h'

ou usando tput :

desativar o linewrap

$ tput rmam     

ativar linewrap

$ tput smam

Veja man 5 terminfo para mais detalhes.

    
por 31.07.2014 / 10:39