5

If I connect to a linux device via serial adapter (no matter if pyserial, screen or minicom), and no matter how I change settings like stty when I enter a long command it gets line wrapped (specifically a space and a carriage return is entered). My knowledge in this area is so small that I couldn't even call myself a beginner, but is it possible that the tool which reads lines or the shell interpreter is wrapping the lines?

Again, changing stty's size to 60 100 didn't change the point where the line wrap happened at all.

Shell information:

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.

(no idea how I find out which build options were chosen)

4
6

Both the shell and the terminal are involved: most terminals that you will use do automatic line-wrapping. At startup, bash (in lib/readline/terminal.c) checks two termcap flags related to this:

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

which (refer to terminfo(5)) tell it if the terminal wraps lines in the special manner that VT100s (and related terminals) do:

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

That's the case for Linux console and xterm. When bash sees this, it will helpfully wrap when it decides your cursor is at the right margin (to avoid problems with the newline glitch), as seen in 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. */

At the same time, the terminal will wrap (by default) when it reaches the right margin. Using stty to increase the size of the terminal to 100 columns will not help, if your terminal does not have 100 columns (and the terminal does not know what you told stty). bash knows (or should, unless you have set the environment variable COLUMNS).

But supposing that your terminal window actually has 100 columns...

If bash is confused about the line-length, it will misbehave in a manner matching the OP's comment

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.

This is the subject of several bug reports (which should be part of the bash FAQ, but the only aspect mentioned there is the issue with nonprinting characters in a prompt).

Given that comment, it appears that the connection "linux device via serial adapter" used cannot tell the shell reliably how wide the terminal is, so it defaults to 80 columns.

The comment about busybox appears to be off target, given the followup edit showing that the actual shell is bash. But the comment about "serial adapter" implies that you won't get window-size events passed to the shell. Reading bash's source-code, it appears that in this situation, it will only get a useful screen-size when first initializing (bash only executes _rl_get_screen_size initially, or in response to a SIGWINCH).

But you can make a terminal description with the actual screen size, and use that in a subshell (which bash would use in the case where the system cannot supply a proper screensize):

#!/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
1
  • Very well explained. I hope I get around to testing that. – erikbwork Oct 13 '16 at 13:47
2

It's terminal emulator doing the linewrap. You can turn off it by sending terminal emulator some control sequence:

turn off linewrap:

$ printf %b '\033[?7l'

turn on linewrap:

$ printf %b '\033[?7h'

or using tput:

turn off linewrap

$ tput rmam     

turn on linewrap

$ tput smam

See man 5 terminfo for more details.

13
  • A copy&paste of the first command didn't resolve it. It's still wrapping. Checked with screen and in python via pyserial. Anyway what is the terminal emulator in a python command using pyserial? There is no screen, minicom or xterm involved. – erikbwork Jul 31 '14 at 9:01
  • @erikb85: I don't understand what you mean. See here: en.wikipedia.org/wiki/Terminal_emulator for terminal emulator definition. – cuonglm Jul 31 '14 at 9:04
  • I am not using a terminal emulator. I am opening a device file to connect to a serial port. Then I send and receive bytes. – erikbwork Jul 31 '14 at 9:20
  • 1
    If you don't use terminal emulator, this will not work. – cuonglm Jul 31 '14 at 9:36
  • @erikb85 You are using a terminal emulator (unless you were using a physical serial terminal — but then you wouldn't be using software like minicom). However the terminal emulator wraps at its right margin, so you wouldn't see that wrapping in normal use. – Gilles 'SO- stop being evil' Jul 31 '14 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.