Output apt-get upgrade to text - bash

I've written a script for updating ubuntu packages and to email me however the output of the what's been upgrade and services restarted does not get emailed or produced. I've tried to run the update from the command line and output to a text file but still nothing gets written to the text file. Any ideas?
TEMP="/tmp/upgrade.txt"
MAIL_ADDR="user#example.com"
cat /dev/null > $TEMP
apt-get update && apt-get upgrade --assume-yes > $TEMP
mail -s "Upgrade for $HOSTNAME" $MAIL_ADDR < $TEMP
rm $TEMP

Just using '&>' redirect in your apt-get commands would fix this issue.
apt-get update &>$TEMP
apt-get upgrade --assume-yes &>> $TEMP

Related

When running my bash script for setting ssh tunneling, it stops half

The following is my bash script setting up ssh tunneling. However, it always stops when it get to the echo part. does anyone know why? My distro is ubuntu 20.
apt update && apt install -y wget && DEBIAN_FRONTEND=noninteractive apt-get install
openssh-server -y &&
mkdir -p ~/.ssh && cd $_ &&
echo "ssh-ed25519
AAAAC3NzaC1lZDI1NTE5AAAAII2AOiMJXSWr/yYuAkSur/QSfdwBbmK3hs4qzlMvOQxT dmml#Dmms-MBP"
>> authorized_keys
&& service ssh start
thanks.
My response would be better placed in a comment, but I can't get the formatting right, so I'll post it here. The problem is likely due to a formatting issue. Splitting the string that's passed to the echo command over multiple lines is especially problematic. Try re-formatting as shown below, noting the backslash (\) at the end of each line. There's likely a better way to accomplish the goal than stringing a large number of commands together. Also, resist the temptation to use "set -e" here. See comments for additional details.
apt update && \
apt install -y wget && \
DEBIAN_FRONTEND=noninteractive apt-get installopenssh-server -y && \
mkdir -p ~/.ssh && \
cd $_ && \
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII2AOiMJXSWr/yYuAkSur/QSfdwBbmK3hs4qzlMvOQxT dmml#Dmms-MBP" >> authorized_keys && \
service ssh start

apt-get install tzdata noninteractive

When I try to
apt-get install -y tzdata
the command line option for picking timezone shows up. I am trying to use this in a script to do some setup, how can I make the apt-get run without user input?
I know to reconfigure the tzdata I can do
echo "America/New_York" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
But when installing I need it to run fully even if it doesn't set the right timezone, I can always reconfigure it.
I tried
echo 5 | apt-get install -y tzdata
but it is not working as expected.
This is the script I used
(Updated Version with input from #elquimista from the comments)
#!/bin/bash
ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
dpkg-reconfigure --frontend noninteractive tzdata
Seems to work fine.
As one liner:
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
If someone wants to achieve it in Dockerfile, use as below.
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata
To avoid playing directly with symlinks and to run configuration only once, I suggest to use debconf-set-selections command:
echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections
echo 'tzdata tzdata/Zones/Europe select Paris' | debconf-set-selections
DEBIAN_FRONTEND="noninteractive" apt install -y tzdata
I have recently found the following solution in a Dockerfile building the Cingulata FHE library:
ln -snf /usr/share/zoneinfo/$(curl https://ipapi.co/timezone) /etc/localtime
It basically uses the API provided by ipapi.co to retrieve the timezone information. This automatically configures the timezone properly instead of skipping the dialog and using the default (UTC).
All credit for this should go to #PYA but the right order should be:
ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
export DEBIAN_FRONTEND=noninteractive
apt-get install -y tzdata
dpkg-reconfigure --frontend noninteractive tzdata
Here is how I did it:
echo 1 > input.txt
echo 1 >> input.txt
apt-get install -y tzdata < input.txt
ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
echo America/Los_Angeles > /etc/timezone
The first two echo statements create a text file that contains the selection numbers for the geographic area menu and the city/region menu. This file is then used to provide input to the apt-get install command. The tzdata package will be installed without asking for any user input. The timezone will be set to Africa/Abidjan as if you entered 1 and 1 in response to the prompts you would normally get. Then I change the timezone to what I want with the last two commands.
Instead of 1 and 1, you could use the actual numbers for the geographic area and city/region that you want, but it seems to me that those numbers could change.
here is what worked for me:
from ubuntu:bionic
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y tzdata
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
After reading the comments, I did two steps below to use the TZ environment variable:
Added the following to the Dockerfile
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && apt-get clean
Added the following to the docker CMD script:
if [ ! -z "${TZ}" ]; then
echo "${TZ}" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
fi
This worked for me and allowed me to set the time zone when starting the container.

Trying to add a char to the end of each line in a given file, how is it done?

I have a file which looks like that:
sudo apt-get install rar
sudo apt-get install gimp
sudo apt-get install gnome-tweak-tool
sudo apt-get install unity-tweak-tool
sudo apt-get install pidgin
I want to somehow add "-y" in the end of each line, how is it done?
Thanks
sed -i 's:$: -y:' YOURFILE
Will do it for you.
-i does the modification "in place", so no new file created (actully there's a tmp file)
s substitute
:delimiter
$ end of line
see the 3. point
-y replacement
Assuming you want to add -y (change it as you deem appropriate) at the end of each line, you can use sed by saying
$ cat file
sudo apt-get install rar
sudo apt-get install gimp
sudo apt-get install gnome-tweak-tool
sudo apt-get install unity-tweak-tool
sudo apt-get install pidgin
$ sed 's/$/ -y/' file
sudo apt-get install rar -y
sudo apt-get install gimp -y
sudo apt-get install gnome-tweak-tool -y
sudo apt-get install unity-tweak-tool -y
sudo apt-get install pidgin -y
This prints on standard out. If you wish to make in-place changes inside the file, you can use -i option of sed by saying
sed -i 's/$/ -y/' file
or redirect the output to another file by doing
sed 's/$/ -y/' file > newfile
If you are vi mode you can try
:%s/$/text_to_be_added/g and press "Enter"
If you are bash mode you can try
sed 's/$/text_to_be_added/g' filename

Script for Installing missing packages via dpkg-query

I've got a script working to echo out the packages missing in the command line but would like a option to add in control for install the missing applications. What would the best way go to doing this? apt-get install $tmp?
#!/bin/bash
echo "Checking server for missing packages..."
tmp=$(dpkg-query -W -f='${Package} ${Status} \n' apache2 openssh-server php5 \
php5-cli php5-xsl php5-imap php5-curl | grep "no package found")
if [[ $tmp =~ "no package found" ]]
then
echo "working"
apt-get install $tmp
else
echo "foo"
fi
I've tried to add a loop into it but not getting the output from $tmp
Thanks
apt-get won't complain if you name packages already installed on your system.
Given this fact, I wouldn't bother trying to filter out already installed packages and just use the following one-liner.
apt-get install apache2 openssh-server php5 php5-cli php5-xsl php5-imap php5-curl
You might want to add -qy switches to run quietly and without beeing asked any question.

Redirecting bash script to /dev/null not executing?

so I'm very new to bash and I was making an installer for build-essential and OpenSSL. The problem is that It always stops after the first exec line. Here's my code:
#!/bin/bash
echo "Installing build-essential"
exec sudo apt-get install build-essential > /dev/null 2>&1
echo "Finished installing build-essential"
echo ""
echo "Installing OpenSSL"
exec sudo apt-get install openssl > /dev/null 2>&1
echo "Finished installing OpenSSL"
echo ""
echo "Updates complete!"
And here's the output:
Installing build-essential
[sudo] password for matthew:
Please keep in mind that I just started a few hours ago. Sorry for the dump question.
exec never returns to the calling script. It replaces the current process with the command following exec. Just remove the exec altogether, and let apt-get run like any other command.
Note: there are uses of exec that do return to the calling script, such as those that only do I/O redirection.

Resources