简体   繁体   English

当脚本在 shell 的标准输入上时,apt-get 之后的 shell 脚本中的命令未正确执行

[英]Command in a shell script following apt-get not correctly executed when script is on shell's stdin

I have a script, simplified to below:我有一个脚本,简化如下:

echo Step one...
apt-get install -y --reinstall ca-certificates 
echo Step two...

For this use case, I cannot run it directly, it has to be piped to bash, like below:对于这个用例,我不能直接运行它,它必须通过管道传输到 bash,如下所示:

cat script.sh | bash

The problem is shown in the output below, where anything after the apt-get command (starting with the second echo statement) not even executed, but rather the echo command is displayed rather than executed问题显示在下面的 output 中,其中 apt-get 命令(从第二个 echo 语句开始)之后的任何内容都没有执行,而是显示而不是执行 echo 命令

How can I make this work?我怎样才能使这项工作?

# cat uu | bash
Step one...
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 509 not upgraded.
Need to get 0 B/166 kB of archives.
After this operation, 0 B of additional disk space will be used.
Preconfiguring packages ...

echo Step two...
(Reading database ... 131615 files and directories currently installed.)
Preparing to unpack .../ca-certificates_20170717~14.04.2_all.deb ...
Unpacking ca-certificates (20170717~14.04.2) over (20170717~14.04.2) ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Setting up ca-certificates (20170717~14.04.2) ...
Processing triggers for ca-certificates (20170717~14.04.2) ...
Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

Notice how echo Step two... is shown in output while apt-get is still executing, not run as a command after it finishes.请注意,当apt-get仍在执行时,在 output 中显示了echo Step two... ,而不是在完成后作为命令运行。

The problem here is that apt-get, or something it starts when reconfiguring this particular package, is consuming content you want only the bash interpreter itself to read.这里的问题是 apt-get,或者它在重新配置这个特定的 package 时启动的东西,正在消耗您只希望 bash 解释器本身读取的内容。

A narrow (command-by-command) approach is to redirect stdin of apt-get from /dev/null :一种狭窄的(逐个命令)方法是从/dev/null重定向 apt-get 的标准输入:

#!/usr/bin/env bash
echo Step one...
apt-get install -y --reinstall ca-certificates </dev/null
echo Step two...                              #^^^^^^^^^^

A more general approach is to encapsulate your code in a function, and call that function only at the end of the script:更通用的方法是将代码封装在 function 中,并仅在脚本末尾调用 function:

#!/usr/bin/env bash
main() {
  echo Step one...
  apt-get install -y --reinstall ca-certificates 
  echo Step two...
}
main

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM