如何回答所有交互式对话和非对话问题

如何回答所有交互式对话和非对话问题

我想从 node js 代码在 ubuntu 18.04 上运行此命令,因此我无法回答提示,我应该调用它一次

sudo apt-get install --install-recommends linux-generic-hwe-18.04

我用下面的技巧做到了

printf'\n'| sudo apt-get install --install-recommends linux-generic-hwe-18.04

但随后我收到一个对话框询问,选择了第二个选项,但我的答案是第一个选项,又称“安装软件包维护者的版本”,下面的技巧对它不起作用

┌─────────────────────────────────┤  ├─────────────────────────────────┐
│ A new version of /boot/grub/menu.lst is available, but the version   │
│ installed currently has been locally modified.                       │
│                                                                      │
│ What would you like to do about menu.lst?                            │
│                                                                      │
│     install the package maintainer's version                         │
│     keep the local version currently installed                       │
│     show the differences between the versions                        │
│     show a side-by-side difference between the versions              │
│     show a 3-way difference between available versions               │
│     do a 3-way merge between available versions (experimental)       │
│     start a new shell to examine the situation                       │
│                                                                      │
│                                                                      │
│                                <Ok>                                  │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

以下均不起作用

printf'\n1\n'| sudo apt-get install --install-recommends linux-generic-hwe-18.04 printf'\n\n'| sudo apt-get install --install-recommends linux-generic-hwe-18.04

我也尝试过很多方法,比如下面这些,但都没有用

sudo DEBIAN_FRONTEND=非交互式 apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade

我经常遇到这类问题,例如关于 libssl 的问题,请告诉我如何回答这类问题?我想首先回答所有问题,然后运行命令

答案1

Dpkg 实际上确实提供了一种自动回答对话框问题的方法,并且在预先安装时非常流行(主要是 ubuntu 服务器,尽管新的安装程序不支持),因为这样的安装程序往往有大量的菜单和菜单选项。

什么是 debconf 文件?


A德布康夫(Debian 配置)文件,也称为种子文件,是一个列出安装程序所询问的参数和问题(逐字逐句,原样)以及我们对这些问题的回答的文件。如果问题缺失或答案不受支持 - 将选择默认值(如果可能)。

每个包都有一个配置列表,即使在安装过程中没有询问任何问题并使用默认值。重新安装包且未指定任何新配置时,将使用机器已知的配置。 笔记:debconf 文件实际上并不配置软件包,它们只是保存了安装程序使用的一组问题和答案值。

我们如何查看或创建包 debconf 选择?


  • 要列出对每个已安装包所做的所有选择,只需使用debconf-get-selections
  • 要列出特定的包,请使用debconf-get-selections |grep '<my_package_name>'
  • 要将现有答案的值更改为其他值或从命令行添加新的选择,请使用debconf-set-selections '<my_package_selection_stanza>'
  • 要更改或添加文件中的值,请使用debconf-set-selections '<my_file_location>'

请参阅手册页以获取更多信息:debconf-获取选择(1)debconf-设置选择(1)

通常很难得出正确的完整选择列表,一个很好的方法是先安装一个包,将其选择转储到文件中,编辑相关选择并从文件中设置新选择。 您也可以将字符串或文件内容传递给 set 命令:

echo "some selection" |debconf-set-selections

理解 debconf 语法:


下面是两个包 debconf 选择的示例,一个用于 lightdm(一个 ubuntu 显示管理器),还有几个来自 grub 选择的节:

$debconf-get-selections |grep lightdm
lightdm shared/default-x-display-manager   select   lightdm
lightdm lightdm/daemon_name   string   /usr/sbin/lightdm

$debconf-get-selections |grep grub-pc
grub-pc grub-pc/chainload_from_menu.list boolean true
grub-pc grub-pc/timeout string 10
grub-pc grub-pc/install_devices multiselect

我们可以看到,语法非常直观:第一部分是包名称,后面跟着一个“/”和一个问题/配置名称。之后是回答方法和答案。

注入 debconf 选择和包重新配置


debconf-set-selections命令更新了存储在操作系统中的 debconf 数据库。可以在安装新软件包之前设置选择列表,然后使用这些选择列表。对于已安装的软件包,无需清除。dpkg-reconfigure '<my_package_name>'应用新选择后即可轻松使用。

您还可以定义一个 debconf 级别,只允许出现并由您回答一些问题/确认提示,或者定义应询问非关键问题:

dpkg-reconfigure -p '<level>' '<my_package_name>'

可用级别为:低、中、高或关键。有关 debconf 的更多信息,请访问:debianwiki/debconf。如果您希望完全禁用任何对话框(仅当您的选择完全符合您的预期时才建议使用),请使用非交互式选项:dpkg-reconfigure --frontend Noninteractive '<package_name>'

答案2

如果您想以编程方式回答交互式程序的提示,则应使用expect。安装expect包并编写一个脚本来运行您的程序并回答提示。脚本的总体布局如下:

#!/usr/bin/expect

spawn <command_to_run>
expect <something_that_should_appear_on_screen>
send <keys_that_should_be_sent_to_program>
expect <something_that_should_appear_on_screen>
send <keys_that_should_be_sent_to_program>
expect <something_that_should_appear_on_screen>
send <keys_that_should_be_sent_to_program>
...
expect <something_that_should_appear_at_the_very_end>
exit

正确使用 expect 需要一些练习,但是一旦你习惯了它,它就是一个非常有用的工具。

相关内容