由于 /etc/profile.d 中的脚本以退出状态 1 退出,因此无法使用 SSH 登录服务器

由于 /etc/profile.d 中的脚本以退出状态 1 退出,因此无法使用 SSH 登录服务器

所以我遇到了这个问题,我无法使用 SSH 登录我的服务器。看:

ssh -v myuser@myserver
debug1: Authentication succeeded (password).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
Last login: Sun Jul  5 20:10:54 2015 from x.x.x.x
-bash: KSH_VERSION: unbound variable
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype [email protected] reply 0
debug1: channel 0: free: client-session, nchannels 1
Connection to x.x.x.x closed.
Transferred: sent 2264, received 2800 bytes, in 0.2 seconds
Bytes per second: sent 13241.8, received 16376.8
debug1: Exit status 1

问题是“-bash:KSH_VERSION:未绑定变量”,我认为这会终止连接。我知道为什么会发生这种情况...我正在编写一个放在 /etc/profile.d 中的脚本,并且该脚本中有“set -euo pipelinefail”(哎呀)...“o”选项是“nounset”并且这解释了“未绑定变量”...当脚本设置选项时,它使 vim.sh 在未绑定变量上失败。

现在,如何解决这个问题?我无法通过 ssh 发送命令来删除文件,例如,我无法以另一个用户身份登录,我无法使用另一个 shell,“--noprofile”和“--norc”选项bash 不起作用……我尝试过的任何技巧都不起作用……

有什么想法吗?

答案1

我遇到了同样的问题,终于找到了解决方案。

正如@nkms 提到的:

在获取 /etc/profile 之前,您有大约 1/3 的机会(至少我有 1/3)中断(按 Ctrl+C)登录过程

为了增加你的机会,我使用了以下循环:

$ (trap '' INT; while true; do ssh myuser@myserver; done)

该脚本启动 subshel​​l '(' 并停用该子 shell 的 ctr-c 命令(使用 trap 命令)。然后它循环执行 ssh 命令。如果您连续按 ctrl-c 或按住 ctrl-c,则机会增加抓住正确的时机。

... 奇迹般有效!

答案2

在获取 /etc/profile 之前,您有大约 1/3 的机会(至少我有 1/3)中断(按 Ctrl+C)登录过程:

$ ssh -v localhost
OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
........
Authenticated to localhost ([::1]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
Last login: Tue Jul  7 19:46:42 2015 from localhost
^C-bash-4.2$ 

编辑以澄清一些事情:

当 sshd 在服务器上打开会话时,它通过读取用户 shell(在本例中为 /bin/bash)来实现。

bash 或 ssh 命令(包括 sftp)运行时给出的任何选项并不重要。该 ssh 命令(包括 sftp)或 bash 选项被传递到 bash 实例会话已打开。您无法控制该实例的行为。例如:

client$ ssh localhost bash --noprofile --norc

服务器上的 strace 输出:

[pid 60047] execve("/bin/bash", ["bash", "-c", "bash --noprofile --norc"], [/* 16 vars */]) = 0
[pid 60047] execve("/usr/bin/bash", ["bash", "--noprofile", "--norc"], [/* 28 vars */]) = 0

正如您所看到的,ssh 命令(“bash --noprofile --norc”)在第一个 execve 上作为参数传递给带有“-c”选项的“bash”。

您无法控制的第一个 bash 实例是 read ~/.bashrc ,它反过来会读取 /etc/bashrc ,它将加载 /etc/profile.d/ 下的脚本(至少在 Red Hat 系统上 - 我不这样做)不知道其他人)。

[pid 60047] open("/home/user/.bashrc", O_RDONLY) = 3
[pid 60047] open("/etc/bashrc", O_RDONLY) = 3

我能想到的唯一方法是上面的方法,在加载脚本之前足够快地中止登录过程(但不要快到中止会话)。 - 您可能希望增加系统负载(如果可能),以便在登录过程中为您提供更多时间。

附注如果您觉得答案有用请标记

答案3

sftp也失败了?如果没有,您可以利用它来放置一个好的 /etc/profile.d 文件在那里。

答案4

这不太可能起作用,但您可以尝试在建立 ssh 连接时发送 KSH_VERSION 值:

KSH_VERSION=x ssh -v -o 'SendEnv=KSH_VERSION' myuser@myserver

这个想法是将环境变量设置为某个值,这样 bash 就不会抱怨它未设置。我说它不太可能起作用,因为默认的 SSH 服务器配置不允许您设置这个特定的变量。仅当有人有理由在此特定服务器上使该设置更加宽松时,这才有效。

相关内容