如何像使用SSH一样简单地连接到串行端口?


86

是否可以像使用SSH一样连接到串行终端?一定有比Minicom这样的工具更简单的方法,像这样

$ serial /dev/ttyS0 

我知道我可以从端口到控制台cat进行输出,/dev/ttyS0但是只有一种通信方式是可行的。和echo出端口是一样的,但周围的其他方式,来港。

如何在Unix / Linux上以最简单的方式实现与串行端口的双向通信?


2
很好的答案!!不幸的是,当使用带有少量命令的嵌入式系统时,似乎没有人完全符合我的目的。但是,我确实找到了另一种使用shell脚本的方法,该脚本是我对问题的回答之一。
ihateto2011年

Answers:


69

我找到screen了最有用的串行通信程序,因为无论如何我将其用于其他用途。screen /dev/ttyS0 <speed>尽管设备的默认设置可能有所不同,但通常只是。它还允许您通过进入命令模式并执行来将任何内容传送到会话中exec !! <run some program that generates output>


3
屏幕+1!另请参阅:serverfault.com/q/81544/11086
乔什(Josh)

1
另请参见noah.org/wiki/Screen_notes#using_screen_as_a_serial_terminal和手册页面stty(1),我必须添加其他选项(例如奇偶校验)才能使其正常工作。
Lekensteyn 2012年

3
感到
as

screen是真棒,但我不认为它比简单的minicom:-)
西罗桑蒂利新疆改造中心法轮功六四事件

1
@CiroSantilli刘晓波死六四事件法轮功-屏幕可能不比Minicom更简单,但是由于我已经使用了Screen,所以对我来说,使用Screen进行串行操作的复杂性较低,因此完全无需使用Minicom。
yeti

48

背景

需要任何程序minicom通过串行端口进行通信的主要原因是,在启动连接之前需要先设置端口。如果未正确设置,则catand echo命令将无法满足您的期望。请注意,一旦运行了类似的程序minicom,该端口将保留所使用的设置minicom。您可以使用以下stty程序查询通讯设置:

stty < /dev/ttyS0

如果做对了,在启动计算机之后,在运行任何其他程序之前,例如minicom,通信设置将恢复为默认设置。这些可能与您建立连接所需要的有所不同。在这种情况下,发送的命令catecho到端口要么产生垃圾或者不工作。

使用之后stty再次运行,您会注意到设置已设置为程序正在使用的设置。minicom

最少的串行通讯

基本上,通过串行端口进行双向通信需要做两件事:1)配置串行端口,以及2)打开伪tty读写。

我知道做的最基本的程序是picocom。您还可以使用类似的工具setserial来设置端口,然后直接从外壳与之交互。


5
picocom也可以让您连接到串行端口而无需重新配置它(--noinit),并且可以退出而无需恢复串行端口配置(--noreset或使用Ctrl-A/ Ctrl-Q退出picocom)。我发现picocom它比容易使用得多minicom。由于我尚未弄清的原因,minicom有时有时根本不会在以前工作正常的端口上发送或接收数据,或者picocom不会遇到任何麻烦。这可能是一些不可思议的配置选项,但是无论如何我都无法弄清楚(这种现象已经在多台机器上发生了)。
Michael Burr

picocom +1!我发现如果没有正确的行尾,我将无法向串行设备写入命令:我需要使用--omap crcrlf --echo选项
user2561747,

24

如果系统上安装了UUCP,则可以使用命令cu,例如

 $ cu -l /dev/ttyS0 -s 9600

使用~^D~.退出。
iman

24

我发现,使用shell脚本的方式在这里是把cat作为后台进程和while循环读取用户输入和echo它的端口。我对其进行了修改,使其更加通用,完全符合我的目的。

#!/bin/sh

# connect.sh

# Usage:
# $ connect.sh <device> <port speed>
# Example: connect.sh /dev/ttyS0 9600

# Set up device
stty -F $1 $2

# Let cat read the device $1 in the background
cat $1 &

# Capture PID of background process so it is possible to terminate it when done
bgPid=$!

# Read commands from user, send them to device $1
while read cmd
do
   echo "$cmd" 
done > $1

# Terminate background read process
kill $bgPid

1
另外,我在下面做了一个稍微修改的版本它也可以发送Ctrl + C和Ctrl + Z。
Fritz

@Fritz很好找到!因此,如果我做对了,后台进程将永远不会被杀死,因为$?似乎没有扩展到正确的地方吗?
ihatetoregister

1
@ihatetoregister:不太正确。后台进程被杀死,但不是出于人们可能期望的原因。$?扩展为最后一个非后台命令的退出代码(在这种情况下为stty -F $1 $2),因此当没有错误时,它将扩展为0。因此,最后一行变成kill 0反过来似乎杀死了当前的shell及其所有子级(我认为在交互式shell中,它的行为有所不同)。对于所有的详情,请参阅下面的解释:unix.stackexchange.com/questions/67532/...
弗里茨

1
但是,脚本中真正的陷阱在于,当您按Ctrl + D结束脚本时,后台进程才会被杀死,因为这样可以while干净地结束循环。如果使用Ctrl + C或kill命令将其杀死,则该cat过程将保持活动状态。要解决此问题,您需要使用trap命令kill $bgPid在shell退出时执行,就像下面的脚本一样。老实说,如果您只是将整个脚本添加到您的帖子中,我什至都不介意。我试图这样做,但是编辑被拒绝了。
Fritz

您能否澄清连接的位置,因为答案中已注释掉了该位置
克里斯·哈尔克罗

14

试试http://tio.github.io

“ tio”是一个简单的TTY终端应用程序,具有简单的命令行界面,可轻松连接到TTY设备以进行基本输入/输出。

典型用途是没有选项。例如:

tio /dev/ttyS0

对应于常用选项:

tio --baudrate 115200 --databits 8 --flow none --stopbits 1 --parity none /dev/ttyS0

它为所有选项提供完整的shell自动完成支持。


3
msys2在Windows上使用,因此可以安装tiopacman -S tio因为默认情况下它位于可用的软件包中。screenpicocom等等都没有。谢谢!
Kohányi罗伯特

12

该脚本基于另一个答案,但通过串行端口发送所有内容(Ctrl + Q除外),而不仅仅是单个命令,后跟Enter。这使您可以在远程主机上使用Ctrl + C或Ctrl + Z,并可以使用诸如aptitude或alsamixer之类的交互式“ GUI”程序。可以通过按Ctrl + Q退出。

#!/bin/bash

if [[ $# -lt 1 ]]; then
    echo "Usage:"
    echo "  femtocom <serial-port> [ <speed> [ <stty-options> ... ] ]"
    echo "  Example: $0 /dev/ttyS0 9600"
    echo "  Press Ctrl+Q to quit"
fi

# Exit when any command fails
set -e

# Save settings of current terminal to restore later
original_settings="$(stty -g)"

# Kill background process and restore terminal when this shell exits
trap 'set +e; kill "$bgPid"; stty "$original_settings"' EXIT

# Remove serial port from parameter list, so only stty settings remain
port="$1"; shift

# Set up serial port, append all remaining parameters from command line
stty -F "$port" raw -echo "$@"

# Set current terminal to pass through everything except Ctrl+Q
# * "quit undef susp undef" will disable Ctrl+\ and Ctrl+Z handling
# * "isig intr ^Q" will make Ctrl+Q send SIGINT to this script
stty raw -echo isig intr ^Q quit undef susp undef

# Let cat read the serial port to the screen in the background
# Capture PID of background process so it is possible to terminate it
cat "$port" & bgPid=$!

# Redirect all keyboard input to serial port
cat >"$port"

7

顺便说一句,腻子包(确实在Linux上运行)确实包含串行支持。


4

可能发生的另一个问题是,您的用户帐户可能需要设置为“ dialout”组才能访问串行端口。

sudo usermod -a -G dialout $USER

3

Putty在Linux上运行良好,并提供了一些便利,特别是对于串行通信。它有一个我无法直接解决的缺点:从Putty窗口本身没有复制粘贴。Windows版本有一个可爱的自动复制到剪贴板的高亮显示部分,右键单击以粘贴行为(并且有出色的chrome和firefox插件可以实现相同的行为),但是在Linux上,没有复制可以使用AFAIK。

如果缺少副本是一个问题(对我而言),请打开腻子登录并打开标准的终端窗口,# tail -f putty.log并且双向文本可用于标准的copypasta操作。


1
我发现Linux下的Putty不会粘贴“剪贴板”(使用control-C复制的内容),但是会在中间鼠标插入“主要选择”(您在某些程序中当前选择的内容)。同样,您可以在腻子的屏幕中选择字符以定义主要选择。但是,如果我希望将Putty屏幕中的文本传输到某些VM,则需要将其作为剪贴板,因此我必须使用中介程序从主要选择中接收文本,然后将其复制到剪贴板。
卡迪夫太空人


2

这取决于您想做什么。您是否要从终端交互运行外壳程序或应用程序,通过串行线连接到另一台计算机,通过串行口自动与设备通信?

如果您想进行双向通讯,那么我想您想在终端上与人互动。您可以通过在串行端口上设置getty(1)会话,将系统配置为允许从终端通过串行端口登录-getty是用于设置终端并允许登录到该终端的工具。将条目放入inittab(5)文件中,以在相应的串行端口上运行它respawn

如果要连接的设备,并启动自动双向对话,那么你可以看到,如果指望会得到你想要的东西。使用stty(1)将端口配置为正确的奇偶校验,波特率和其他相关设置。

如果要通过串行端口与另一台计算机进行交互通信,则需要终端仿真软件。这确实做了很多工作-它设置了端口,解释了ANSI或其他终端命令序列(ANSI远远不是串行终端所支持的唯一标准)。许多终端仿真器还支持文件传输协议,例如kermit或zmodem。

串行通信和终端I / O的来龙去脉非常复杂;您可以在串行howto中阅读到比该主题更多的知识


1

您可能想看看

http://serialconsole.sourceforge.net

优点:没有像minicom或picocom这样的明显的安全问题(如果您没有给用户提供外壳程序访问权限的问题,没问题,但是如果您要设置终端服务器,您很可能会遇到一个问题... )


1

您需要确保在设备上具有正确的读写许可,您可以通过以下方式查看它:

$ls -l /dev/[serial device]

我依靠您找到的脚本并进行了一些修改。

对于我到目前为止使用的开发系统,它们曾经需要:

  • 无平价和
  • 一站式

这些值是脚本中的默认值。

因此,为了进行连接,您可以像下面这样简单地使用它:

./connect.sh /dev/[serial device] [baud speed]

例:

$./connect.sh /dev/ttyUSB0 19200

脚本:

#!/bin/bash

# connect.sh


#Taken from example modified by: ihatetoregister
# On stack exchange, thread:
# http://unix.stackexchange.com/questions/22545/how-to-connect-to-a-serial-port-as-simple-as-using-ssh
# Modified by Rafael Karosuo <rafaelkarosuo@gmail.com>
#   - parity enabling and amount of stop bits
#   - no execution without minimum params
#   - exit code for stty
#   - bgPid fix, used $! instead of $? to take the PID of cat proc in background.
#   - exit command to end the program
#   - CR termination and strip of NL added by READ command, in order to make $cmd\r\n format instead of \n$cmd\n


# Usage:
# $./connect.sh <device> <port speed> [# Stop bits] [parity]

# Stop bits 1|2
# Parity even | odd

# If no last two params, then default values stopbits=1, parity=disab

# Example: 
# connect.sh /dev/ttyS0 9600 1 even, this will use 1 stop bit and even parity
# connect.sh /dev/ttyS0 9600, this will take default values for parity and stopbit


#Check if at least port and baud params provided
if [ -z "$1" ] || [ -z "$2" ]; then
    printf "\nusage: ./connect.sh <device> <port speed> [# Stop bits 1|2] [parity even|odd]\n\tNeed to provide at least port and baud speed parameters.\n\texample:connect.sh /dev/ttyS0 9600\n\n"
    exit 1;
else
    case "$3"   in
        2) stopb="cstopb";;
        *) stopb="-cstopb";;
    esac

    if [ "$4" = "even" ]; then
        par="-parodd"
    elif [ "$4" = "odd" ]; then
        par="parodd"
    else
        par="-parity"
    fi
    printf "\nThen stty -F $1 $2 $stopb $par\n";
fi

# Set up device
stty -F "$1" "$2" "$stopb" "$par" -icrnl

# Check if error ocurred
if [ "$?" -ne 0 ]; then
    printf "\n\nError ocurred, stty exited $?\n\n"
    exit 1;
fi

# Let cat read the device $1 in the background
cat -v "$1" &

# Capture PID of background process so it is possible to terminate it when done
bgPid="$!"

# Read commands from user, send them to device $1
while [ "$cmd" != "exit" ]
do
   read cmd
   echo -e "\x08$cmd\x0D" > "$1" #strip off the \n that read puts and adds \r for windows like LF

done

# Terminate background read process
kill "$bgPid"

PS:您需要知道哪种类型的换行正在使用您的接收器系统,因为这将确定在我需要LF之类的Windows的情况下如何发送命令,这意味着我需要发送

command\r

ASCII值:

  • LF:0Ah,换行符“ \ n”
  • CR:0Dh,carrige返回“ \ r”
  • BS:08小时,后退空格“ <-”

1
#!/bin/sh如果(1)  不是文件的第一行,则将被忽略。(2)认真吗?您1用来指定偶数奇偶校验并2指定奇数?(3)通常有一条“使用情况”或“帮助”消息来记录所有参数,而不仅仅是强制性参数。(4)你应该总是给你的shell变量引用(例如"$1""$2""$3""$4""$stopb""$par""$bgPid",甚至"$?""$!"),除非你有一个很好的理由不要了,你一定要知道自己在做什么。
斯科特


1

我不知道为什么没人提到ser2net

范例/etc/ser2net.conf

3000:telnet:600:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT
3001:telnet:600:/dev/ttyUSB1:115200 8DATABITS NONE 1STOPBIT
3002:telnet:600:/dev/ttyUSB2:115200 8DATABITS NONE 1STOPBIT
3003:telnet:600:/dev/ttyUSB3:115200 8DATABITS NONE 1STOPBIT

您可以轻松连接到串行端口:

telnet localhost 3000

或远程:

telnet <ip> 3000

甚至在路由器上设置端口转发并将其公开给Internet,以便您可以从任何地方连接到它(让我们跳过安全性问题,我在谈论灵活性)。


0

另一个简单的选择是通过带有-X标志的ssh访问计算机并运行诸如putty或gtkterm之类的程序。

所以:

$ ssh -X <user>@<machine_address>

$ sudo apt-get install gtkterm (if not installed already)

$ gtkterm

它应该在客户端PC上启动图形界面,从那里可以像访问主机一样访问串行端口。

免责声明:仅在ubuntu机器上尝试过此操作。我猜想它不能在没有图形界面的机器上使用。

从ssh手册中:

-X

启用X11转发。也可以在配置文件中按主机指定。X11转发应谨慎启用。能够绕过远程主机(针对用户的X授权数据库)上的文件权限的用户可以通过转发的连接访问本地X11显示。然后,攻击者可能能够执行诸如按键监视之类的活动。因此,默认情况下,X11转发受X11 SECURITY扩展限制。有关更多信息,请参考ssh -Y选项和ssh_config(5)中的ForwardX11Trusted指令。

-Y

启用受信任的X11转发。受信任的X11转发不受X11 SECURITY扩展控件的约束。

因此,-Y如果安全是一个问题,请使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.