为 ubuntu 16.04 服务器调试 preseed/late_command:未找到 tee 和不存在目录

为 ubuntu 16.04 服务器调试 preseed/late_command:未找到 tee 和不存在目录

我正在尝试在 ubuntu 16.04 服务器机器上运行以下预置文件(在打包程序构建期间):

d-i preseed/late_command string \
in-target mkdir -v -p -m 0440 "/etc/sudoers.d"; \
in-target echo "%vagrant ALL=(ALL) NOPASSWD: ALL" | tee -a /etc/sudoers.d/vagrant; \
in-target echo "Defaults:vagrant !requiretty" | tee -a /etc/sudoers.d/vagrant; \
in-target chmod 440 /etc/sudoers.d/vagrant;

在 /var/log/installer/syslog 中我可以看到以下错误:

log-output: sh:
log-output: tee: not found

当我将“| tee -a”部分更改为“>>”时,如下所示:

d-i preseed/late_command string \
in-target mkdir -v -p -m 0440 "/etc/sudoers.d"; \
in-target echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant; \
in-target echo "Defaults:vagrant !requiretty" >> /etc/sudoers.d/vagrant; \
in-target chmod 440 /etc/sudoers.d/vagrant;

它突然开始抱怨找不到目录,而没有提及 mkdir 行 - 所以它既没有创建目录,也没有找到它:

log-output: sh: can't create /etc/sudoers.d/vagrant: nonexistent directory
log-output: sh: can't create /etc/sudoers.d/vagrant: nonexistent directory
log-output: chmod:
log-output: cannot access '/etc/sudoers.d/vagrant'
log-output: : No such file or directory

我一直在研究 github 上的其他脚本。我还在 preseed.cfg 文件中添加了以下行:

d-i pkgsel/include string openssh-server coreutils wget sudo

我甚至尝试将 coreutils 安装为目标命令,以确保 tee 可用。这已经持续了几天,一次又一次地重建 ubuntu,却发现系统日志中存在相同的错误。如果有人能解释一下——这肯定是件简单的事情,但我没有看到它……

答案1

两件事情:

  1. 执行此操作时,in-target some_command > /some/path重定向不会在目标内部发生。您需要执行以下操作:in-target --pass-stdout some_command > /target/some/path

  2. in-target命令会将命令的输出重定向到日志文件。因此,in-target默认情况下尝试重定向输出不起作用。您需要做的是使用--pass-stdoutin-target 的参数

in-target --pass-stdout echo "hello" > /target/root/hello.txt

这将创建一个文件 /target/root/hello.txt,内容为“hello”

从:https://salsa.debian.org/installer-team/debian-installer-utils/-/blob/3e67bc7987eb4a9cdff5fe8d1084e612fe7bb48f/README

in-target:在 /target 中运行指定的命令并返回其退出状态。debconf passthrough 前端用于在安装程序中使用 cdebconf 询问 debconf 问题。这对于运行 dpkg-reconfigure、debconf-apt-progress 和 taskel 等程序特别有用。log-output 实用程序用于记录任何输出;如果使用选项 --pass-stdout 调用 in-target,log-output 将遵守它。

答案2

echo使用似乎不起作用in-target。要解决此问题,请尝试以下操作(在 Ubuntu 18.04 中尝试过):

d-i preseed/late_command string \
    echo "some text" >> /target/path/to/file.ext ; \
    in-target [some-other-command-in-target]

笔记:

  • 不要in-target在行前使用
  • /target在真实路径之前使用
  • 在其他命令中,您大多可以in-target在行前使用

答案3

如果您更喜欢使用 debian 安装程序,那么在将 ssh 公钥添加到 authorized_keys 时,此方法对我在 17.10.1 服务器上有效。您必须确保事先创建 .ssh 目录。

d-i preseed/late_command string in-target /bin/sh -c 'echo "my string" >> /home/username/.ssh/authorized_keys';

我花了大约一天的时间调试这个问题,并尝试了以下方法,得到了各种结果。如果有更详细的文档说明在 Debian 安装程序中针对各种非/“目标内”指令使用哪个 shell,那就太好了,但我可能没有找对地方。

  1. 使用纯授权密钥路径的纯目标内回显:

    in-target echo "my string" >> /home/username/.ssh/authorized_keys;
    

    给出“目录未找到”/var/log/installer/syslog

  2. 带有目标 authorized_keys 路径的普通目标内回显:

    in-target echo "my string" >> /target/home/username/.ssh/authorized_keys;
    

    在目标机器上生成一个空白的authorized_keys文件,查看时/var/log/installer/syslog你会发现“my string”输出到stdout

  3. 在目标中具有明确的sh -c...和目标 authorized_keys 路径:

    in-target /bin/sh -c 'echo "my string" >> /target/home/username/.ssh/authorized_keys';
    

    产生“目录未找到”错误/var/log/installer/syslog

希望这可以节省一些时间和调试!

答案4

echo 将在目标指令内工作。您必须将其放在反引号 (`) 中。例如,我想从预置文件更新我的机器的主机名:

目标主机名echo "ubn"$(lshw | grep -m 1 serial | awk '{print tolower ($2)}')

反引号告诉 shell 将其作为一个命令运行。

相关内容