Notes for talking to the VAX (and anything else on a serial line) from Linux.
Verified on picocom v3.1 and GNU Screen 5.0.1.
| Task | Command |
|---|---|
| Connect (simple) | picocom -b 9600 /dev/ttyS0 |
| Leave picocom | Ctrl-A then Ctrl-X |
| Connect (shareable, logged) | screen -dmS {session_name} -L -Logfile ~/session.log /dev/ttyS0 9600 |
| Join a screen session | screen -x {session_name} |
| Leave screen, keep it running | Ctrl-A then d |
| Kill a screen session | screen -S {session_name} -X quit |
| List screen sessions | screen -ls |
| Who is holding the port | fuser -v /dev/ttyS0 |
# The serial port is owned by a group, not by you:
ls -l /dev/ttyS0
Typically crw-rw—- root uucp. On Debian/Ubuntu the group is dialout.
# Check you are in that group:
id
# Add yourself if not (log out and back in afterwards):
sudo usermod -aG uucp $USER
If you get “Permission denied” opening the port, this is why. Do not reach for
sudo picocom — fix the group instead.
The simple choice. One terminal, one session, no multiplexing.
# Connect at 9600 baud:
picocom -b 9600 /dev/ttyS0
# Connect with explicit settings (8N1, no flow control):
picocom -b 9600 -d 8 -p 1 -y n -f n /dev/ttyS0
# Log the whole session to a file:
picocom -b 9600 --logfile session.log /dev/ttyS0
# Connect without taking an exclusive lock:
picocom -b 9600 --no-lock /dev/ttyS0
Every command is prefixed by Ctrl-A. Press Ctrl-A then the second key.
| Keys | Action |
|---|---|
Ctrl-A Ctrl-X | Exit, and reset the serial port |
Ctrl-A Ctrl-Q | Exit without resetting the port |
Ctrl-A Ctrl-H | Show this help |
Ctrl-A Ctrl-V | Show current port settings |
Ctrl-A Ctrl-C | Toggle local echo |
Ctrl-A Ctrl-B | Set baud rate (prompts) |
Ctrl-A Ctrl-U | Baud up |
Ctrl-A Ctrl-D | Baud down |
Ctrl-A Ctrl-F | Cycle flow control |
Ctrl-A Ctrl-Y | Cycle parity |
Ctrl-A Ctrl-I | Cycle data bits |
Ctrl-A Ctrl-J | Cycle stop bits |
Ctrl-A Ctrl-P | Pulse DTR (drop it 1 sec, raise it) |
Ctrl-A Ctrl-T | Toggle DTR |
Ctrl-A Ctrl-G | Toggle RTS |
Ctrl-A Ctrl-\ | Send BREAK |
Ctrl-A Ctrl-W | Write raw hex bytes |
Ctrl-A Ctrl-S | Send (upload) a file |
Ctrl-A Ctrl-R | Receive (download) a file |
# To send a literal Ctrl-A to the far end, press it twice:
Ctrl-A Ctrl-A
# Change the escape key if Ctrl-A clashes (here, to Ctrl-O):
picocom -b 9600 --escape o /dev/ttyS0
Use this instead of picocom when you want any of:
# Start a detached, logging session called “vax”:
screen -dmS vax -L -Logfile ~/vax.log /dev/ttyS0 9600
# Attach to it (multi-attach: others can be attached too):
screen -x vax
# Attach exclusively, detaching anyone else:
screen -r vax
# Detach and leave it running:
Ctrl-A d
# Kill it for good, without attaching:
screen -S vax -X quit
# Send a command into the session without attaching:
screen -S vax -X stuff "SHOW TIME^M"
# List sessions:
screen -ls
# Remove “(Dead ???)” entries left by crashed sessions:
screen -wipe
# 1. The log file is buffered — 10 seconds by default.
Reading ~/vax.log right after sending a command shows nothing, and it looks
like the command never ran. Turn buffering off:
screen -S vax -X logfile flush 0
Add it right after starting the session. Without it, anything scripted against the log will read stale data.
# 2. stuff expands shell-style variables.
This does not send what you think:
screen -S vax -X stuff "LYNX :== $DKA0:[LYNX293]LYNX.EXE^M"
$DKA0 is eaten and the VAX receives LYNX :== :[LYNX293]LYNX.EXE.
Escape every dollar sign:
screen -S vax -X stuff "LYNX :== \$DKA0:[LYNX293]LYNX.EXE^M"
This bites constantly on VMS, where $ is everywhere — SYS$LOGIN,
f$search, VMI$ROOT.
All prefixed by Ctrl-A.
| Keys | Action |
|---|---|
Ctrl-A d | Detach, leave session running |
Ctrl-A ? | Help / key list |
Ctrl-A [ | Scrollback mode (arrows/PgUp, q to leave) |
Ctrl-A H | Toggle logging on/off |
Ctrl-A a | Send a literal Ctrl-A to the far end |
Ctrl-A k | Kill this window (confirm with y) |
picocom is built with USE_FLOCK, so it takes an exclusive lock. While it
is running, nothing else can open the port — screen will simply fail.
# Find out what is holding it:
fuser -v /dev/ttyS0
lsof /dev/ttyS0
Output like this means picocom (PID 1996744) owns it:
USER PID ACCESS COMMAND /dev/ttyS0: josephk 1996744 F.... picocom
Quit that program before starting another. If it is a screen session you have
forgotten about, screen -ls will show it.
# Show current settings for the port:
stty -F /dev/ttyS0 -a
Look for speed 9600 baud, cs8, -parenb (no parity), -cstopb
(1 stop bit), -crtscts (no hardware flow control).
# Set them by hand:
stty -F /dev/ttyS0 9600 cs8 -parenb -cstopb -crtscts clocal
Normally unnecessary — picocom and screen set the line themselves.
Slow. At 9600 baud you get roughly 1 KB per second, so about 17 minutes per megabyte. Use the network if the machine has one.
# Paste a small text file into a VMS session (works with no extra tools): On the VMS side:
CREATE MYFILE.COM
Then paste the text, and finish with Ctrl-Z.
# ZMODEM (needs lrzsz installed on Linux):
sudo pacman -S lrzsz
Then in picocom, Ctrl-A Ctrl-S to send and Ctrl-A Ctrl-R to receive.
The far end needs matching ZMODEM software, which classic VMS does not have
by default.
# For binary files on VMS, use FTP over the network instead. Always set binary mode first, and repair the record attributes on arrival:
SET FILE/ATTRIBUTES=(RFM:FIX,MRS:512,LRL:512,RAT:NONE) FILE.EXE
| Symptom | Cause | Fix |
|---|---|---|
| Permission denied on the device | not in the uucp / dialout group | usermod -aG uucp $USER, then re-login |
| “Device or resource busy” | another program holds the port | fuser -v /dev/ttyS0, quit it |
| Connects, but nothing appears | far end has no output yet | press Enter to draw a prompt |
| Garbage characters | wrong baud rate | Ctrl-A Ctrl-U / Ctrl-A Ctrl-D to hunt for it |
| Everything doubled | local echo on and remote echo | Ctrl-A Ctrl-C to toggle local echo off |
| Enter does nothing on VMS | CR/LF mapping | try picocom –omap crlf |
| Screen log is empty or stale | 10-second flush buffer | screen -S vax -X logfile flush 0 |
$ vanishes from a stuff command | variable expansion | escape it as \$ |
| Session gone after closing terminal | used picocom, not screen | use screen for long jobs |
| picocom | screen | |
|---|---|---|
| Quick interactive session | yes | works |
| Survives closing the terminal | no | yes |
| Two people on one session | no | yes |
| Automatic logging | with –logfile | yes |
| Scriptable from outside | no | yes (-X stuff) |
| Change baud mid-session | yes | no |
| Send BREAK | yes | Ctrl-A Ctrl-B |
Rule of thumb: picocom to poke at something, screen for anything that must not die — a long build, an install, or a session you want a transcript of.