wip
This commit is contained in:
19
tools/README.md
Normal file
19
tools/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Shell scripts
|
||||
|
||||
## Russian
|
||||
|
||||
Эти скрипты я писал в разное время для решения разных задач.
|
||||
Чтобы они не растерялись по репозиториям и носителям, я решил собрать их здесь в одну кучу.
|
||||
|
||||
Я всегда использую Ubuntu в качестве своих настольных и серверных ОС, поэтому все эти скрипты писались и использовались в этих средах с версий 18.*.
|
||||
|
||||
Многие скрипты зависимы от [io.sh](/io.sh).
|
||||
|
||||
## English
|
||||
|
||||
These scripts were written at different times to solve different my own problems.
|
||||
I decided to collect them here in a heap so that they are not lost in repositories and media.
|
||||
|
||||
I always use Ubuntu as my desktop and server OS, so all these scripts has been written and used in these environments since version 18.*.
|
||||
|
||||
Many scripts depending on [io.sh](/io.sh).
|
||||
32
tools/basic-ubuntu-lemp.sh
Normal file
32
tools/basic-ubuntu-lemp.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
apt update && apt upgrade -y --autoremove
|
||||
apt install -y \
|
||||
apt-transport-https \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
curl \
|
||||
dialog \
|
||||
gettext \
|
||||
gnupg \
|
||||
htop \
|
||||
libaio1 \
|
||||
libcurl4-gnutls-dev \
|
||||
libexpat1-dev \
|
||||
libghc-zlib-dev \
|
||||
libssl-dev \
|
||||
make \
|
||||
mc \
|
||||
nano \
|
||||
net-tools \
|
||||
nmap \
|
||||
p7zip-full \
|
||||
software-properties-common \
|
||||
unzip \
|
||||
inotify-tools \
|
||||
git \
|
||||
mariadb-server \
|
||||
mariadb-client \
|
||||
nginx \
|
||||
certbot
|
||||
26
tools/dc
Normal file
26
tools/dc
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
CONTAINER="my-container" # the name of the container in which to 'exec' something
|
||||
CONFIG="$(dirname $([ -L $0 ] && readlink -f $0 || echo $0))/docker-compose.yml" # path to compose yml file
|
||||
CMD="docker-compose -f $CONFIG" # docker-compose command
|
||||
APP_URL='http://localhost:8000/'
|
||||
|
||||
open_browser() {
|
||||
if which xdg-open > /dev/null; then
|
||||
xdg-open "$1" </dev/null >/dev/null 2>&1 & disown
|
||||
elif which gnome-open > /dev/null; then
|
||||
gnome-open "$1" </dev/null >/dev/null 2>&1 & disown
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'' | 'help' ) echo -e "Provide one of operations: \t start, stop, up, down, restart, rebuild, open";
|
||||
echo "Otherwise all args will be passed to 'docker exec -ti $CONTAINER ...'" ;;
|
||||
'open' ) open_browser $APP_URL ;;
|
||||
'up' ) $CMD up -d --build ;; # build and start containers
|
||||
'down' ) $CMD down --remove-orphans ;; # stop and remove containers
|
||||
'start' ) $CMD start ;; # start containers
|
||||
'stop' ) $CMD stop ;; # stop containers
|
||||
'restart' ) $CMD stop && $CMD start ;; # restart containers
|
||||
'rebuild' ) $CMD down --remove-orphans && $CMD up -d --build ;; # rebuild containers
|
||||
* ) docker exec -ti $CONTAINER $@ # exec anything in container
|
||||
esac
|
||||
@@ -1,54 +1,55 @@
|
||||
#!/bin/bash
|
||||
# https://gist.github.com/anthonyaxenov/c16e1181d4b8a8644c57ec8a1f6cf21c
|
||||
#########################################################################
|
||||
# #
|
||||
# Set display resolution #
|
||||
# Set output resolution #
|
||||
# #
|
||||
# Author: Anthony Axenov (Антон Аксенов) #
|
||||
# Version: 1.0 #
|
||||
# License: WTFPL #
|
||||
# License: WTFPLv2 #
|
||||
# #
|
||||
#########################################################################
|
||||
# #
|
||||
# Using this script you can change your display resolution #
|
||||
# Using this script you can change your output resolution #
|
||||
# to any one you need. Just adjust some vars below and run script #
|
||||
# (chmod +x needed). #
|
||||
# #
|
||||
#########################################################################
|
||||
|
||||
# https://gist.github.com/anthonyaxenov/c16e1181d4b8a8644c57ec8a1f6cf21c
|
||||
|
||||
# Set display name to work with. You can get it via 'xrandr --listactivemonitors'
|
||||
display="HDMI-2"
|
||||
# Set width of this display in px
|
||||
width=1600
|
||||
# Set height of this display in px
|
||||
height=900
|
||||
# Set output name to work with. You can get it via 'xrandr --listactivemonitors'
|
||||
output="HDMI-3"
|
||||
# Set width of this output in px
|
||||
width=1920
|
||||
# Set height of this output in px
|
||||
height=1080
|
||||
# Set refresh rate in Hz of this output in px
|
||||
refresh=120
|
||||
|
||||
# Sometimes cvt and gtf generates different modelines.
|
||||
# You can play around and look which of them gives best result:
|
||||
modeline=$(cvt ${width} ${height} | grep "Modeline")
|
||||
# modeline=$(gtf ${width} ${height} 60 | grep "Modeline")
|
||||
modeline=$(cvt ${width} ${height} ${refresh} | grep "Modeline")
|
||||
# modeline=$(gtf ${width} ${height} ${refresh} | grep "Modeline")
|
||||
|
||||
# Some important data needed to xrandr:
|
||||
modename="${width}x${height}_my"
|
||||
modename="${width}x${height}@${refresh}_my"
|
||||
params=$(echo "$modeline" | sed "s|^\s*Modeline\s*\"[0-9x_.]*\"\s*||")
|
||||
|
||||
echo "Set resolution ${width}x${height} on display $display:"
|
||||
echo "Set resolution ${width}x${height}@${refresh} on output $output:"
|
||||
echo "$modename $params"
|
||||
|
||||
# Simple logic:
|
||||
# 1. Switch display to safe mode which always exists (I believe) to avoid errors
|
||||
xrandr --output $display --mode 640x480
|
||||
# 2. If display aready have our mode -- we must delete it to avoid errors
|
||||
# 1. Switch output to safe mode which always exists (I believe) to avoid errors
|
||||
xrandr --output $output --mode 640x480 --verbose
|
||||
# 2. If output aready have our mode -- we must delete it to avoid errors
|
||||
if $(xrandr | grep -q "$modename"); then
|
||||
# 2.1. Detach mode from display
|
||||
xrandr --delmode $display $modename
|
||||
# 2.1. Detach mode from output
|
||||
xrandr --delmode $output $modename
|
||||
# 2.2. Remove mode itself
|
||||
xrandr --rmmode $modename
|
||||
fi
|
||||
# 3. Create new mode with freshly generated parameters
|
||||
xrandr --newmode $modename $params
|
||||
# 4. Attach mode to our display
|
||||
xrandr --addmode $display $modename
|
||||
# 5. Switch display to this mode immidiately
|
||||
xrandr --output $display --mode $modename
|
||||
xrandr --newmode $modename $params --verbose
|
||||
# 4. Attach mode to our output
|
||||
xrandr --addmode $output $modename --verbose
|
||||
# 5. Switch output to this mode immidiately
|
||||
xrandr --output $output --mode $modename --refresh $refresh --verbose
|
||||
0
tools/free-space.sh
Normal file → Executable file
0
tools/free-space.sh
Normal file → Executable file
121
tools/init-home-mediasrv.sh
Normal file
121
tools/init-home-mediasrv.sh
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt update && sudo apt upgrade -y --autoremove
|
||||
sudo apt install -y \
|
||||
alien \
|
||||
apt-transport-https \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
curl \
|
||||
dconf-editor \
|
||||
default-jdk \
|
||||
dialog \
|
||||
gettext \
|
||||
gnupg \
|
||||
gparted \
|
||||
hardinfo \
|
||||
htop \
|
||||
libaio1 \
|
||||
libcurl4-gnutls-dev \
|
||||
libexpat1-dev \
|
||||
libghc-zlib-dev \
|
||||
libssl-dev \
|
||||
lsb-release \
|
||||
lsp-plugins \
|
||||
make \
|
||||
mc \
|
||||
nano \
|
||||
neofetch \
|
||||
net-tools \
|
||||
nmap \
|
||||
p7zip-full \
|
||||
easyeffects \
|
||||
software-properties-common \
|
||||
ubuntu-restricted-extras \
|
||||
unzip \
|
||||
vlc \
|
||||
ffmpeg \
|
||||
xclip \
|
||||
inotify-tools \
|
||||
notify-osd \
|
||||
fonts-open-sans \
|
||||
libnotify-bin \
|
||||
gnome-software \
|
||||
gnome-software-plugin-flatpak \
|
||||
gnome-software-plugin-snap \
|
||||
terminator \
|
||||
geoclue-2.0 \
|
||||
redshift \
|
||||
redshift-gtk \
|
||||
samba \
|
||||
dkms
|
||||
|
||||
|
||||
# https://selectel.ru/blog/tutorials/how-to-install-and-configure-samba-on-ubuntu-20-04/
|
||||
# https://linuxconfig.org/how-to-configure-samba-server-share-on-ubuntu-22-04-jammy-jellyfish-linux
|
||||
# https://phoenixnap.com/kb/ubuntu-samba
|
||||
# https://computingforgeeks.com/install-and-configure-samba-server-share-on-ubuntu/
|
||||
# https://linux.how2shout.com/how-to-install-samba-on-ubuntu-22-04-lts-jammy-linux/
|
||||
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
|
||||
sudo bash -c 'grep -v -E "^#|^;" /etc/samba/smb.conf.bak | grep . > /etc/samba/smb.conf'
|
||||
sudo systemctl enable --now smbd
|
||||
sudo usermod -aG sambashare $USER
|
||||
sudo smbpasswd -a $USER
|
||||
|
||||
|
||||
|
||||
|
||||
sudo add-apt-repository -y ppa:agornostal/ulauncher && \
|
||||
sudo apt install -y --autoremove ulauncher
|
||||
|
||||
curl -L https://yt-dl.org/downloads/latest/youtube-dl -o "${HOME}/.local/bin/youtube-dl" && \
|
||||
sudo chmod +rx "${HOME}/.local/bin/youtube-dl"
|
||||
|
||||
wget "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" && \
|
||||
sudo dpkg -i google-chrome-stable_current_amd64.deb
|
||||
|
||||
git clone https://github.com/aircrack-ng/rtl8812au.git && \
|
||||
cd rtl8812au && \
|
||||
sudo make dkms_install
|
||||
|
||||
sudo curl -s -o /usr/share/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg && \
|
||||
echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list && \
|
||||
echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing candidate" | sudo tee /etc/apt/sources.list.d/syncthing.list && \
|
||||
sudo apt update && sudo apt install -y --autoremove syncthing && \
|
||||
wget "https://raw.githubusercontent.com/syncthing/syncthing/main/etc/linux-desktop/syncthing-start.desktop" -O $HOME/.local/share/applications/syncthing-start.desktop && \
|
||||
wget "https://raw.githubusercontent.com/syncthing/syncthing/main/etc/linux-desktop/syncthing-ui.desktop" -O $HOME/.local/share/applications/syncthing-ui.desktop && \
|
||||
ln -sf $HOME/.local/share/applications/syncthing-start.desktop $HOME/.config/autostart/syncthing-start.desktop
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
||||
sudo apt install -y kodi kodi-pvr-iptvsimple
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
5
tools/inotifywait-cp/README.md
Normal file
5
tools/inotifywait-cp/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Backing up photos from Syncthing
|
||||
|
||||
More info:
|
||||
* 🇷🇺 [axenov.dev/резервное-копирование-фотографий-со](https://axenov.dev/резервное-копирование-фотографий-со/)
|
||||
* 🇺🇸 (planned to translate)
|
||||
19
tools/inotifywait-cp/inotifywait-cp.service
Normal file
19
tools/inotifywait-cp/inotifywait-cp.service
Normal file
@@ -0,0 +1,19 @@
|
||||
# Daemon file
|
||||
# Place or symlink it to /etc/systemd/system/inotifywait-cp.service
|
||||
# Enable and start: sudo systemctl enable --now inotifywait-cp
|
||||
# Check it: sudo systemctl status inotifywait-cp
|
||||
|
||||
[Unit]
|
||||
Description=Photosync from android
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
# correct these parameters as needed:
|
||||
User=user
|
||||
WorkingDirectory=/home/user
|
||||
ExecStart=bash /home/user/.local/bin/photosync-a53.sh
|
||||
|
||||
|
||||
[Install]
|
||||
WantedBy=network.target
|
||||
59
tools/inotifywait-cp/inotifywait-cp.sh
Normal file
59
tools/inotifywait-cp/inotifywait-cp.sh
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# My use case:
|
||||
# syncthing synchronizes ALL changes in DCIM directory on my android to PC.
|
||||
# I wanted files to be copied somewhere else on my PC to stay forever, so I
|
||||
# could sort them later and safely free some space on mobile without loss.
|
||||
# Also I wish to have some stupid log with history of such events.
|
||||
|
||||
# inotify-tools package must be installed!
|
||||
|
||||
# CHANGE THIS PARAMETERS to ones you needed
|
||||
dir_src="$HOME/Syncthing/Mobile/Camera"
|
||||
dir_dest="$HOME/some/safe/place"
|
||||
dir_logs="$HOME/inotifywait-cp-logs"
|
||||
regexp="[0-9]{8}_[0-9]{6}.*\.(jpg|mp4|gif)"
|
||||
|
||||
print() {
|
||||
echo -e "[`date '+%H:%M:%S'`] $*" \
|
||||
| tee -a "$dir_logs/`date '+%Y%m%d'`.log"
|
||||
}
|
||||
|
||||
copy () {
|
||||
mkdir -p "$dir_src" "$dir_dest" "$dir_logs"
|
||||
if [ -f "$dir_dest/$1" ]; then
|
||||
print "SKIPPED:\t$dir_dest/$1"
|
||||
else
|
||||
cp "$dir_src/$1" "$dir_dest/$1"
|
||||
print "COPIED:\t$dir_src/$1 => $dir_dest/$1"
|
||||
fi
|
||||
}
|
||||
|
||||
mkdir -p "$dir_src" "$dir_dest" "$dir_logs"
|
||||
|
||||
print "START\t========================="
|
||||
|
||||
# First, try to backup files synced since last exec of this script
|
||||
ls -1 "$dir_src" \
|
||||
| grep -E "^$regexp$" \
|
||||
| while read filename; do copy "$filename"; done
|
||||
|
||||
# Next, run inotifywait against source directory with args:
|
||||
# --quiet -- print less (only print events)
|
||||
# --monitor -- don't stop after first event (like infinite loop)
|
||||
# --event -- first syncthing creates hidden file to write data into
|
||||
# then renames it according to source file name, so here
|
||||
# we listen to MOVED_TO event to catch final filename
|
||||
# --format %f -- print only filename
|
||||
# --include -- filename regexp to catch event from, ensure your $regexp
|
||||
# is correct or remove line 56 to catch synced ALL files
|
||||
|
||||
inotifywait \
|
||||
--quiet \
|
||||
--monitor \
|
||||
--event moved_to \
|
||||
--format %f \
|
||||
--include "$regexp" \
|
||||
"$dir_src" \
|
||||
| while read filename; do copy "$filename"; done
|
||||
|
||||
print "FINISH\t========================="
|
||||
157
tools/netbeans-php-wrapper/php
Normal file
157
tools/netbeans-php-wrapper/php
Normal file
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Welcome to amusement park!
|
||||
|
||||
[[ "$1" = '--help' ]] || [[ "$1" = '-h' ]] && cat <<EOF && exit
|
||||
NetBeans docker wrapper for php
|
||||
===============================
|
||||
Anthony Axenov (c) 2023, The MIT License
|
||||
https://axenov.dev
|
||||
https://opensource.org/license/mit
|
||||
Replacement host php interpreter with dockerized one to run & debug cli php scripts.
|
||||
Usage:
|
||||
./$(basename $0) --container=<NAME> [--map=<PATH1>:<PATH2>] [PHP_ARGS] <SCRIPT> [SCRIPT_ARGS]
|
||||
Arguments:
|
||||
--container : docker container where your SCRIPT is located. Required.
|
||||
--map : sources path mapped from the host to container. Not required.
|
||||
PATH1 is an absolute path to php sources directory on the host.
|
||||
PATH2 is an absolute path of the same directory inside of container.
|
||||
Delimiter ':' is required. If PATH1, PATH2 or delimiter is missed
|
||||
or value is empty then error will be thrown.
|
||||
PHP_ARGS : arguments you can pass to real php interpreter according to its --help.
|
||||
Not required.
|
||||
SCRIPT : a path to script file (.php) to be executed in container. Required.
|
||||
Note that this file must exist inside or be available from that container.
|
||||
SCRIPT_ARGS : arguments to call your script with. They will be passed to script as is.
|
||||
Not required.
|
||||
Read this article to know how to set this helper as interpreter for NetBeans:
|
||||
ru: https://axenov.dev/netbeans-php-docker-xdebug-cli
|
||||
en: https://axenov.dev/en/netbeans-php-docker-xdebug-cli-en
|
||||
EOF
|
||||
|
||||
pwd=$(pwd) # current working directory
|
||||
cmdline=($@) # copy currently called command line to array
|
||||
collect_php_args=1 # should we collect php args or script ones?
|
||||
quiet=0 # should we print some useful data before executing?
|
||||
|
||||
# find a path where this wrapper is located
|
||||
wrapper_dir="$(dirname $0)"
|
||||
|
||||
# find a path where project is probably located
|
||||
project_dir="$(dirname $wrapper_dir)"
|
||||
|
||||
# here we check if this wrapper is global or local
|
||||
# but if it is set as global from nbproject dir of
|
||||
# current project then it is not detected as global
|
||||
# anyway behavior will be correct
|
||||
nbproject="$(basename $wrapper_dir)"
|
||||
[ "$nbproject" = 'nbproject' ] && is_global=0 || is_global=1
|
||||
|
||||
# prepare new array to collect php args
|
||||
declare -a php_cmd=("docker" "exec")
|
||||
|
||||
# and another one for script args
|
||||
declare -a script_args=()
|
||||
|
||||
# and one more for directory mapping
|
||||
declare -a map_arr=()
|
||||
|
||||
# iterate over arguments we received from netbeans
|
||||
for arg in "${cmdline[@]}"; do
|
||||
|
||||
# if this is a container name
|
||||
if [ "${arg::11}" = '--container' ]; then
|
||||
container="${arg:12}" # save it
|
||||
php_cmd+=("$container" 'php') # add php itself
|
||||
continue # jump to next iteration
|
||||
fi
|
||||
|
||||
# if this is a path map
|
||||
if [ "${arg::5}" = '--map' ]; then
|
||||
map="${arg:6}" # save it
|
||||
map_arr=(${map//:/ }) # split it and check if it is correct
|
||||
if [ -z "${map_arr[0]}" ] || [ -z "${map_arr[1]}" ]; then
|
||||
echo "ERROR: directory map is incorrect!"
|
||||
echo "Use $0 --help to get info about how to use this wrapper."
|
||||
echo "Exit code 3."
|
||||
exit 3
|
||||
fi
|
||||
continue # jump to next iteration
|
||||
fi
|
||||
|
||||
# if this is a container name
|
||||
if [ "${arg::7}" = '--quiet' ]; then
|
||||
quiet=1
|
||||
continue # jump to next iteration
|
||||
fi
|
||||
|
||||
# if this is an absolute path to a script file
|
||||
if [ -f "$arg" ]; then
|
||||
# make its path correct for container
|
||||
if [ "$map" ]; then # when paths are mapped
|
||||
# remove first part of map from an absolute filepath and append result to second map part
|
||||
filepath="${map_arr[1]}${arg##${map_arr[0]}}"
|
||||
else # when paths are NOT mapped
|
||||
# remove project path from absolute filepath
|
||||
filepath="${arg##$project_dir/}"
|
||||
fi
|
||||
php_cmd+=("$filepath") # append php args with filepath
|
||||
collect_php_args=0 # now we need to collect script args
|
||||
continue # jump to next iteration
|
||||
fi
|
||||
|
||||
if [ "$collect_php_args" = 1 ]; then # if we collect php args
|
||||
php_cmd+=("$arg") # add current arg to php args as is
|
||||
continue # jump to next iteration
|
||||
fi
|
||||
|
||||
script_args+=("$arg") # otherwise add current arg to script args as is
|
||||
done
|
||||
|
||||
# docker container name is required so we must halt here if there is no one
|
||||
if [ -z "$container" ]; then
|
||||
echo "ERROR: no docker container is specified!" >&2
|
||||
echo "Use $0 --help to get info about how to use this wrapper." >&2
|
||||
echo "Exit code 1." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# path to php script is also required so we must halt here too if there is no one
|
||||
if [ -z "$filepath" ]; then
|
||||
echo "ERROR: no script filepath is specified!" >&2
|
||||
echo "Use $0 --help to get info about how to use this wrapper." >&2
|
||||
echo "Exit code 2." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
cmdline="${php_cmd[*]} ${script_args[*]}" # make a command to execute
|
||||
|
||||
# print some important data collected above
|
||||
if [ "$quiet" = 0 ]; then
|
||||
echo "NetBeans docker wrapper for php"
|
||||
echo "==============================="
|
||||
echo -e "Container name: $container"
|
||||
echo -e "Script path: $filepath"
|
||||
echo -e "Directory mapping: ${map:-(none)}"
|
||||
echo -e "Command line:\n$cmdline\n"
|
||||
fi
|
||||
|
||||
# some debug output
|
||||
# echo "=== some debug output ========="
|
||||
# cat <<EOF | column -t
|
||||
# is_global $is_global
|
||||
# container $container
|
||||
# pwd $pwd
|
||||
# wrapper_dir $wrapper_dir
|
||||
# nbproject $nbproject
|
||||
# project_dir $project_dir
|
||||
# map $map
|
||||
# map_arr[0] ${map_arr[0]}
|
||||
# map_arr[1] ${map_arr[1]}
|
||||
# filepath $filepath
|
||||
# EOF
|
||||
# echo "==============================="
|
||||
|
||||
$cmdline # execute
|
||||
|
||||
# that's folks!
|
||||
@@ -1,16 +1,15 @@
|
||||
#!/bin/bash
|
||||
# https://gist.github.com/anthonyaxenov/b8336a2bc9e6a742b5a050fa2588d71e
|
||||
#####################################################################
|
||||
# #
|
||||
# Stupidly simple backup script for own projects #
|
||||
# #
|
||||
# Author: Anthony Axenov (Антон Аксенов) #
|
||||
# Version: 1.0 #
|
||||
# License: WTFPLv2 More info (RU): https://axenov.dev/?p=1234 #
|
||||
# License: WTFPLv2 More info: https://axenov.dev/?p=1423 #
|
||||
# #
|
||||
#####################################################################
|
||||
|
||||
# https://gist.github.com/anthonyaxenov/b8336a2bc9e6a742b5a050fa2588d71e
|
||||
|
||||
# database credentials ==============================================
|
||||
|
||||
DBUSER=
|
||||
|
||||
72
tools/rsync-backup.sh
Executable file
72
tools/rsync-backup.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
RS_SRC_DEV=/dev/sdb1
|
||||
RS_DST_DEV=/dev/sdc1
|
||||
LOG_DIR="/home/$USER/rsync-logs"
|
||||
USE_NTFY=0
|
||||
NTFY_TITLE="Backup: $RS_SRC_DEV => $RS_DST_DEV"
|
||||
NTFY_CHANNEL=""
|
||||
|
||||
log() {
|
||||
[ ! -d "$LOG_DIR" ] && mkdir -p "$LOG_DIR"
|
||||
echo -e "[`date '+%H:%M:%S'`] $*" | tee -a "$LOG_DIR/`date '+%Y%m%d'`.log"
|
||||
}
|
||||
|
||||
# отправляет простую нотификацию
|
||||
ntfy_info() {
|
||||
[ $USE_NTFY == 1 ] && ntfy send \
|
||||
--title "$NTFY_TITLE" \
|
||||
--message "$1" \
|
||||
--priority 1 \
|
||||
"$NTFY_CHANNEL"
|
||||
}
|
||||
|
||||
# отправляет нотификацию с предупреждением
|
||||
ntfy_warn() {
|
||||
[ $USE_NTFY == 1 ] && ntfy send \
|
||||
--title "$NTFY_TITLE" \
|
||||
--tags "warning" \
|
||||
--message "$1" \
|
||||
--priority 5 \
|
||||
"$NTFY_CHANNEL"
|
||||
}
|
||||
|
||||
log "START\t========================="
|
||||
|
||||
mnt_check=$(findmnt -nf "$RS_SRC_DEV")
|
||||
if [ $? -gt 0 ]; then
|
||||
log "Source partition '$RS_SRC_DEV' is not mounted. Exit 1."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RS_SRC_PATH=$(echo $mnt_check | awk '{ print $1 }')
|
||||
log "Source partition '$RS_SRC_DEV' is mounted at '$RS_SRC_PATH'"
|
||||
|
||||
mnt_check=$(findmnt -nf "$RS_DST_DEV")
|
||||
if [ $? -gt 0 ]; then
|
||||
log "Destination partition '$RS_DST_DEV' is not mounted. Exit 1."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RS_DST_PATH=$(echo $mnt_check | awk '{ print $1 }')
|
||||
log "Destination partition '$RS_DST_DEV' is mounted at '$RS_DST_PATH'"
|
||||
|
||||
log "Executing rsync:"
|
||||
|
||||
rsync -huva \
|
||||
--progress \
|
||||
--delete \
|
||||
--exclude='lost+found' \
|
||||
--exclude='.Trash' \
|
||||
"$RS_SRC_PATH/" \
|
||||
"$RS_DST_PATH/" \
|
||||
| while read line; do log "$line"; done
|
||||
|
||||
if [ $? -gt 0 ]; then
|
||||
log "Something went wrong. Exit 3."
|
||||
ntfy_warn "Something went wrong, check log"
|
||||
exit 3
|
||||
fi
|
||||
ntfy_info "Success!"
|
||||
|
||||
log "FINISH\t========================="
|
||||
18
tools/s3-backup-old.sh
Executable file
18
tools/s3-backup-old.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
TTL_DAYS=1
|
||||
S3="s3://......"
|
||||
OLDER_THAN=$(date -d "$TTL_DAYS days ago" "+%s")
|
||||
echo $OLDER_THAN
|
||||
s3cmd ls -r $S3 | while read -r line; do
|
||||
FILETIME=$(echo "$line" | awk {'print $1" "$2'})
|
||||
FILETIME=$(date -d "$FILETIME" "+%s")
|
||||
echo $FILETIME - $OLDER_THAN
|
||||
if [[ $FILETIME -le $OLDER_THAN ]]; then
|
||||
FILEPATH=$(echo "$line" | awk {'print $4'})
|
||||
if [ $FILEPATH != "" ]; then
|
||||
printf 'Must delete: %s\n' $FILEPATH
|
||||
echo "s3cmd del $FILEPATH"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
342
tools/s3-backup.sh
Normal file
342
tools/s3-backup.sh
Normal file
@@ -0,0 +1,342 @@
|
||||
#!/bin/bash
|
||||
#####################################################################
|
||||
# #
|
||||
# Stupidly simple backup script for own projects #
|
||||
# #
|
||||
# Author: Anthony Axenov (Антон Аксенов) #
|
||||
# Version: 1.2 #
|
||||
# License: WTFPLv2 #
|
||||
# More info (RU): https://axenov.dev/?p=1272 #
|
||||
# #
|
||||
#####################################################################
|
||||
|
||||
# use remote storages ===============================================
|
||||
|
||||
USE_SSH=1
|
||||
USE_S3=1
|
||||
|
||||
# database credentials ==============================================
|
||||
|
||||
DBUSER=
|
||||
DBPASS=
|
||||
DBNAME=
|
||||
DBCHARSET="utf8"
|
||||
|
||||
# dates for file structure ==========================================
|
||||
|
||||
TODAY_DIR="$(date +%Y.%m.%d)"
|
||||
TODAY_FILE="$(date +%H.%M)"
|
||||
|
||||
# local storage =====================================================
|
||||
|
||||
LOCAL_BAK_DIR="/backup"
|
||||
LOCAL_BAK_PATH="$LOCAL_BAK_DIR/$TODAY_DIR"
|
||||
|
||||
# database backup file
|
||||
LOCAL_SQL_FILE="$TODAY_FILE-db.sql.gz"
|
||||
LOCAL_SQL_PATH="$LOCAL_BAK_PATH/$LOCAL_SQL_FILE"
|
||||
|
||||
# project path and backup file
|
||||
LOCAL_SRC_DIR="/var/www/html"
|
||||
LOCAL_SRC_FILE="$TODAY_FILE-src.tar.gz"
|
||||
LOCAL_SRC_PATH="$LOCAL_BAK_PATH/$LOCAL_SRC_FILE"
|
||||
|
||||
# log file
|
||||
LOG_FILE="$TODAY_FILE.log"
|
||||
LOG_PATH="$LOCAL_BAK_PATH/$LOG_FILE"
|
||||
|
||||
# remote storages ===================================================
|
||||
|
||||
SSH_HOST="user@example.com"
|
||||
SSH_BAK_DIR="/backup"
|
||||
SSH_BAK_PATH="$SSH_BAK_DIR/$TODAY_DIR"
|
||||
SSH_SQL_FILE="$SSH_BAK_PATH/$LOCAL_SQL_FILE"
|
||||
SSH_SRC_FILE="$SSH_BAK_PATH/$LOCAL_SRC_FILE"
|
||||
SSH_LOG_FILE="$SSH_BAK_PATH/$LOG_FILE"
|
||||
|
||||
S3_BUCKET="s3://my.bucket"
|
||||
S3_DIR="$S3_BUCKET/$TODAY_DIR"
|
||||
S3_SQL_FILE="$S3_DIR/$LOCAL_SQL_FILE"
|
||||
S3_SRC_FILE="$S3_DIR/$LOCAL_SRC_FILE"
|
||||
S3_LOG_FILE="$S3_DIR/$LOG_FILE"
|
||||
|
||||
# autoremove ========================================================
|
||||
|
||||
# time to live on different storages
|
||||
TTL_LOCAL=3
|
||||
TTL_SSH=7
|
||||
TTL_S3=60
|
||||
|
||||
# autoremove flags
|
||||
CLEAR_SSH=1
|
||||
CLEAR_S3=1
|
||||
|
||||
# notifications =====================================================
|
||||
|
||||
USE_NTFY=1
|
||||
NTFY_TITLE="Backup script"
|
||||
NTFY_CHANNEL=
|
||||
|
||||
#====================================================================
|
||||
#
|
||||
# Functions used for the whole backup flow
|
||||
#
|
||||
#====================================================================
|
||||
|
||||
# prints arguments to stdout and into log file
|
||||
log() {
|
||||
echo -e "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_PATH"
|
||||
}
|
||||
|
||||
# sends notification with information
|
||||
ntfy_info() {
|
||||
[ $USE_NTFY == 1 ] && ntfy send \
|
||||
--title "$NTFY_TITLE" \
|
||||
--message "$1" \
|
||||
--priority 1 \
|
||||
"$NTFY_CHANNEL"
|
||||
}
|
||||
|
||||
# sends notification with warning
|
||||
ntfy_warn() {
|
||||
[ $USE_NTFY == 1 ] && ntfy send \
|
||||
--title "$NTFY_TITLE" \
|
||||
--tags "warning" \
|
||||
--message "$1" \
|
||||
--priority 5 \
|
||||
"$NTFY_CHANNEL"
|
||||
}
|
||||
|
||||
# prints initialized parameters
|
||||
show_params() {
|
||||
log "Initialized parameters:"
|
||||
|
||||
log "├ [ Remotes ]"
|
||||
log "│\t├ USE_SSH = $USE_SSH"
|
||||
[ $USE_SSH == 1 ] && log "│\t├ SSH_HOST = $SSH_HOST"
|
||||
log "│\t├ USE_S3 = $USE_S3"
|
||||
[ $USE_S3 == 1 ] && log "│\t├ S3_BUCKET = $S3_BUCKET"
|
||||
|
||||
log "├ [ Database ]"
|
||||
log "│\t├ DBUSER = $DBUSER"
|
||||
log "│\t├ DBNAME = $DBNAME"
|
||||
log "│\t├ DBCHARSET = $DBCHARSET"
|
||||
log "│\t├ LOCAL_SQL_PATH = $LOCAL_SQL_PATH"
|
||||
[ $USE_SSH == 1 ] && log "│\t├ SSH_SQL_FILE = $SSH_SQL_FILE"
|
||||
[ $USE_S3 == 1 ] && log "│\t├ S3_SQL_FILE = $S3_SQL_FILE"
|
||||
|
||||
log "├ [ Sources ]"
|
||||
log "│\t├ LOCAL_SRC_DIR = $LOCAL_SRC_DIR"
|
||||
log "│\t├ LOCAL_SRC_PATH = $LOCAL_SRC_PATH"
|
||||
[ $USE_SSH == 1 ] && log "│\t├ SSH_SRC_FILE = $SSH_SRC_FILE"
|
||||
[ $USE_S3 == 1 ] && log "│\t├ S3_SRC_FILE = $S3_SRC_FILE"
|
||||
|
||||
log "├ [ Log ]"
|
||||
log "│\t├ LOG_PATH = $LOG_PATH"
|
||||
[ $USE_SSH == 1 ] && log "│\t├ SSH_LOG_FILE = $SSH_LOG_FILE"
|
||||
[ $USE_S3 == 1 ] && log "│\t├ S3_LOG_FILE = $S3_LOG_FILE"
|
||||
|
||||
log "├ [ Autoclear ]"
|
||||
log "│\t├ TTL_LOCAL = $TTL_LOCAL"
|
||||
[ $USE_SSH == 1 ] && {
|
||||
log "│\t├ CLEAR_SSH = $CLEAR_SSH"
|
||||
log "│\t├ TTL_SSH = $TTL_SSH"
|
||||
}
|
||||
[ $USE_S3 == 1 ] && {
|
||||
log "│\t├ CLEAR_S3 = $CLEAR_S3"
|
||||
log "│\t├ TTL_S3 = $TTL_S3"
|
||||
}
|
||||
|
||||
log "└ [ ntfy ]"
|
||||
log "\t├ USE_NTFY = $USE_NTFY"
|
||||
[ $USE_NTFY == 1 ] && log "\t├ NTFY_TITLE = $NTFY_TITLE"
|
||||
[ $USE_NTFY == 1 ] && log "\t└ NTFY_CHANNEL = $NTFY_CHANNEL"
|
||||
}
|
||||
|
||||
# initializes directories for backup
|
||||
init_dirs() {
|
||||
if [ ! -d "$LOCAL_BAK_PATH" ]; then
|
||||
mkdir -p $LOCAL_BAK_PATH
|
||||
fi
|
||||
[ $USE_SSH == 1 ] && ssh $SSH_HOST "mkdir -p $SSH_BAK_PATH"
|
||||
}
|
||||
|
||||
# clears old local backups
|
||||
clear_local_backups() {
|
||||
log "\tLocal:"
|
||||
log $(find "$LOCAL_BAK_DIR" -type d -mtime +"$TTL_LOCAL" | sort)
|
||||
find "$LOCAL_BAK_DIR" -type d -mtime +"$TTL_LOCAL" | xargs rm -rf
|
||||
}
|
||||
|
||||
# clears old backups on remote ssh storage
|
||||
clear_ssh_backups() {
|
||||
if [ $USE_SSH == 1 ] && [ $CLEAR_SSH == 1 ]; then
|
||||
log "\tSSH:"
|
||||
log $(ssh "$SSH_HOST" "find $SSH_BAK_DIR -type d -mtime +$TTL_SSH" | sort)
|
||||
ssh "$SSH_HOST" "find $SSH_BAK_DIR -type d -mtime +$TTL_SSH | xargs rm -rf"
|
||||
else
|
||||
log "\tSSH: disabled (\$USE_SSH, \$CLEAR_SSH)"
|
||||
fi
|
||||
}
|
||||
|
||||
# clears backups on remote s3 storage
|
||||
clear_s3_backups() {
|
||||
# https://gist.github.com/JProffitt71/9044744?permalink_comment_id=3539681#gistcomment-3539681
|
||||
if [ $USE_S3 == 1 ] && [ $CLEAR_S3 == 1 ]; then
|
||||
log "\tS3:"
|
||||
OLDER_THAN=$(date -d "$TTL_S3 days ago" "+%s")
|
||||
s3cmd ls -r $S3_DIR | while read -r line; do
|
||||
FILETIME=$(echo "$line" | awk {'print $1" "$2'})
|
||||
FILETIME=$(date -d "$FILETIME" "+%s")
|
||||
if [[ $FILETIME -le $OLDER_THAN ]]; then
|
||||
FILEPATH=$(echo "$line" | awk {'print $4'})
|
||||
if [ $FILEPATH != "" ]; then
|
||||
log "$line"
|
||||
s3cmd del $FILEPATH
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "\tS3: disabled (\$USE_S3 + \$CLEAR_S3)"
|
||||
fi
|
||||
}
|
||||
|
||||
# clears old backups
|
||||
clear_backups() {
|
||||
echo
|
||||
log "1/7 Removing old backups..."
|
||||
clear_local_backups
|
||||
clear_ssh_backups
|
||||
clear_s3_backups
|
||||
}
|
||||
|
||||
# makes archive with database dump
|
||||
backup_db() {
|
||||
echo
|
||||
log "2/7 Dumping DB: $DBNAME..."
|
||||
mysqldump \
|
||||
--user=$DBUSER \
|
||||
--password=$DBPASS \
|
||||
--opt \
|
||||
--default-character-set=$DBCHARSET \
|
||||
--quick \
|
||||
$DBNAME | gzip > $LOCAL_SQL_PATH
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
send_db_ssh
|
||||
send_db_s3
|
||||
else
|
||||
log "\t- ERROR: failed to create dump. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to create dump"
|
||||
log "3/7 Sending database backup to $SSH_HOST... skipped"
|
||||
log "4/7 Sending database backup to $S3_DIR... skipped"
|
||||
fi
|
||||
}
|
||||
|
||||
# sends database archive into ssh remote storage
|
||||
send_db_ssh() {
|
||||
echo
|
||||
log "3/7 Sending database backup to $SSH_HOST..."
|
||||
if [ $USE_SSH == 1 ]; then
|
||||
rsync --progress "$LOCAL_SQL_PATH" "$SSH_HOST:$SSH_SQL_FILE"
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
else
|
||||
log "\t- ERROR: failed to send DB backup to $SSH_HOST. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to send DB backup to $SSH_HOST"
|
||||
fi
|
||||
else
|
||||
log "\t- disabled (\$USE_SSH)"
|
||||
fi
|
||||
}
|
||||
|
||||
# sends database archive into s3 remote storage
|
||||
send_db_s3() {
|
||||
echo
|
||||
log "4/7 Sending database backup to $S3_DIR..."
|
||||
if [ $USE_S3 == 1 ]; then
|
||||
s3cmd put "$LOCAL_SQL_PATH" "$S3_SQL_FILE"
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
else
|
||||
log "\t- ERROR: failed to send DB backup to $S3_DIR. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to send DB backup to $S3_DIR"
|
||||
fi
|
||||
else
|
||||
log "\t- disabled (\$USE_SSH)"
|
||||
fi
|
||||
}
|
||||
|
||||
# makes archive with project sources
|
||||
backup_src() {
|
||||
echo
|
||||
log "5/7 Compressing project dir: $LOCAL_SRC_DIR..."
|
||||
tar -zcf "$LOCAL_SRC_PATH" "$LOCAL_SRC_DIR"
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
send_src_ssh
|
||||
send_src_s3
|
||||
else
|
||||
log "\t- ERROR: failed to compress project. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to compress project"
|
||||
log "6/7 Sending project backup to $SSH_HOST... skipped"
|
||||
log "7/7 Sending project backup to $S3_DIR... skipped"
|
||||
fi
|
||||
}
|
||||
|
||||
# sends sources archive into ssh remote storage
|
||||
send_src_ssh() {
|
||||
echo
|
||||
log "6/7 Sending project backup to $SSH_HOST..."
|
||||
if [ $USE_SSH == 1 ]; then
|
||||
rsync --progress "$LOCAL_SRC_PATH" "$SSH_HOST:$SSH_SRC_FILE"
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
else
|
||||
log "\t- ERROR: failed to send project backup to $SSH_HOST. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to send project backup to $SSH_HOST"
|
||||
fi
|
||||
else
|
||||
log "\t- disabled"
|
||||
fi
|
||||
}
|
||||
|
||||
# sends sources archive into s3 remote storage
|
||||
send_src_s3() {
|
||||
echo
|
||||
log "7/7 Sending project backup to $S3_DIR..."
|
||||
s3cmd put "$LOCAL_SRC_PATH" "$S3_SRC_FILE"
|
||||
if [ $? == 0 ]; then
|
||||
log "\t- OK"
|
||||
else
|
||||
log "\t- ERROR: failed to send database backup to $S3_DIR. Exit-code: $?"
|
||||
ntfy_warn "ERROR: failed to send project backup to $S3_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# prints used/free space on local storage
|
||||
show_finish() {
|
||||
echo
|
||||
log "Finish!"
|
||||
log "Used space: $(du -h "$LOCAL_BAK_PATH" | tail -n1)" # вывод размера папки с бэкапами за текущий день
|
||||
log "Free space: $(df -h "$LOCAL_BAK_PATH" | tail -n1 | awk '{print $4}')" # вывод свободного места на локальном диске
|
||||
echo
|
||||
}
|
||||
|
||||
# sends log file into both remote storage
|
||||
send_log() {
|
||||
[ $USE_SSH == 1 ] && rsync --progress "$LOG_PATH" "$SSH_HOST:$SSH_LOG_FILE"
|
||||
[ $USE_S3 == 1 ] && s3cmd put "$LOG_PATH" "$S3_LOG_FILE"
|
||||
}
|
||||
|
||||
# main flow =========================================================
|
||||
|
||||
log "Start ----------------------------------------------------------"
|
||||
show_params
|
||||
init_dirs
|
||||
clear_backups
|
||||
backup_db
|
||||
backup_src
|
||||
show_finish
|
||||
send_log
|
||||
ntfy_info "Finish!"
|
||||
40
tools/setup-wakeonlan.sh
Executable file
40
tools/setup-wakeonlan.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
print() {
|
||||
echo -e "$*"
|
||||
}
|
||||
|
||||
state() {
|
||||
sudo ethtool "$iface" | grep -E '^\s+Wake-on:\s\w+' | awk '{print $2}'
|
||||
}
|
||||
|
||||
[ "$1" ] && iface="$1" || iface=enp3s0
|
||||
|
||||
[ -f "/sys/class/net/$iface/address" ] && mac=$(cat "/sys/class/net/$iface/address") || mac=''
|
||||
[ -z "$mac" ] && {
|
||||
print "Wrong interface! $iface" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
state=$(state)
|
||||
|
||||
print "Interface\t: $iface"
|
||||
print "MAC-address\t: $mac"
|
||||
print "WoL state\t: $state"
|
||||
|
||||
if [ $state == 'd' ]; then
|
||||
sudo ethtool -s "$iface" wol gu || true
|
||||
sudo mkdir -p /etc/networkd-dispatcher/configuring.d
|
||||
sudo tee /etc/networkd-dispatcher/configuring.d/wol <<EOF >/dev/null
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ethtool -s $iface wol gu || true
|
||||
EOF
|
||||
sudo chmod 755 /etc/networkd-dispatcher/configuring.d/wol
|
||||
print "* New WOL state\t: $(state)"
|
||||
fi
|
||||
|
||||
print "\nTo wake up this device run this command from another one:\n"
|
||||
print "\twakeonlan -p 8 $mac\n"
|
||||
print "\twol $mac\n"
|
||||
|
||||
49
tools/upgrade-ubuntu.sh
Executable file
49
tools/upgrade-ubuntu.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# https://dev.to/chefgs/upgrading-an-end-of-life-eol-ubuntu-os-to-lts-version-3a36
|
||||
# https://changelogs.ubuntu.com/meta-release
|
||||
|
||||
installed() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# sudo software-properties-qt (переключиться с LTS на нормальные релизы)
|
||||
# sudo aptitude install update-manager-core update-manager
|
||||
# sudo apt upgrade --autoremove -y
|
||||
# installed pkcon && sudo pkcon update --autoremove -y
|
||||
# sudo apt dist-upgrade
|
||||
# sudo apt install update-manager-core
|
||||
# sudo do-release-upgrade -p
|
||||
|
||||
source /etc/os-release
|
||||
|
||||
echo "Loading..."
|
||||
|
||||
IFS=$'\n' codenames=($(curl -s https://changelogs.ubuntu.com/meta-release | grep -xP "^Dist:\s[\w]+$" | sed "s/Dist: //" ))
|
||||
thisCodename="$VERSION_CODENAME"
|
||||
for idx in "${!codenames[@]}"; do
|
||||
if [ "${codenames[idx]}" = "$thisCodename" ]; then
|
||||
nextCodename=${codenames[((idx+1))]}
|
||||
fi
|
||||
done
|
||||
|
||||
targetDownloadPath="`pwd`/upgrade-$nextCodename"
|
||||
targetToolPath="$targetDownloadPath/unpacked"
|
||||
targetToolFile="$targetDownloadPath/$nextCodename.tar.gz"
|
||||
|
||||
echo "Current dist: $thisCodename"
|
||||
echo "Next dist: $nextCodename"
|
||||
echo "Target path: $targetToolFile"
|
||||
|
||||
rm -rf "$targetToolPath"
|
||||
mkdir -p "$targetToolPath"
|
||||
|
||||
echo "Downloading..."
|
||||
cd "$targetDownloadPath"
|
||||
wget "http://archive.ubuntu.com/ubuntu/dists/${nextCodename}-updates/main/dist-upgrader-all/current/${nextCodename}.tar.gz"
|
||||
|
||||
echo "Unpacking..."
|
||||
tar -xaf "$targetToolFile" -C "$targetToolPath"
|
||||
|
||||
echo "Starting..."
|
||||
cd unpacked
|
||||
sudo ./$nextCodename
|
||||
82
tools/vscode-ext.sh
Normal file
82
tools/vscode-ext.sh
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
exts=(
|
||||
'af4jm.vscode-m3u'
|
||||
'ahmadalli.vscode-nginx-conf'
|
||||
'akamud.vscode-theme-onedark'
|
||||
'anweber.statusbar-commands'
|
||||
'baincd.mini-command-palettes'
|
||||
'bmewburn.vscode-intelephense-client'
|
||||
'codezombiech.gitignore'
|
||||
'cweijan.vscode-redis-client'
|
||||
'darkriszty.markdown-table-prettify'
|
||||
'davidmarek.jsonpath-extract'
|
||||
'deitry.apt-source-list-syntax'
|
||||
'devsense.composer-php-vscode'
|
||||
'devsense.intelli-php-vscode'
|
||||
'devsense.phptools-vscode'
|
||||
'devsense.profiler-php-vscode'
|
||||
'dotjoshjohnson.xml'
|
||||
'dunstontc.vscode-go-syntax'
|
||||
'dustypomerleau.rust-syntax'
|
||||
'eamodio.gitlens'
|
||||
'editorconfig.editorconfig'
|
||||
'esbenp.prettier-vscode'
|
||||
'furkanozalp.go-syntax'
|
||||
'gigacode.gigacode-vscode'
|
||||
'golang.go'
|
||||
'grapecity.gc-excelviewer'
|
||||
'humao.rest-client'
|
||||
'irongeek.vscode-env'
|
||||
'jebbs.plantuml'
|
||||
'jeff-hykin.better-go-syntax'
|
||||
'jeppeandersen.vscode-kafka'
|
||||
'jflbr.jwt-decoder'
|
||||
'jinsihou.diff-tool'
|
||||
'jtr.vscode-position'
|
||||
'kenhowardpdx.vscode-gist'
|
||||
'leavesster.jsonpath'
|
||||
'mads-hartmann.bash-ide-vscode'
|
||||
'mamoru.vscode-fish-text'
|
||||
'mechatroner.rainbow-csv'
|
||||
'mehedidracula.php-namespace-resolver'
|
||||
'mhutchie.git-graph'
|
||||
'mrmlnc.vscode-apache'
|
||||
'ms-azuretools.vscode-docker'
|
||||
'ms-ceintl.vscode-language-pack-ru'
|
||||
'ms-vscode.hexeditor'
|
||||
'ms-vscode.makefile-tools'
|
||||
'neilbrayfield.php-docblocker'
|
||||
'neonxp.gotools'
|
||||
'nickdemayo.vscode-json-editor'
|
||||
'nico-castell.linux-desktop-file'
|
||||
'open-rpc.open-rpc'
|
||||
'pejmannikram.vscode-auto-scroll'
|
||||
'pkief.material-icon-theme'
|
||||
'qcz.text-power-tools'
|
||||
'rogalmic.bash-debug'
|
||||
'rust-lang.rust-analyzer'
|
||||
'ryu1kn.partial-diff'
|
||||
'srmeyers.git-prefix'
|
||||
'sumneko.lua'
|
||||
'syler.ignore'
|
||||
'takumii.markdowntable'
|
||||
'tamasfe.even-better-toml'
|
||||
'tyriar.lorem-ipsum'
|
||||
'vitorsalgado.vscode-redis'
|
||||
'waderyan.gitblame'
|
||||
'wayou.vscode-todo-highlight'
|
||||
'weijunyu.vscode-json-path'
|
||||
'xdebug.php-debug'
|
||||
'yinfei.luahelper'
|
||||
'yog.yog-plantuml-highlight'
|
||||
'yves.schema-tree'
|
||||
'yzane.markdown-pdf'
|
||||
'yzhang.markdown-all-in-one'
|
||||
'zgm.cuesheet'
|
||||
'zh9528.file-size'
|
||||
'zobo.php-intellisense'
|
||||
)
|
||||
|
||||
for ext in "$exts[@]"; do
|
||||
code --install-extension $ext
|
||||
done
|
||||
0
tools/ytdlcue.sh
Executable file → Normal file
0
tools/ytdlcue.sh
Executable file → Normal file
Reference in New Issue
Block a user