Boot to shell with Ubuntu MATE 15.04 on Raspberry PI 2 - shell

Is it possible to boot to the terminal? I've tried to look for a grub file but I could not find it. Also /boot/firmware/config.txt does not seem to have such option.

Thanks to Rohith Madhavan and AceFace on Ubuntu-mate bitbucket issues:
You can boot to shell using the following commands:
systemctl set-default multi-user.target --force
systemctl disable lightdm.service --force
systemctl disable graphical.target --force
systemctl disable plymouth.service --force
Replace disable with enable to boot with GUI again.

The proposed solution doesn't work on Ubuntu MATE 16.04 and the "Welcome" application mentions a non-existent "graphical" command. The following worked for me :
#!/bin/bash
if [[ "$1" == 'enable' || "$1" == 'disable' ]]; then
if [ "$1" == 'disable' ]; then
systemctl set-default multi-user.target --force
fi
systemctl $1 lightdm.service --force
systemctl $1 graphical.target --force
systemctl $1 plymouth.service --force
if [ "$1" == 'enable' ]; then
if [ ! -h /etc/systemd/system/display-manager.service ]; then
ln -s /lib/systemd/system/lightdm.service /etc/systemd/system/display-manager.service
fi
systemctl set-default graphical.target --force
fi
else
echo 'Enables or disables GUI at boot.'
echo "Usage : $(basename) {enable | disable}"
fi

Related

Bash script: Installs Docker, Skaffold, Minikube, and kubectl on a Linux system

sims installation process is ok, but when i'm starting minikube i'm getting error:
Exiting due to DRV_NOT_HEALTHY: Found driver(s) but none were healthy. See above for suggestions how to fix installed drivers.
and then when i'm manually running command that i already have in script:
sudo usermod -aG docker $USER && newgrp docker
minikube starts...
any suggestions? here is whole script:
#!/bin/bash
function run_command {
local cmd="$1"
local spinner_text="$2"
echo -n "$spinner_text"
{
eval "$cmd" &>/dev/null
} &
local spinner=$!
local spin='-\|/'
local i=0
while kill -0 $spinner 2>/dev/null
do
i=$(( (i+1) %4 ))
printf "\r$spinner_text ${spin:$i:1}"
sleep .1
done
wait $spinner
local exit_code=$?
if [[ $exit_code != 0 ]]; then
echo "Error: $cmd failed with exit code $exit_code."
exit $exit_code
fi
echo "Done."
}
# Update package lists
run_command "apt-get update" "Updating package lists... "
# Install Docker
run_command "apt-get install -y docker.io" "Installing Docker... "
# Install Skaffold
run_command "curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && chmod +x skaffold && sudo mv skaffold /usr/local/bin" "Installing Skaffold... "
# Install Minikube
run_command "curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin" "Installing Minikube... "
# Install kubectl
run_command "curl -LO https://storage.googleapis.com/kubernetes-release/release/\`curl -L https://storage.googleapis.com/kubernetes-release/release/stable.txt\`/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/" "Installing kubectl... "
# Add the current user to the Docker group
run_command "sudo usermod -aG docker $USER && newgrp docker" "Adding user to Docker group... "
# Add virtual host to /etc/hosts
run_command "echo '192.168.49.2 hcms.dev' | sudo tee -a /etc/hosts" "Adding virtual host to /etc/hosts... "
echo "Installation complete."

Bash Script with Several Nested elif Statements Not Working

I am trying to create a script I can provide to those who will use an academic game I am making. I am trying to do the following:
Verify that Apache2 is installed and Running
If Apache2 is installed, move a folder containing the website files to /var/www/html while backing up apache's original index.html
The code is as follows:
#!/bin/sh
acm=[]
cnn=[]
gnu=[]
ieee=[]
if [pgrep -x "apache2" > /dev/null]; then
echo "Apache 2 Installed and Running!"
if [ -d "$HOME/acmDL" ]; then
sudo mkdir /var/www/bak
sudo mv /var/www/html/index.html /var/www/bak
sudo mv acmDL /var/www/html/
cd /var/www/html/
sudo mv acmDL/* .
exit
elif [ -d "$HOME/cnnDL" ]; then
sudo mkdir /var/www/bak
sudo mv /var/www/html/index.html /var/www/bak
sudo mv cnnDL /var/www/html/
cd /var/www/html/
sudo mv cnnDL/* .
exit
elif [ -d "$HOME/gnuDL" ]; then
sudo mkdir /var/www/bak
sudo mv /var/www/html/index.html /var/www/bak
sudo mv gnuDL /var/www/html/
cd /var/www/html/
sudo mv gnuDL/* .
exit
elif [ -d "$HOME/ieeeDL" ]; then
sudo mkdir /var/www/bak
sudo mv /var/www/html/index.html /var/www/bak
sudo mv ieeeDL /var/www/html/
cd /var/www/html/
sudo mv ieeeDL/* .
exit
else
echo "Provided websites not found... Are you using a custom website?"
fi
else
echo "Please check apache2... It may not have installed correctly"
fi
The error I keep getting is syntax error near unexpected token `elif' on line 15.
As you can see, I even tried moving the boolean expression [ - d "$HOME/site" ] to their own variables, but then the error becomes : -d: command not found and the error on line 15.
Is what I am trying to do impossible, or am I missing something undocumented and yet completely obvious (like a handful of my previous posts)?
This is being run on a minimal installation of Ubuntu 18 on a Virtual Machine. The site directories are shared by Filezilla. Script written in Notepad++ on Windows 7 x64.
First of all, can you rewrite it like this?
Please tell me the execution result.
This is wrong.
if [pgrep -x "apache2" > /dev/null]; then
This is correct.
pgrep -x "apache2" > /dev/null
if [ $? -eq 0 ]; then

What is the proper way to script a new nginx instance with SSL on a new Ubuntu 16.04 server?

I have this so far but I'm missing a couple of things like getting the cron job scripted. Don't want to do this as root. So I'm assuming some more could be done to set up the first user at the same time. The script would need to be idempotent (can be run over and over again without risking changing anything if it was run with the same arguments before).
singledomaincertnginx.sh:
#!/bin/bash
if [ -z "$3" ]; then
echo use is "singledomaincertnginx.sh <server-ssh-address> <ssl-admin-email> <ssl-domain>"
echo example: "singledomaincertnginx.sh user#mydomain.com admin#mydomain.com some-sub-domain.mydomain.com"
exit
fi
ssh $1 "cat > ~/wks" << 'EOF'
#!/bin/bash
echo email: $1
echo domain: $2
sudo add-apt-repository -y ppa:certbot/certbot
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y software-properties-common
sudo apt-get install -y python-certbot-nginx
sudo apt-get install -y nginx
sudo sed -i "s/server_name .*;/server_name $2;/" /etc/nginx/sites-available/default
sudo systemctl restart nginx.service
if [[ -e /etc/letsencrypt/live/$2/fullchain.pem ]]; then
sudo certbot -n --nginx --agree-tos -m "$1" -d "$2"
fi
if [[ ! sudo crontab -l | grep certbot ]]; then
# todo: add cron job to renew: 15 3 * * * /usr/bin/certbot renew --quiet
EOF
ssh $1 "chmod +x ~/wks"
ssh -t $1 "bash -x -e ~/wks $2 $3"
I have this so far but I'm missing a couple of things like getting the cron job scripted.
Here's one way to complete (and correct) what you started:
if ! sudo crontab -l | grep certbot; then
echo "15 3 * * * /usr/bin/certbot renew --quiet" | sudo tee -a /var/spool/cron/crontabs/root >/dev/null
fi
Here's another way I prefer because it doesn't need to know the path of the crontabs:
if ! sudo crontab -l | grep certbot; then
sudo crontab -l | { cat; echo "15 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab -
fi
Something I see missing is how the certificate file /etc/letsencrypt/live/$domain/fullchain.pem gets created.
Do you provide that by other means,
or do you need help with that part?
Don't want to do this as root.
Most of the steps involve running apt-get,
and for that you already require root.
Perhaps you meant that you don't want to do the renewals using root.
Some services operate as a dedicated user instead of root,
but looking through the documentation of certbot I haven't seen anything like that.
So it seems a common practice to do the renewals with root,
so adding the renewal command to root's crontab seems fine to me.
I would improve a couple of things in the script to make it more robust:
The positional parameters $1, $2 and so on scattered around are easy to lose track of, which could lead to errors. I would give them proper names.
The command line argument validation if [ -z "$3" ] is weak, I would make that more strict as if [ $# != 3 ].
Once the remote script is generated, you call it with bash -e, which is good for safeguarding. But if the script is called by something else without -e, the safeguard won't be there. It would be better to build that safeguard into the script itself with set -e. I would go further and use set -euo pipefail which is even more strict. And I would put that in the outer script too.
Most of the commands in the remote script require sudo. For one thing that's tedious to write. For another, if one command ends up taking a long time such that the sudo session expires, you may have to reenter the root password a second time, which will be annoying, especially if you stepped out for a coffee break. It would be better to require to always run as root, by adding a check on the uid of the executing user.
Since you run the remote script with bash -x ~/wks ... instead of just ~/wks, there's no need to make it executable with chmod, so that step can be dropped.
Putting the above together (and then some), I would write like this:
#!/bin/bash
set -euo pipefail
if [ $# != 3 ]; then
echo "Usage: $0 <server-ssh-address> <ssl-admin-email> <ssl-domain>"
echo "Example: singledomaincertnginx.sh user#mydomain.com admin#mydomain.com some-sub-domain.mydomain.com"
exit 1
fi
remote=$1
email=$2
domain=$3
remote_script_path=./wks
ssh $remote "cat > $remote_script_path" << 'EOF'
#!/bin/bash
set -euo pipefail
if [[ "$(id -u)" != 0 ]]; then
echo "This script must be run as root. (sudo $0)"
exit 1
fi
email=$1
domain=$2
echo email: $email
echo domain: $domain
add-apt-repository -y ppa:certbot/certbot
apt-get update
apt-get upgrade -y
apt-get install -y software-properties-common
apt-get install -y python-certbot-nginx
apt-get install -y nginx
sed -i "s/server_name .*;/server_name $domain;/" /etc/nginx/sites-available/default
systemctl restart nginx.service
#service nginx restart
if [[ -e /etc/letsencrypt/live/$domain/fullchain.pem ]]; then
certbot -n --nginx --agree-tos -m $email -d $domain
fi
if ! crontab -l | grep -q certbot; then
crontab -l | {
cat
echo
echo "15 3 * * * /usr/bin/certbot renew --quiet"
echo
} | crontab -
fi
EOF
ssh -t $remote "sudo bash -x $remote_script_path $email $domain"
Are you looking for something like this:
if [[ "$(grep '/usr/bin/certbot' /var/spool/cron/crontabs/$(whoami))" = "" ]]
then
echo "15 3 * * * /usr/bin/certbot renew --quiet" >> /var/spool/cron/crontabs/$(whoami)
fi
and the fi at the end
you can also avoid doing that much sudo by concatenating them like in:
sudo bash -c 'add-apt-repository -y ppa:certbot/certbot;apt-get update;apt-get upgrade -y;apt-get install -y software-properties-common python-certbot-nginx nginx;sed -i "s/server_name .*;/server_name $2;/" /etc/nginx/sites-available/default;systemctl restart nginx.service'
If you are doing this with sudo you are doing this as root
this is a simple thing to do in ansible, best do it there
to do the cron job do this:
CRON_FILE="/etc/cron.d/certbot"
if [ ! -f $CRON_FILE ] ; then
echo '15 3 * * * /usr/bin/certbot renew --quiet' > $CRON_FILE
fi
There are multiple ways to do this and they could be considered "proper" depending on the scenario.
One way to do it on boot time could be using cloud-init, For testing in the case of using AWS when creating the instance you could add your custom script:
This will allow running commands on launch of your instance, In case you would like to automate this process (infrastructure like code) you could use for example terraform
If for some reason you already have the instance up and running and just want to update on demand but not using ssh, you could use saltstack.
Talking about "Idempotency" Ansible could be also a very good tool for doing this, from the ansible glossary:
An operation is idempotent if the result of performing it once is exactly the same as the result of performing it repeatedly without any intervening actions.
There are many tools that can help you achieve this, only thing is to find the tool that adapts better to your needs/scenario.
Copy-paste solution for nginx + Ubuntu
Install dependencies
sudo apt-get install nginx -y
sudo apt-get install software-properties-common -y
sudo add-apt-repository universe -y
sudo add-apt-repository ppa:certbot/certbot -y
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx -y
Get SSL certificate and redirect all traffic from http to https
certbot --nginx --agree-tos --redirect --noninteractive \
--email YOUR#EMAIL.COM \
--domain YOUR.DOMAIN.COM
Test renewal
certbot renew --dry-run
Docs
https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx

Is the Syntax for the Bash Script right for an if elif statement

I added another condition to my if, elseif condition for my bash shell script. I am new to shell scripting, can you guys review my code if my syntax for if conditions are right especially the "fi" implementation. Much appreciated.
if [ -f /etc/system-release ] && grep Amazon /etc/system-release > /dev/null; then
cd /tmp
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
else
# we're either RedHat or Ubuntu
DISTRIBUTOR=`lsb_release -is`
DISTRIBUTOR2=`lsb_release -cs`
if [ "trusty" == $DISTRIBUTOR2 ]; then
cd /tmp
wget https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb
sudo dpkg -i amazon-ssm-agent.deb
sudo start amazon-ssm-agent
elif [ "RedHatEnterpriseServer" == $DISTRIBUTOR ]; then
cd /tmp
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
elif [ "xenial" == $DISTRIBUTOR2 ]; then
cd /tmp
wget https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb
sudo dpkg -i amazon-ssm-agent.deb
sudo systemctl enable amazon-ssm-agent
fi
fi
sleep 10
Looks basically ok, but https://www.shellcheck.net/ has a couple of comments that you should probably address.

How do I uninstall docker-compose?

I installed docker-compose by following the official documentation: http://docs.docker.com/compose/install/
Now I want to uninstall docker-compose.
$ docker-compose -h
offers no command for uninstalling, nor does the official documentation offer any instructions.
I deleted my docker-compose.yml file and /usr/local/bin/docker-compose, but I want to make sure that's everything.
I'm using OSX Yosemite 10.10.3 on a MacbookPro.
EDIT: Regarding the installation instructions I followed, I didn't use pip. I used the documented curl command:
$ curl -L https://github.com/docker/compose/releases/download/1.3.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
Documenation
Please note that this is now in the docs.
Coupled Installation and Removal
Note: on Mac Docker now installs Docker Compose. So the strategy for removal has changed a bit. If you uninstall Docker, and you want to uninstall both, then you also uninstall Docker Compose.
Individual Removal if Installed Using curl
It is commonly installed to /usr/local/bin/docker-compose on macs. However, you can run which docker-compose to find the exact location.
Run the following command (*nix systems) to remove:
rm $(which docker-compose)
If you get a permission denied error then you will need to prepend sudo:
sudo rm $(which docker-compose)
To verify that it was successful, run the following command which should return nothing:
which docker-compose
It should say that the command wasn't found.
Individual Removal if Installed Using PIP
If you've installed Docker Compose using PIP then you can run:
pip uninstall docker-compose
You may have to use sudo if you get a permission denied error:
sudo pip uninstall docker-compose
first get docker path by:
which docker-compose
then it will return path like:/usr/bin/docker-compose
then remove it:
sudo rm -rf /usr/bin/docker-compose
Nowadays docker-compose is part of the docker toolbox.
If you want to remove everything that comes with the Docker Toolbox (including Docker itself).
You can execute this shell script:
#!/bin/bash
# Uninstall Script
if [ "${USER}" != "root" ]; then
echo "$0 must be run as root!"
exit 2
fi
while true; do
read -p "Remove all Docker Machine VMs? (Y/N): " yn
case $yn in
[Yy]* ) docker-machine rm -f $(docker-machine ls -q); break;;
[Nn]* ) break;;
* ) echo "Please answer yes or no."; exit 1;;
esac
done
echo "Removing Applications..."
rm -rf /Applications/Docker
echo "Removing docker binaries..."
rm -f /usr/local/bin/docker
rm -f /usr/local/bin/docker-machine
rm -r /usr/local/bin/docker-machine-driver*
rm -f /usr/local/bin/docker-compose
echo "Removing boot2docker.iso"
rm -rf /usr/local/share/boot2docker
echo "All Done!"
If you still have the depreciated Boot2docker and you want to get rid of it as well.
You can uninstall it by executing the following shell script:
#!/bin/bash
# Uninstall Script
if [ "$(which boot2docker)" == "" ]; then
echo "boot2docker does not exist on your machine!"
exit 1
fi
if [ "${USER}" != "root" ]; then
echo "$0 must be run as root!"
exit 2
fi
echo "Stopping boot2docker processes..."
boot2docker stop && boot2docker delete
echo "Removing boot2docker executable..."
rm -f /usr/local/bin/boot2docker
echo "Removing boot2docker ISO and socket files..."
rm -rf ~/.boot2docker
rm -rf /usr/local/share/boot2docker
echo "Removing boot2docker SSH keys..."
rm -f ~/.ssh/id_boot2docker*
echo "Removing boot2docker OSX files..."
rm -f /private/var/db/receipts/io.boot2docker.*
rm -f /private/var/db/receipts/io.boot2dockeriso.*
echo "Removing Docker executable..."
rm -f /usr/local/bin/docker
echo "All Done!"
You can also just:
sudo yum remove docker-compose-plugin
on RPM-based like Centos
according to: https://docs.docker.com/compose/install/uninstall/
I would use pip uninstall docker-compose

Resources