6

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)

2 Answers2

7

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
Thomas Dickey
  • 76,765
4

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.

desgua
  • 61
cuonglm
  • 153,898
  • 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. – erikbstack Jul 31 '14 at 09:01
  • @erikb85: I don't understand what you mean. See here: http://en.wikipedia.org/wiki/Terminal_emulator for terminal emulator definition. – cuonglm Jul 31 '14 at 09: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. – erikbstack Jul 31 '14 at 09:20
  • 1
    If you don't use terminal emulator, this will not work. – cuonglm Jul 31 '14 at 09: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
  • @Gilles I open a socket in my python code, then read from and write to it. If there is no terminal emulator involved on the server side, then there is none. – erikbstack Aug 01 '14 at 06:42
  • @erikb85 If you're doing this from a Python program then you should post your code (a part of manageable size that reproduces the problem) on [so] (and close or flag for migration this question here). – Gilles 'SO- stop being evil' Aug 01 '14 at 07:34
  • @Gilles Well on stackoverflow they say it's a question for here. Instead of worrying about the moderation stuff let's worry about the content first, okay? – erikbstack Aug 01 '14 at 08:26
  • 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. Try to make that stop. Neither changing stty nor turning off the linewrap helps. – erikbstack Aug 01 '14 at 08:27
  • @erikb85 Doing this from a command line prompt may not behave in the same way as doing this from a program. Show us your code, and try with other devices or other programs on the device — it may be entirely the fault of this particular shell and we'd have no way to know. You need to give us more information if you want us to help, and knowing exactly what shell this is and its build options may be the key to solving the problem. – Gilles 'SO- stop being evil' Aug 01 '14 at 08:58
  • @erikb85 You should have told us from the start about your SO question. All we've done so far is reproduce DrV's analysis. In order to make progress, we need to know what's running on the device. For example, Android's mksh exhibits similar symptoms, but there stty columns 9999 does increase the line length limit. – Gilles 'SO- stop being evil' Aug 01 '14 at 09:01
  • you got the tput commands backward – Corey Goldberg Jan 19 '16 at 23:44