Linux – How to send keystrokes before interactive shell to automate Linux serial port login with GNU screen

expectgnu-screenlinuxserial port

I often have to login into Linux devboards with known fixed usernames and password via the serial port.

The normal commands are:

screen /dev/ttyS0 115200

and then inside screen the session looks like:

<enter>
somehost login: root<enter>
Password: root<enter>
user@host#

How to automate this login procedure so I don't have to type the username and password every time?

I can also use expect if needed. I've tried:

expect -c "spawn screen /dev/ttyS${1:-0} ${2:-115200}; send "\r"; expect \"* login: \"; send \"root\"; expect \"Password: \"; send \"root\"; interact"

but my expect skills don't quite cut it and this just hangs.

Also, if I logoug and login immediately, the second time it does not ask for the password and goes directly to the prompt:

user@host#

so hopefully the script should also take that into account. See also: https://stackoverflow.com/questions/9464887/modify-expect-based-ssh-script-to-work-on-machines-that-dont-require-a-password

Similar question for SSH: https://stackoverflow.com/questions/459182/using-expect-to-pass-a-password-to-ssh

Best Answer

You can help to debug expect by adding option -d. In your example you would see that you are doing "...send "\r"..." which is evaluated by the shell as ...send r... because \r is on its own outside the doublequotes. Try changing that to send \"\r\" as in the other cases. You also need to put a similar carriage-return at the end of each send: send \"root\r\".

It would cleaner to write a small shell script file, or use single quotes, converting to doublequotes for the ${1:-0} that need interpolating:

expect -c 'spawn screen /dev/ttyS'"${1:-0} ${2:-115200}"'; send \r; expect " login: ";...'

This complete script (without using the shell) also deals with the already logged in case:

#!/bin/expect --
set tty 0
set baud 115200
if { $argc >= 1 } {
 set tty [lindex $argv 0]
}
if { $argc >= 2 } {
 set baud [lindex $argv 1]
}
spawn screen /dev/ttyS$tty $baud
send \r
expect {
      "login: " {
           send root\r
           expect "Password: "
           send root\r
       }
       "#" 
    }
interact
Related Question