为什么必须设置 TERM=xterm 才能使我的脚本在远程执行时正常工作?

为什么必须设置 TERM=xterm 才能使我的脚本在远程执行时正常工作?

我正在尝试自动安装 Debian 服务器(debian 6.0 squeeze 64bit)。

部分安装需要安装 Sun JRE 包。

此软件包有许可协议,必须接受。我有一个脚本,使用以下几行来接受并安装 JRE:

echo "sun-java6-bin shared/accepted-sun-dlj-v1-1 boolean true" | debconf-set-selections
apt-get install -y sun-java6-jre

在本地执行脚本时,此方法很好。但是,我需要使用 ssh 命令远程执行脚本,例如:

ssh -i keyFile root@hostname './myScript'

这不管用。

具体来说,它在 上失败了apt-get install -y sun-java6-jre。似乎尽管我将许可协议设置为已接受,但当以这种方式远程运行时,它会被忽略。

尽管将值设置为true,但当我运行此命令时,系统仍会提示我手动接受协议:

ssh -i keyFile root@hostname 'apt-get install -y sun-java6-jre'

我怀疑这与运行适当的终端会话时所处理的环境有关,但不知道下一步该尝试什么来修复它。

編輯 0env:我比较了通过远程执行和通过本地终端会话执行的输出ssh。输出之间的唯一区别是本地终端会话具有附加值TERM=xterm

编辑1TERM在调用我的脚本时设置环境变量,就像这样ssh -i keyFile root@hostname 'export TERM=xterm; ./myScript',会产生正确的行为,但这实际上只是答案的一半,因为我不知道为什么您需要设置它。对于能够最好地解释原因的人来说,这是一个可接受的答案!

(我也修改了问题标题,从“Sun/Oracle JRE 的远程脚本安装“ 到 ”为什么必须设置 TERM=xterm 才能使我的脚本在远程执行时正常工作?“因为这是一个更准确的问题)

答案1

sun-java6-jre 软件包包含通过(也称为 debconf 前端的“shell 脚本”接口)preinst提示许可协议的脚本。debconf 的实现很难理解,但我猜想实现会检查环境变量并尝试为不同的终端实现不同的许可协议提示。请参阅 debconf 教程/usr/share/debconf/confmoduledb_input()TERMhttp://www.fifi.org/doc/debconf-doc/tutorial.html. 这个想法是,如果最终用户视力受损,debconf 前端可能最终会使用盲文显示器,而 preinst 脚本就可以正常工作。

据我所知,您不应该将脚本输出传递给交互式 debconf 前端。它供人类使用,并且可能随时发生变化(根据环境变量、月相等)。您可能需要谷歌搜索debconf frontend noninteractive

答案2

它不是布尔值选择

您可以验证 debconf 数据库的内容:

root@workstation:~# debconf-show sun-java6-jre
* shared/accepted-sun-dlj-v1-1: true
  sun-java6-jre/stopthread: true
  sun-java6-jre/jcepolicy:
  shared/error-sun-dlj-v1-1:
* shared/present-sun-dlj-v1-1:
root@workstation:~# 

正如您所看到的,在我的计算机上它已设置为 true,因为我在安装期间手动接受了它。如果我再次安装 sun-java6-jre,它不会提示我接受许可证。

我们将其设置为 false :

root@workstation:~# echo sun-java6-jre shared/accepted-sun-dlj-v1-1 select false | /usr/bin/debconf-set-selections

现在我们来检查一下:

root@workstation:~# debconf-show sun-java6-jre
* shared/accepted-sun-dlj-v1-1: false
  sun-java6-jre/stopthread: true
  sun-java6-jre/jcepolicy:
  shared/error-sun-dlj-v1-1:
* shared/present-sun-dlj-v1-1:
root@workstation:~# 

因此尝试:

ssh -i keyFile root@hostname "echo sun-java6-jre shared/accepted-sun-dlj-v1-1 select true | /usr/bin/debconf-set-selections && apt-get install -y sun-java6-jre"

使用 debconf-show 命令进行故障排除。

我怀疑你说

在本地执行脚本时,此方法可以正常工作。

这是因为您在某个时候手动安装了 sun-java6-jre。

答案3

由于问题已经改变,这里是另一个答案。

TERM 变量作为 sun-java5-jre 的一部分进行检查预安装脚本(参见这里)。此脚本中的 /usr/share/debconf/confmodule 用于与 deconf 数据库交互,并检查数据库中是否已将许可证设置为已接受。如果没有,它将调用 debconf 方法向您显示许可证。Debconf 将以适合您环境的方式显示它。这就是 TERM 的作用所在。如果您没有 TERM,它应该会切换到其他方法

以下是在 debconf 中将许可证设置为 false(不接受)的示例

Preparing to replace sun-java6-jre 6.26-1~lffl~oneiric~ppa (using .../sun-java6-jre_6.26-1~lffl~oneiric~ppa_all.deb) ...
debconf: Unable to initialise frontend: Dialog
debconf: (TERM is not set so the dialogue frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: Unable to initialise frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Configuring sun-java6-jre
-------------------------

Operating System Distributor License for Java v1.1 (DLJ)

Operating System Distributor License for Java version 1.1 (DLJ)

SUN MICROSYSTEMS, INC. ("SUN") IS WILLING TO LICENSE THE JAVA PLATFORM STANDARD
EDITION DEVELOPER KIT ("JDK" - THE "SOFTWARE") TO YOU ONLY UPON THE CONDITION
THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS LICENSE AGREEMENT (THE
"AGREEMENT").  PLEASE READ THE AGREEMENT CAREFULLY.  BY INSTALLING, USING, OR
DISTRIBUTING THIS SOFTWARE, YOU ACCEPT ALL OF THE TERMS OF THE AGREEMENT. 



...................................... CUT .................................
    DLJ v1.1                                                  27APR2006ANS

In order to install this package, you must accept the license terms, the
"Operating System Distributor License for Java" (DLJ), v1.1. Not accepting will
cancel the installation.

Do you accept the DLJ license terms? yes

下面是许可证已获批准的示例(在 deconf 中设置为 true)

 root@workstation:/home/andrey/buildarea# ssh root@localhost "echo 'sun-java6-bin shared/accepted-sun-dlj-v1-1 boolean true' | debconf-set-selections && aptitude -y reinstall sun-java6-jre"
root@localhost's password:
Reading package lists...
Building dependency tree...
Reading state information...
Reading extended state information...
Initialising package states...
Writing extended state information...
The following packages will be REINSTALLED:
  sun-java6-jre
0 packages upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 168 not upgraded.
Need to get 0 B/6,381 kB of archives. After unpacking 0 B will be used.
Writing extended state information...
debconf: Unable to initialise frontend: Dialog
debconf: (TERM is not set so the dialogue frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: Unable to initialise frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: Unable to re-open stdin:
(Reading database ... 161723 files and directories currently installed.)
Preparing to replace sun-java6-jre 6.26-1~lffl~oneiric~ppa (using .../sun-java6-jre_6.26-1~lffl~oneiric~ppa_all.deb) ...
debconf: Unable to initialise frontend: Dialog
debconf: (TERM is not set so the dialogue frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: Unable to initialise frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
sun-dlj-v1-1 license has already been accepted
Unpacking replacement sun-java6-jre ...
Processing triggers for shared-mime-info ...
Setting up sun-java6-jre (6.26-1~lffl~oneiric~ppa) ...
Reading package lists...
Building dependency tree...
Reading state information...
Reading extended state information...
Initialising package states...
Writing extended state information...
root@workstation:/home/andrey/buildarea# 

安装过程中是否收到相同的“debconf”消息?您可以查看我的实验以及通过 SSH 成功安装 sun-java6-jre这里注意:运行 ssh root@localhost“env”时,我也看不到 TERM 变量。

如果你想查看 deb 包在安装前、安装中、安装后做了什么,请下载 .deb 文件:

aptitude download sun-java6-jre

提取 .deb

ar x sun-java6-jre......deb

解压 control.tar.gz 并查看 preinstal 和其他文件。data.tar.gz 是包的内容。

这可能无法直接回答您的问题但希望能够有所帮助。

相关内容