Category Archives: linux

The days of 80 columns in a terminal are long gone. With wide screens and tabbed terminal emulators, I now often have terminals which are up to 150 or more columns wide. This can cause problems for applications which assume an 80 column terminal or are initialised with 80 columns and then are not ‘told’ that the terminal is wider.

If you’re using a terminal emulator over serial, then you can run into some annoying problems. For example, using a utility called picocom to open a serial terminal to some other system, which then presents a console with bash. Even if the terminal you started with was 150 columns wide, Bash wraps lines at 80 characters, which is annoying if you’re navigating around in a deep filesystem hierarchy.

So, the solution:

Before you start your picocom session, resize your terminal to the preferred width.

You can use the tput command to show you how many columns you’ve got if you’re interested:

elesueur@simple ~$ tput cols
143

Open picocom to your target:

elesueur@simple:~$ picocom -b 115200 /dev/ttyUSB2
picocom v1.4

port is        : /dev/ttyUSB2
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
escape is      : C-a
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : ascii_xfr -s -v -l10
receive_cmd is : rz -vv

Terminal ready

Ubuntu 10.10 elesueur-panda ttyO2

elesueur-panda login:

Login, and type stty -a

elesueur@elesueur-panda:~$ stty -a
speed 115200 baud; rows 0; columns 0; line = 0;

elesueur@elesueur-panda:~$ tput cols
80

elesueur@elesueur-panda:~$ echo $COLUMNS
80

Notice that Bash thinks the terminal is only 80 columns wide.

We could use stty or setterm to set our terminal width:

elesueur@elesueur-panda:~$ stty cols 143
elesueur@elesueur-panda:~$ stty -a
speed 115200 baud; rows 0; columns 143; line = 0;

But we still have the same problem. Bash needs to know that the terminfo data has been updated, and this is done with a simple command:

elesueur@elesueur-panda:~$ resize
COLUMNS=143;
LINES=57;
export COLUMNS LINES;

An strace of resize shows that it firstly writes a string to /dev/tty to obtain the current window size, then does a TIOCSWINSZ ioctl on /dev/tty to set the current size of the terminal:


write(3, “\0337\33[r\33[999;999H\33[6n”, 19

read(3, “\33[57;143R”, 4096)            = 9

ioctl(3, TIOCGWINSZ, {ws_row=0, ws_col=0, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(3, TIOCSWINSZ, {ws_row=57, ws_col=143, ws_xpixel=0, ws_ypixel=0}) = 0
— SIGWINCH (Window changed) @ 0 (0) —

Then immediately after it does the TIOCSWINSZ, it sends a SIGWINCH to Bash, which tells Bash that the window size has changed.

You don’t actually need to manually set the width with stty, resize figures the details out for you.

I don’t know why Bash can’t figure out the correct width when first started. Never-the-less, resize works well, and you could stick it in your .bashrc.

I and many others I know run MacOS as their primary operating system. Much of the research I do involves Linux, and therefore I often use Linux in order to become friendly with it.

A good way to run Linux is inside a virtual machine, where it need not worry about power management which unfortunately it doesn’t handle well, and fortunately, MacOS does. Linux is getting better though. Anyway, Linux runs well inside VMware Fusion, and with plenty of memory, you don’t even really notice that it’s running in a VM.

Sharing files between the host and the Linux is a problem that is easily solved. VMware try to give you tools to do it, and they seem to work well with Windows. MacOS has an NFS server, Linux does NFS well. With a little hacking, you can get MacOS and Linux to share a common home directory, allowing for very easy, seamless, integrated file sharing between the two environments.

Warning, the procedure below can be harmful to your Ubuntu installation if you do something wrong.

Give MacOS an /etc/exports file with the following contents (typical):

/Users/<macosuser> -network 172.16.97.0 -mask 255.255.255.0

Start nfsd by typing:

$ sudo nfsd enable

Install Ubuntu inside Fusion in the normal way. Open a terminal, and give the root user a password:

$ sudo passwd

Log out of gnome, and get to a console by pressing fn + ctrl + option + F1, and login as root.

Edit /etc/passwd:

# vim /etc/passwd

Change the uid of your local user to that of your user on MacOS. You can find your MacOS uid by issuing the following command in Terminal:

$ ls -ln ~

It will probably be 501 or similar. Change the uid of the local user in Ubuntu (probably 1000) to 501. Do the same for your local group in /etc/group for Ubuntu.

You will also need to know the IP address of the VMware adapter on MacOS. Use $ ifconfig. It will probably be something like:

vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 00:50:56:c0:00:08
inet 172.16.97.1 netmask 0xffffff00 broadcast 172.16.97.255

You now have the option of putting this in /etc/hosts like:

<macos_hostname>.local 172.16.97.1

Which will allow you to refer to your MacOS as macos_hostname.local in the next section.

The next step is to mount the nfs shared home directory into /home/<ubuntuser>. Do this by editing /etc/fstab and adding a line at the bottom that looks like:

<macos_hostname>.local:/Users/<macosuser> /home/<ubuntuuser> nfs defaults 0 0

You should now be able to login to Ubuntu again by pressing fn + ctrl +option + F7 (maybe F8 on new Ubuntu’s), and have your MacOS home directory shared with your Ubuntu user and have full read/write permissions.

Yay.