Home > Software design >  Command in a shell script following apt-get not correctly executed when script is on shell's st
Command in a shell script following apt-get not correctly executed when script is on shell's st

Time:11-22

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:

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

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.

CodePudding user response:

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.

A narrow (command-by-command) approach is to redirect stdin of apt-get from /dev/null:

#!/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:

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