Skip to content

Instantly share code, notes, and snippets.

@CandleHater
Last active May 10, 2020 15:13
Show Gist options
  • Save CandleHater/c36f8c205b31f70081d9e821bde36ebb to your computer and use it in GitHub Desktop.
Save CandleHater/c36f8c205b31f70081d9e821bde36ebb to your computer and use it in GitHub Desktop.
Initial setup on Debian (incl. Raspbian)
#!/bin/bash
# bash <(curl -s https://gist.githubusercontent.com/CandleHater/c36f8c205b31f70081d9e821bde36ebb/raw/initial-setup.sh)
# TODO
# - rename initial.sh + move gist to repo
# - bootloader configs https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711_bootloader_config.md
# - split up parts to several bash scripts and create repository
# apt packages
PACKAGES_INSTALL_BASICS="\
apt-transport-https \
git \
bash-completion \
htop \
curl \
wget \
tmux \
jq \
bc \
python3 \
python3-pip"
PACKAGES_INSTALL_RASPBERRY="\
wiringpi"
PACKAGES_UNNEEDED_RASPBERRY="\
libreoffice* \
oracle-java* \
chromium-browser \
nuscratch \
scratch \
sonic-pi \
minecraft-pi \
plymouth \
sysbench"
# intro
clear
for ((c = 0; c < $(tput cols); c++)); do
echo -n "🕯️🕯️🕯️"
done
echo
echo
# system info
echo "- system info"
echo "RAM"
free -h
echo
echo -e "Kernel\t: $(uname -rvm)"
echo -e "Uptime\t: $(uptime -p)"
cat /proc/cpuinfo | grep "model name" | sed "s/model name/CPU/g"
# raspberry?
IS_RASPBERRY=false
IS_RASPBERRY_ZERO=false
IS_RASPBERRY_4=false
if grep -Fq "Raspberry" /proc/cpuinfo; then
IS_RASPBERRY=true
echo -n -e "Model\t: Raspberry Pi"
# Pi Zero
if grep -Fq "Raspberry Pi Zero" /proc/cpuinfo; then
IS_RASPBERRY_ZERO=true
echo -n " Zero"
fi
# Pi 4
if grep -Fq "Raspberry Pi 4" /proc/cpuinfo; then
IS_RASPBERRY_4=true
echo -n " 4"
fi
echo
fi
echo
# config - general
echo "- config"
CONFIG_FILE="/home/$USER/.candle.conf"
if [[ -f "$CONFIG_FILE" ]]; then
echo "config file found ($CONFIG_FILE):"
cat $CONFIG_FILE
source $CONFIG_FILE
echo
fi
# hostname?
if [ -z ${CFG_HOSTNAME+x} ]; then
read -r -p "change hostname '$(hostname)' (press ENTER to skip): " CFG_HOSTNAME
if [ -z "$CFG_HOSTNAME" ]; then
CFG_HOSTNAME=$(hostname)
fi
# save
echo "CFG_HOSTNAME=\"$CFG_HOSTNAME\"" >> $CONFIG_FILE
fi
# use desktop?
if [ -z ${CFG_USE_DESKTOP+x} ]; then
read -n 1 -r -p "Using a desktop enviroment? [Y/n] " CFG_USE_DESKTOP
echo
if [[ $CFG_USE_DESKTOP =~ ^[Yy|]$ ]]; then
CFG_USE_DESKTOP=true
else
CFG_USE_DESKTOP=false
fi
# save
echo "CFG_USE_DESKTOP=$CFG_USE_DESKTOP" >> $CONFIG_FILE
fi
# remove python2?
if [[ "$CFG_USE_DESKTOP" = false ]]; then
PYTHON2_IS_INSTALLED=$(dpkg-query -W -f='${Status}' python2 2>/dev/null | grep -c "ok installed")
if [ $PYTHON2_IS_INSTALLED -eq 1 ]; then
read -n 1 -r -p "remove python2? [Y/n] " REMOVE_PYTHON2
echo
fi
fi
# reboot?
read -n 1 -r -p "reboot afterwards? [Y/n] " REBOOT
echo
echo
# config - raspberry
if [ "$IS_RASPBERRY" = true ]; then
echo "- config [Raspberry Pi]"
# bluetooth disable?
if [ -z ${CFG_DISABLE_BLUETOOTH+x} ]; then
read -n 1 -r -p "disable Bluetooth? [Y/n] " CFG_DISABLE_BLUETOOTH
echo
if [[ $CFG_DISABLE_BLUETOOTH =~ ^[Yy|]$ ]]; then
CFG_DISABLE_BLUETOOTH=true
else
CFG_DISABLE_BLUETOOTH=false
fi
# save
echo "CFG_DISABLE_BLUETOOTH=$CFG_DISABLE_BLUETOOTH" >> $CONFIG_FILE
fi
# LEDs disable?
if [ -z ${CFG_DISABLE_LED+x} ]; then
read -n 1 -r -p "disable LEDs? [Y/n] " CFG_DISABLE_LED
echo
if [[ $CFG_DISABLE_LED =~ ^[Yy|]$ ]]; then
CFG_DISABLE_LED=true
else
CFG_DISABLE_LED=false
fi
# save
echo "CFG_DISABLE_LED=$CFG_DISABLE_LED" >> $CONFIG_FILE
fi
# USB disable?
if [ -z ${CFG_DISABLE_USB+x} ]; then
read -n 1 -r -p "disable USB? [Y/n] " CFG_DISABLE_USB
echo
if [[ $CFG_DISABLE_USB =~ ^[Yy|]$ ]]; then
CFG_DISABLE_USB=true
else
CFG_DISABLE_USB=false
fi
# save
echo "CFG_DISABLE_USB=$CFG_DISABLE_USB" >> $CONFIG_FILE
fi
# not desktop
if [[ "$CFG_USE_DESKTOP" = false ]]; then
read -n 1 -r -p "disable HDMI + audio? [Y/n] " DISABLE_HDMI
echo
read -n 1 -r -p "remove unneeded packages ($PACKAGES_UNNEEDED_RASPBERRY)? [Y/n] " REMOVE_PACKAGES_UNNEEDED_RASPBERRY
echo
fi
# SPI activate?
if [ "$(sudo raspi-config nonint get_spi)" = "1" ]; then
read -n 1 -r -p "activate SPI? [Y/n] " ACTIVATE_SPI
echo
fi
# i2c activate?
if [ "$(sudo raspi-config nonint get_i2c)" = "1" ]; then
read -n 1 -r -p "activate i2c? [Y/n] " ACTIVATE_I2C
echo
fi
# shutdown button service install/update?
if [ "$IS_RASPBERRY_4" = true ]; then
if [ -z ${CFG_BUTTON_SHUTDOWN+x} ]; then
read -n 1 -r -p "install shutdown button service? [Y/n] " CFG_BUTTON_SHUTDOWN
echo
if [[ $CFG_BUTTON_SHUTDOWN =~ ^[Yy|]$ ]]; then
CFG_BUTTON_SHUTDOWN=true
else
CFG_BUTTON_SHUTDOWN=false
fi
# save
echo "CFG_BUTTON_SHUTDOWN=$CFG_BUTTON_SHUTDOWN" >> $CONFIG_FILE
fi
fi
# stresstest
read -n 1 -r -p "run stresstest? [Y/n] " STRESSTEST
echo
echo
fi
# password
echo "- change password of current user '$USER' (press CTRL+D to skip)"
sudo passwd $USER
echo
# add user
echo "- add user (press ENTER to skip)"
read -r -p "username: " USER_NEW
if [ ! -z "$USER_NEW" ]; then
read -n 1 -r -p "copy groups of current user '$USER'? [Y/n] " USER_NEW_GROUPS
echo
read -n 1 -r -p "lock current user '$USER' in two days? [Y/n] " USER_NEW_LOCK_OLD
echo
echo
sudo useradd -m $USER_NEW
echo "user added"
echo
sudo passwd $USER_NEW
echo
echo
sudo usermod -s /bin/bash $USER_NEW
echo "bash configured"
if [[ $USER_NEW_GROUPS =~ ^[Yy|]$ ]]; then
USER_GROUPS=$(groups | sed -e "s/$USER //g" | sed -e "s/ /,/g")
sudo usermod -a -G $USER_GROUPS $USER_NEW
echo
echo "groups copied from user '$USER': $USER_GROUPS"
fi
if [[ $USER_NEW_LOCK_OLD =~ ^[Yy|]$ ]]; then
echo
sudo usermod --expiredate $(date -d "2 days" +"%Y-%m-%d") $USER
echo "current user locked"
fi
echo
else
echo "skipped"
fi
echo
# custom comment
echo "- add 'candle custom' comment to config files"
CUSTOM_COMMENT="# candle custom [$(date)]"
echo "$CUSTOM_COMMENT"
if [ -f /etc/rc.local ]; then
if ! grep -q "# candle custom" /etc/rc.local; then
sudo sed -i -e "s/\"exit 0\"/exit/g" /etc/rc.local # see comment in rc.local
sudo sed -i -e "s/exit 0/$CUSTOM_COMMENT\n\nexit 0/g" /etc/rc.local
echo "/etc/rc.local"
fi
fi
if [ -f ~/.bashrc ]; then
if ! grep -q "# candle custom" ~/.bashrc; then
echo -e "\n$CUSTOM_COMMENT" >> ~/.bashrc
echo "~/.bashrc"
fi
fi
if [ -f /boot/config.txt ]; then
if ! grep -q "# candle custom" /boot/config.txt; then
sudo sh -c "echo '\n$CUSTOM_COMMENT' >> /boot/config.txt"
echo "/boot/config.txt"
fi
fi
echo
# hostname
HOSTNAME_OLD=$(hostname)
if [ ! -z "$CFG_HOSTNAME" ] && [ "$CFG_HOSTNAME" != "$HOSTNAME_OLD" ]; then
echo "- hostname"
sudo sh -c "echo '$CFG_HOSTNAME' > /etc/hostname"
sudo sed -i -e "s/$HOSTNAME_OLD/$CFG_HOSTNAME/g" /etc/hosts
sudo hostname $CFG_HOSTNAME
echo "hostname set to: $(hostname)"
echo
fi
# locale
# TODO
# sudo update-locale LC_ALL="en_US.UTF-8"
# keyboard layout
if [ ! "$(localectl | grep Keymap | cut -d: -f2 | xargs)" = "de-latin1" ]; then
echo "- keyboard layout"
sudo localectl set-keymap de-latin1
echo "changed to DE"
echo
fi
# timezone
if [ ! "$(timedatectl | grep "Time zone" | cut -d: -f2 | cut -d\( -f1 | xargs)" = "Europe/Berlin" ]; then
echo -n "- timezone"
sudo timedatectl set-timezone Europe/Berlin
sudo dpkg-reconfigure -f noninteractive tzdata
fi
# lock root user
if [ "$(sudo grep root /etc/shadow | grep '\!')" = "" ]; then
echo "- lock root user"
sudo passwd -u root --lock
echo
fi
# apt - update
echo "- apt update"
sudo apt update
echo
echo "- apt upgrade"
sudo apt upgrade -y
echo
echo "- apt upgrade"
sudo apt dist-upgrade -y
echo
echo "- apt autoremove (purge)"
sudo apt autoremove --purge -y
echo
# install basic packages
echo "- apt install basic packages ($PACKAGES_INSTALL_BASICS)"
sudo apt install -y $PACKAGES_INSTALL_BASICS
echo
# bash alias
BASH_ALIAS="alias la='ls -la'
alias py='python3'
"
if ! grep -q "alias la='ls -la'" ~/.bashrc; then
echo "- bash alias (.bashrc)"
echo -e "$BASH_ALIAS" >> ~/.bashrc
echo -e "$BASH_ALIAS"
fi
# fail2ban
if [ ! "$(systemctl is-active fail2ban.service)" = "active" ]; then
echo "- fail2ban"
sudo apt install -y fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
echo
fi
# unattended upgrades
if [ ! -f /etc/apt/apt.conf.d/02periodic ]; then
echo "- unattended upgrades"
sudo apt install -y unattended-upgrades
sudo sh -c "echo '
APT::Periodic::Enable \"1\";
APT::Periodic::Update-Package-Lists \"1\";
APT::Periodic::Download-Upgradeable-Packages \"1\";
APT::Periodic::Unattended-Upgrade \"1\";
APT::Periodic::AutocleanInterval \"1\";
APT::Periodic::Verbose \"2\";' > /etc/apt/apt.conf.d/02periodic"
echo
sudo unattended-upgrades -d
echo
fi
# SSH host key renew
SSH_KEY_SIZE="8192"
if ! ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub | grep -q "$SSH_KEY_SIZE"; then
echo "- renew SSH host key ($SSH_KEY_SIZE bit)"
sudo rm /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server
echo
echo y | sudo ssh-keygen -N "" -t rsa -b $SSH_KEY_SIZE -f /etc/ssh/ssh_host_rsa_key
echo
fi
# remove welcome message
sudo sh -c "echo -n '' > /etc/motd"
# raspberry
if [ "$IS_RASPBERRY" = true ]; then
# update firmware
echo "- rpi update"
sudo SKIP_WARNING=1 rpi-update
echo
# Pi4
if [ "$IS_RASPBERRY_4" = true ]; then
# button shutdown service
if [ "$CFG_BUTTON_SHUTDOWN" = true ]; then
echo "- install button service"
cd /tmp
git clone https://github.com/Howchoo/pi-power-button.git
./pi-power-button/script/install
cd ~
echo
fi
# eeprom - update
echo "- eeprom update"
sudo rpi-eeprom-update -a
echo
# eeprom - config
# echo "- eeprom config"
# EEPROM_CURRENT_FILE=$(ls /lib/firmware/raspberrypi/bootloader/beta/pieeprom-20*.bin | head -1)
# # get config
# cp $EEPROM_CURRENT_FILE /tmp/pieeprom.bin
# rpi-eeprom-config /tmp/pieeprom.bin > /tmp/bootconf.txt
# # set POWER_OFF_ON_HALT
# echo -n "POWER_OFF_ON_HALT=1"
# if grep -q "POWER_OFF_ON_HALT=1" /tmp/bootconf.txt; then
# echo -n " (skipped)"
# elif grep -q "POWER_OFF_ON_HALT=0" /tmp/bootconf.txt; then
# sed -i -e "s/POWER_OFF_ON_HALT=0/POWER_OFF_ON_HALT=1/g" /tmp/bootconf.txt
# echo -n " (changed)"
# else
# echo "POWER_OFF_ON_HALT=1" >> /tmp/bootconf.txt
# echo -n " (added)"
# fi
# echo
# # apply config
# rpi-eeprom-config --out /tmp/pieeprom-configured.bin --config /tmp/bootconf.txt /tmp/pieeprom.bin
# # flash bootloader
# echo "# flash bootloader"
# sudo rpi-eeprom-update -d -f /tmp/pieeprom-configured.bin
# echo
fi
# install basic packages
echo "- install basic raspberry packages ($PACKAGES_INSTALL_RASPBERRY)"
sudo apt install -y $PACKAGES_INSTALL_RASPBERRY
echo
# desktop
if [[ "$CFG_USE_DESKTOP" = true ]]; then
# install - firefox & xscreensaver (offers display timeout setting)
echo "- install firefox and xscreensaver"
sudo apt install -y firefox-esr xscreensaver
echo
# TODO add setup-control-view.sh
fi
# spi
if [[ $ACTIVATE_SPI =~ ^[Yy|]$ ]]; then
echo "- activate SPI"
sudo raspi-config nonint do_spi 0
echo "OK"
echo
fi
# i2c
if [[ $ACTIVATE_I2C =~ ^[Yy|]$ ]]; then
echo "- activate i2c"
sudo raspi-config nonint do_i2c 0
echo "OK"
echo
fi
# disable avahi (multi-cast DNS)
if [ "$(systemctl is-active avahi.service)" = "active" ]; then
echo "- disable avahi (multi-cast DNS)"
sudo systemctl disable avahi-daemon
sudo systemctl stop avahi-daemon
echo
fi
# disable TriggerHappy (button service)
if [ "$(systemctl is-active triggerhappy.service)" = "active" ]; then
echo "- disable TriggerHappy (button service)"
sudo systemctl disable triggerhappy.socket
sudo systemctl stop triggerhappy.socket
sudo systemctl disable triggerhappy
sudo systemctl stop triggerhappy
echo
fi
# ZRAM swap
echo "- ZRAM swap install/update"
sudo wget -O /usr/bin/zram.sh https://raw.githubusercontent.com/novaspirit/rpi_zram/master/zram.sh
sudo chmod +x /usr/bin/zram.sh
if ! grep -q "zram.sh" /etc/rc.local; then
sudo sed -i -e "s/exit 0/\/usr\/bin\/zram.sh \&\nexit 0/g" /etc/rc.local
echo "ZRAM installed"
else
echo "ZRAM updated"
fi
echo
# disable bluetooth
if [[ "$CFG_DISABLE_BLUETOOTH" = true ]]; then
echo "- disable bluetooth"
sudo systemctl disable hciuart.service
sudo systemctl disable bluealsa.service
sudo systemctl disable bluetooth.service
echo
sudo apt remove -y --purge pi-bluetooth bluez bluez-firmware
echo
if ! grep -q "disable-bt" /boot/config.txt; then
if [ "$IS_RASPBERRY_4" = true ]; then
sudo sh -c "echo 'dtoverlay=disable-bt' >> /boot/config.txt"
else
sudo sh -c "echo 'dtoverlay=pi3-disable-bt' >> /boot/config.txt"
fi
fi
echo "OK"
echo
fi
# disable/configure HDMI/audio
if [[ $DISABLE_HDMI =~ ^[Yy|]$ ]]; then
# disable HDMI
if ! grep -q "/usr/bin/tvservice -o" /etc/rc.local; then
echo "- disable HDMI"
sudo sed -i -e "s/exit 0/\/usr\/bin\/tvservice -o # disable HDMI\nexit 0/g" /etc/rc.local
sudo /usr/bin/tvservice -o
echo "OK"
echo
fi
# disable audio
if ! grep -q "dtparam=audio=off" /boot/config.txt; then
echo "- disable audio"
sudo sh -c "echo 'dtparam=audio=off' >> /boot/config.txt"
echo "OK"
echo
fi
# set minimum RAM shared with GPU
sudo raspi-config nonint do_memory_split 16
echo
else
if [[ "$CFG_USE_DESKTOP" = true ]]; then
# RAM shared with GPU
if [ "$IS_RASPBERRY_4" = true ]; then
sudo raspi-config nonint do_memory_split 512
else
sudo raspi-config nonint do_memory_split 128
fi
fi
fi
# disable USB
if [[ "$CFG_DISABLE_USB" = true ]]; then
if ! grep -q "/sys/devices/platform/soc/20980000.usb/buspower" /etc/rc.local; then
echo "- disable USB"
sudo sed -i -e "s/exit 0/echo 0 | sudo tee \/sys\/devices\/platform\/soc\/20980000.usb\/buspower # disable USB\nexit 0/g" /etc/rc.local
echo 0 | sudo tee /sys/devices/platform/soc/20980000.usb/buspower > /dev/null
echo "OK"
fi
else
if ! grep -q "max_usb_current=1" /boot/config.txt; then
echo "- higher USB current"
sudo sh -c "echo 'max_usb_current=1' >> /boot/config.txt"
echo "OK"
echo
fi
fi
# disable splash screen
if ! grep -q "disable_splash=1" /boot/config.txt; then
echo "- disable splash screen"
sudo sh -c "echo 'disable_splash=1' >> /boot/config.txt"
echo "OK"
echo
fi
# disable LEDs
if [[ "$CFG_DISABLE_LED" = true ]]; then
echo "- disable LEDs"
# status LED
if [ "$IS_RASPBERRY_ZERO" = true ]; then
if ! grep -q "dtparam=act_led_activelow=on" /boot/config.txt; then
sudo sh -c "echo 'dtparam=act_led_trigger=none' >> /boot/config.txt"
sudo sh -c "echo 'dtparam=act_led_activelow=on' >> /boot/config.txt"
echo "ACT LED disabled"
fi
else
if ! grep -q "dtparam=act_led_activelow=off" /boot/config.txt; then
sudo sh -c "echo 'dtparam=act_led_trigger=none' >> /boot/config.txt"
sudo sh -c "echo 'dtparam=act_led_activelow=off' >> /boot/config.txt"
echo "ACT LED disabled"
fi
fi
# power LED
if ! grep -q "dtparam=pwr_led_trigger=none" /boot/config.txt; then
sudo sh -c "echo 'dtparam=pwr_led_trigger=none' >> /boot/config.txt"
sudo sh -c "echo 'dtparam=pwr_led_activelow=off' >> /boot/config.txt"
echo "PWR LED disabled"
fi
echo
fi
# wifi country
echo "- set WiFi country"
sudo raspi-config nonint do_wifi_country DE
echo
# expand rootfs
echo "- expand rootfs"
sudo raspi-config --expand-rootfs > /dev/null
echo "OK"
echo
# stresstest
if [[ $STRESSTEST =~ ^[Yy|]$ ]]; then
echo "- stresstest"
bash <(curl -s https://raw.githubusercontent.com/rootzoll/raspiblitz/master/home.admin/config.scripts/blitz.stresstest.sh)
echo
fi
# remove unneeded packages
if [[ $REMOVE_PACKAGES_UNNEEDED_RASPBERRY =~ ^[Yy|]$ ]]; then
echo "- apt remove unneeded packages"
sudo apt remove -y --purge $PACKAGES_UNNEEDED_RASPBERRY | grep "Removing "
echo
fi
fi
# python2 - remove
if [[ $REMOVE_PYTHON2 =~ ^[Yy|]$ ]]; then
echo "- remove python2"
# packages
sudo pip freeze | grep -v "^-e" | xargs pip uninstall -y
# python
sudo apt remove -y --purge python2 python-pip
echo
fi
# pip3 - upgrade
PYTHON_PIP_UPGRADE="python3 -m pip install --upgrade --force pip setuptools wheel"
echo "- pip3 upgrade pip $PYTHON_PIP_UPGRADE"
$PYTHON_PIP_UPGRADE
echo
# pip3 bash completion
if ! grep -q "pip bash completion" ~/.bashrc; then
echo "- pip3 bash completion added (.bashrc)"
python3 -m pip completion --bash >> ~/.bashrc
echo "OK"
echo
fi
# pip3 - upgrade outdated packages
echo "- upgrade outdated pip3 packages"
echo "getting outdated packages.."
PYTHON_PIP_OUTDATED=$(python3 -m pip list --outdated --format freeze | awk '{split($0, a, "=="); print a[1]}')
while IFS= read -r package
do
# skip "problematic" packages
if [[ "$package" =~ ^(lxml|cryptography|pycairo|PyGObject|pyOpenSSL)$ ]]; then
echo "# '$package' pip3 package skipped"
continue
fi
# upgrade one by one, as some might not be managed by pip
echo "# '$package' pip3 package upgrade"
python3 -m pip install --upgrade $package
echo
done < <(echo "$PYTHON_PIP_OUTDATED")
echo
# apt - clean
echo "- apt clean"
sudo apt autoremove -y
echo
sudo apt autoclean -y
echo
sudo apt clean -y
# show storage sizes
echo "- HDD space"
df -h
echo
# candles
for ((c = 0; c < $(tput cols); c++)); do
echo -n "🕯️🕯️🕯️"
done
echo
echo
# reboot
if [[ $REBOOT =~ ^[Yy|]$ ]]; then
echo "- rebooting.."
echo
echo
sudo reboot
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment