我正在尝试在 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
两件事情:
执行此操作时,
in-target some_command > /some/path
重定向不会在目标内部发生。您需要执行以下操作:in-target --pass-stdout some_command > /target/some/path
该
in-target
命令会将命令的输出重定向到日志文件。因此,in-target
默认情况下尝试重定向输出不起作用。您需要做的是使用--pass-stdout
in-target 的参数
in-target --pass-stdout echo "hello" > /target/root/hello.txt
这将创建一个文件 /target/root/hello.txt,内容为“hello”
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,那就太好了,但我可能没有找对地方。
使用纯授权密钥路径的纯目标内回显:
in-target echo "my string" >> /home/username/.ssh/authorized_keys;
给出“目录未找到”
/var/log/installer/syslog
带有目标 authorized_keys 路径的普通目标内回显:
in-target echo "my string" >> /target/home/username/.ssh/authorized_keys;
在目标机器上生成一个空白的authorized_keys文件,查看时
/var/log/installer/syslog
你会发现“my string”输出到stdout
在目标中具有明确的
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 将其作为一个命令运行。