【问题标题】:different ssh behavior from crond与 crond 不同的 ssh 行为
【发布时间】:2017-10-28 12:39:19
【问题描述】:

我已经在这个上拔了几个小时的头发了。我欢迎任何关于下一步的新想法。

目标是通过 SSH 登录到自定义应用程序 CLI,然后使用自定义 CLI 命令之一在远端设备上下拉调试 shell。在客户端,我使用 CentOS 最小并运行 ssh,如下所示:

工作案例:

[user@ashleys-xpvm ws]$ ssh -p8222 admin@192.168.56.20

admin@192.168.56.20's password:  
Welcome to CLI
admin connected from 172.29.33.108 using ssh on scm2 
TRAN39# debug-utils shell 
device@scm2:~$

ssh 客户端会话使用特定于应用程序的端口 8222 访问自定义 CLI。进入 CLI 后,我们使用“debug-utils shell”命令下拉到 bash shell。

此序列是使用 Python/pexpect 编写的,并且在从用户命令行启动脚本时运行良好。当脚本被移动到 crontab 以由 crond 自动运行时,问题就出现了。在后一种情况下,脚本以一种特殊的方式失败。

按照这篇文章的建议:How to simulate the environment cron executes a script with? 我在客户端机器上启动了一个新的 shell,它的环境变量与 cron 作业使用的相同,我能够手动重现自动 cron 作业正在运行的相同问题进入。

设置 cron 环境后,远端设备现在在我们发出命令以放入设备的 bash shell 时抛出以下错误:

sh-4.2$ ssh -p8222 admin@192.168.56.20

admin@192.168.56.20's password: 
Welcome to CLI
admin connected from 172.29.33.108 using ssh on scm2
TRAN39# debug-utils shell
error: failed to decode arguments
TRAN39# 

问题重现后,我设置了两个终端,一个带有工作环境变量,另一个带有失败的环境变量。我使用“-vvv”标志从两个终端运行 ssh,并比较了两者之间的调试输出。

这两个输出是相同的,除了它们逐步通过环境变量来确定要发送到发送 SSH 服务器的位置(显然),以及“位设置”行略有不同。我查看了环境变量行,我可以看到 ssh 忽略了所有这些行,除了 LANG,它在工作情况和失败情况下都是相同的。

我现在不知道为什么远端设备上的 ssh 服务器在这两个客户端环境设置之间的行为不同。

这里是工作环境:

[user@centos_vm ws]$ env
XDG_SESSION_ID=294
HOSTNAME=centos_vm
SELINUX_ROLE_REQUESTED=
TERM=xterm-256color
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.56.20 52795 22
SELINUX_USE_CURRENT_RANGE=
OLDPWD=/home/user
SSH_TTY=/dev/pts/4
USER=user
LS_COLORS=rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:
MAIL=/var/spool/mail/user
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin
PWD=/home/user/ws
LANG=en_US.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/home/user
LOGNAME=user
SSH_CONNECTION=192.168.56.20 52795 192.168.56.101 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/env
[user@centos_vm ws]$ 

...这里是失败的(即 cron)环境:

sh-4.2$ env
XDG_SESSION_ID=321
SHELL=/bin/sh
USER=user
PATH=/usr/bin:/bin
PWD=/home/user/ws
LANG=en_US.UTF-8
HOME=/home/user
SHLVL=2
LOGNAME=user
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/env
OLDPWD=/home/user
sh-4.2$ 

目前,我对 ssh 调试的了解已经不够深入,因此非常感谢任何有关下一步查看的指导。

【问题讨论】:

  • 不确定是否是您的问题,但我会在 cron 运行的脚本/程序中设置 PATH。
  • 我很确定我已经尝试过了,但我会再试一次并确认。
  • 正如我所想,这并没有什么不同。不过感谢您的建议。
  • @Denis -- 你可以尝试在 crontab 中设置TERM=xterm 吗?
  • @whjm Bingo!, cron 环境中的 TERM=xterm 成功了!非常感谢。

标签: linux bash ssh cron centos


【解决方案1】:

通常ssh 不指定命令(ssh user@host)会将本地主机上的TERM 的值传递给远程服务器。例如:

# TERM=foo ssh 127.0.0.1
bash-4.4# echo $TERM
foo
bash-4.4#

在 crontab 中,crond 默认不会设置 TERM var,所以在 ssh 登录后,TERM 将设置为 dumb(这不是完整的功能)。见例子:

# (unset TERM; ssh 127.0.0.1)
bash-4.4# echo $TERM
dumb
bash-4.4# clear
TERM environment variable not set.
bash-4.4#

在您的情况下,听起来远程应用程序需要功能更强大的TERM,因此在 crontab 中将其明确设置为TERM=xterm(将传递给远程服务器)将解决它。

注意 ssh 带有命令 (ssh user@host command...) 不会在远程服务器上分配 pty,因此不会传递本地 TERM。要强制创建 pty 并传递 var,我们必须使用 ssh -t。见例子:

# echo $TERM
dtterm
# ssh 127.0.0.1 'tty; echo $TERM'
not a tty
dumb
# ssh -t 127.0.0.1 'tty; echo $TERM'
/dev/pts/8
dtterm
#

Wikipedia 上发现哑终端

哑终端是那些可以解释有限数量的控制代码(CRLF 等)但没有能力处理执行功能的特殊转义序列的能力,例如如清除一行、清除屏幕或控制光标位置。在这种情况下,哑终端有时被称为玻璃电传打字机,因为它们本质上具有与机械电传打字机相同的有限功能。通过将环境变量 TERM 设置为 dumb,现代类 Unix 系统仍然支持这种类型的哑终端。智能终端也可以处理转义序列,特别是VT52VT100ANSI 转义序列。

【讨论】:

  • 感谢您的解决方案。将 TERM=term 传递给 crontab 调用,它就像一个魅力。
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 2010-10-10
  • 2015-06-06
  • 2021-04-07
  • 2011-04-14
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多