├── .gitignore ├── aac2ac3 ├── amdcccle-su ├── apt-tree ├── arguments ├── askubuntu-package ├── ati-info ├── backup-data ├── backup-home ├── backup-system ├── boinc-manager ├── cksum16 ├── clearsign ├── cloud-copy-update ├── cp-deep ├── cpf ├── dd-status ├── debextract ├── dwww-man ├── environment ├── geoip ├── hdinfo ├── home ├── README.md ├── bash-completion │ ├── .gitignore │ ├── bash-completion.txt │ ├── bash_completion │ ├── bash_completion.d │ │ ├── README │ │ ├── askubuntu │ │ └── dwww-man │ └── install.sh ├── bash_aliases ├── bash_aliases_min ├── bash_aliases_root ├── bash_aliases_server ├── bashrc ├── data │ └── gtksourceview-3.0 │ │ └── language-specs │ │ ├── apache.lang │ │ ├── groff.lang │ │ └── nginx.lang ├── git │ ├── config │ └── templates │ │ ├── HEAD │ │ ├── README.md │ │ ├── hooks │ │ └── pre-commit │ │ └── info │ │ └── exclude ├── install-bash_aliases.sh ├── min_to_root.sh ├── profile ├── pythonrc.py └── startup ├── hostlist ├── iso2ps2 ├── kernel-remove-old ├── matchsubtitles ├── md5sumdir ├── meld-bin ├── monitor-rotate ├── monitor-switch ├── multibootusb ├── nautilus-scripts ├── .gitignore ├── Arguments ├── Folder Usage ├── Folder md5sum ├── Open as Text ├── Search for files ├── install.sh ├── lib │ └── open_as.py ├── ⟹ Compare │ ├── .icon-name │ ├── Binaries │ ├── Images │ └── With Meld ├── ⟹ Emulator │ └── .icon-name ├── ⟹ Format │ ├── JSON (in-place) │ └── JSON (in-place, sorted) └── ⟹ Subtitles │ ├── 3D Subtitle - Side-by-Side │ ├── 3D Subtitle - Top-and-Bottom │ ├── Compare │ └── Match ├── newscript ├── ntfs-fix-colon ├── ntfsuuid ├── pencheck ├── powerstats ├── reference ├── Makefile ├── Makefiles ├── QuineRelay.rb ├── apt-get ├── checkboxes ├── commonlib ├── devtools-version-check ├── edid.txt ├── formatter.py ├── hostlist-mac ├── interactive ├── lfs-host ├── monitor-names ├── multibootusb.sh ├── parallel ├── polyglot ├── randspeed ├── repeat.py ├── select ├── template ├── udisks.py ├── wrapper └── wrapper-python3 ├── rename-user ├── spacechem-zipsave ├── ssd-writes ├── subtitle-shift ├── swap-fix ├── unicode-decode ├── unicode-encode ├── usb-power ├── whatsapp ├── whatsapp.desktop └── whatsapp.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Intentionally blank, for now. 2 | # For personal excludes, like IDE settings, use .git/info/exclude 3 | # See home/git/templates/info/exclude 4 | -------------------------------------------------------------------------------- /aac2ac3: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | infile=$1 4 | 5 | filename=${infile##*/} 6 | filepath=${infile%"$filename"} 7 | filetitle=${filename%.*} 8 | fileext=${filename#"$filetitle"} 9 | 10 | outfile=${filepath}${filetitle}-aac2ac3.mkv #${fileext} 11 | 12 | myname="${0##*/}" 13 | fatal() { [[ "$1" ]] && echo "$1" >&2 ; exit ${2:-1} ; } 14 | 15 | # Check if external tools are present 16 | if type avconv >/dev/null 2>&1; then 17 | conv=avconv 18 | elif type ffmpeg >/dev/null 2>&1; then 19 | conv=ffmpeg 20 | else 21 | fatal "Neither avconv nor ffmpeg were found. Either one is required." 22 | fi 23 | 24 | 25 | $conv -i "$infile" \ 26 | -codec copy -codec:a ac3_fixed -b:a 448k "$outfile" 27 | 28 | 29 | exit 30 | 31 | 32 | # How to De-noise a recording 33 | # default (ratio=0.5) 34 | sox $input -n trim 0 $time noiseprof | sox $input $output noisered 35 | # custom "ratio" 36 | sox $input -n trim 0 $time noiseprof $tmp 37 | sox -n trim 0 $time noiseprof | sox $input noisered 38 | sox $input $output noisered $tmp $ratio # ratio = [0-1] 39 | 40 | # Concatenating several wavs to create a multichannel 41 | sox --combine merge L.wav R.wav C.wav SL.wav SR.wav surround.wav 42 | sox --combine mix f1.wav "|sox f2.wav -p pad 4" "|sox f3.wav -p pad 8" out.wav 43 | 44 | 45 | # Approach 1 46 | #http://forum.xbmc.org/showthread.php?tid=62652 47 | 48 | # extract the specified track 49 | #mkvextract tracks "$INPUT" $TRACK:"$WORKDIR/AAC2AC3Temp.aac" 50 | 51 | # faad outputs a raw 24 bit PCM stream (anything higher than 24 bits seems to 52 | # introduce anomalies) which is then piped to aften and converted to a 640 kbit/s 53 | # AC3 stream (640 kbit/s is max allowed and yields highest possible quality) 54 | #faad -b 2 -f 2 -q -w "$WORKDIR/AAC2AC3Temp.aac" | 55 | #aften -v 1 -b 640 -raw_fmt s24_le -raw_sr $RATE -raw_ch $CHANNELS -chmap 0 -lfe 1 - "$WORKDIR/AAC2AC3Temp.ac3" 56 | 57 | #mkvmerge -o "$OUTPUT" "$INPUT" "$WORKDIR/AAC2AC3Temp.ac3" 58 | #mkvmerge -o "$OUTPUT" -A "$INPUT" "$WORKDIR/AAC2AC3Temp.ac3" 59 | 60 | ########################## 61 | 62 | # Approach 2 63 | 64 | #To create a multichannel .ac3 you need to create first a multichannel wav. 65 | #Of course sox comes very handy: 66 | 67 | #sox -M L.wav R.wav C.wav SL.wav SR.wav surround.wav 68 | 69 | # And now the ac3 encoding 70 | 71 | #aften -b 448 -cmix 0 -smix 0 -dsur 2 -acmod 7 surround.wav surround.ac3 72 | 73 | #-b 448 — Bitrate in kbps (4 channels: 384 kbps, 5 channels: 448 kbps) 74 | #-smix 2 — Surround mix level ( 0: -3dB, 1: -6dB, 2: 0 ) 75 | #-dsur 2 — (2: Dolby surround encoded, 0: not indicated, 1: not Dolby surround encoded) 76 | #-acmod 7 — Audio coding mode, or channel order (7: L,R,C,SL,SR) 77 | 78 | #sox -m f1.wav "|sox f2.wav -p pad 4" "|sox f3.wav -p pad 8" out.wav 79 | 80 | 81 | # My version 82 | #mkvmerge --identify-verbose "$infile" 83 | #File '': container: QuickTime/MP4 84 | #Track ID 1: video (avc1) 85 | #Track ID 2: audio (mp4a) 86 | #Track ID 2: audio (A_AAC) 87 | 88 | #mvkextract tracks "$infile" "$id":"$tmpfile" 89 | -------------------------------------------------------------------------------- /amdcccle-su: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pkexec /usr/bin/amdcccle "$@" 3 | -------------------------------------------------------------------------------- /apt-tree: -------------------------------------------------------------------------------- 1 | #!/bin/bash -u 2 | # 3 | # Show package dependency tree 4 | # Inspired by https://gist.github.com/damphat/6214499 5 | # 6 | # Copyright (C) 2021 Rodrigo Silva (MestreLion) 7 | # License: GPLv3 or later, at your choice. See 8 | #------------------------------------------------------------------------------ 9 | 10 | usage() { 11 | if [[ "${1:-}" ]]; then exec >&2; fi 12 | cat <<-USAGE 13 | Usage: $myname [options] PACKAGE 14 | USAGE 15 | if [[ "${1:-}" ]] ; then 16 | cat <<- USAGE 17 | Try '$myname --help' for more information. 18 | USAGE 19 | exit 1 20 | fi 21 | cat <<-USAGE 22 | 23 | Show package dependency tree 24 | 25 | Options: 26 | -h|--help - show this page. 27 | 28 | Other options are passed to 'apt-rdepends', for example: 29 | -r|--reverse - show packages that depend on the specified one 30 | 31 | Suggested bash-completion: 32 | complete -F _comp_pkg_names apt-tree 33 | USAGE 34 | exit 0 35 | } 36 | 37 | exists() { type "$@" >/dev/null 2>&1; } 38 | argerr() { printf "%s: %s\n" "$myname" "${1:-error}" >&2; usage 1; } 39 | invalid() { argerr "invalid ${2:-option}: ${1:-}"; } 40 | missing() { argerr "missing ${1:+$1 }argument${2:+ from $2}."; } 41 | 42 | #------------------------------------------------------------------------------ 43 | 44 | myname=${0##*/} 45 | opts=() 46 | args=() 47 | package= 48 | 49 | # Pre-parse for -h|--help, ignoring if after '--' 50 | for arg in "$@"; do 51 | if [[ "$arg" == '--' ]]; then break; fi 52 | if [[ "$arg" == "-h" || "$arg" == "--help" ]]; then usage; fi 53 | done 54 | while (($#)); do 55 | case "$1" in 56 | -*) opts+=( "$1" );; 57 | * ) args+=( "$1" );; 58 | --) shift; break;; 59 | esac 60 | shift || break 61 | done 62 | args+=("$@") 63 | case ${#args[@]} in 64 | 0) missing PACKAGE;; 65 | 1) package=${args[0]}; if [[ -z "$package" ]]; then missing PACKAGE; fi;; 66 | *) invalid "${args[1]}" argument;; 67 | esac 68 | 69 | #------------------------------------------------------------------------------ 70 | 71 | if ! exists apt-rdepends; then 72 | echo "Installing pre-requisite apt-rdepends" 73 | sudo apt install apt-rdepends # not the same output as `apt rdepends`! 74 | fi 75 | 76 | #------------------------------------------------------------------------------ 77 | 78 | declare -gA dep=() 79 | declare -gA num=() 80 | pkgs=: 81 | 82 | parse_deps() { 83 | local root=$1 84 | local pkg 85 | local category name version 86 | while read category name version; do 87 | if [[ "$category" == "P" ]]; then 88 | pkg=$name 89 | dep["$pkg"]="" 90 | num["$pkg"]=0 91 | else 92 | dep["$pkg"]="${dep["$pkg"]} ${name}" 93 | num["$pkg"]=$((${num["$pkg"]} + 1)) 94 | fi 95 | done < <( 96 | apt-rdepends "${opts[@]}" "$root" | 97 | # mark 'P' for package, 'D' for dependency 98 | sed -E 's/^/P\t/; s/^P?\t? +[^:]+: /D\t/; s/ \(([^)]+)\)/\t\1/' 99 | ) 100 | walk_deps "$root" 101 | } 102 | 103 | walk_deps() { 104 | local root=$1 105 | local level=${2:-0} 106 | local last=${3:-0} 107 | local prefix=${4:-} 108 | local T1= T2= 109 | local pkg 110 | local i=0 111 | 112 | # mark packages already printed to avoid circular dependencies 113 | local dupe=; if [[ "$pkgs" == *:${root}:* ]]; then dupe=*; fi 114 | 115 | if ((level++)); then 116 | T1=' │ '; if ((last)); then T1=' '; fi 117 | T2=' ├─ '; if ((last)); then T2=' ╰─ '; fi 118 | fi 119 | echo "${prefix}${T2}${root}${dupe}" 120 | 121 | # Do not print children of duplicates, otherwise add it to the "list" 122 | if [[ "$dupe" ]]; then return; fi 123 | 124 | pkgs=${pkgs}${root}: 125 | prefix="${prefix}${T1}" 126 | for pkg in ${dep[$root]:1}; do 127 | walk_deps "$pkg" $level $((++i == num[$root])) "$prefix" 128 | done 129 | } 130 | 131 | parse_deps "$package" 132 | -------------------------------------------------------------------------------- /arguments: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Print all command line arguments. If used in GUI, also prints relevant 4 | # Nautilus Scripts vars and uses zenity for output 5 | 6 | # Use -v var1 [var2...] to inspect shell/env variables 7 | 8 | var=0 9 | 10 | get_var() { 11 | { declare -p $1 2>/dev/null || echo "declare - $1: not set" ; } | 12 | awk '/^declare/{$1="";$2=sprintf("%-3s",substr($2,2))}1' 13 | } 14 | 15 | i=0 16 | while [ $# -gt 0 ]; do 17 | ((i++)) 18 | output+="\$$i=$1\n" 19 | ((var)) && vars+="$(get_var "$1")\n" 20 | case "$1" in -v) var=1 ;; esac 21 | shift 22 | done 23 | 24 | output+="$vars" 25 | 26 | if [[ "$TERM" == "dumb" ]] ; then 27 | if [[ "$output" ]]; then output+="\n"; fi 28 | output+="PWD\n$PWD\n\n" 29 | output+="NAUTILUS_SCRIPT_CURRENT_URI\n${NAUTILUS_SCRIPT_CURRENT_URI:+$NAUTILUS_SCRIPT_CURRENT_URI\n\n}" 30 | output+="NAUTILUS_SCRIPT_SELECTED_URIS\n${NAUTILUS_SCRIPT_SELECTED_URIS:+$NAUTILUS_SCRIPT_SELECTED_URIS\n}" 31 | output+="NAUTILUS_SCRIPT_SELECTED_FILE_PATHS\n${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS:+$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS\n}" 32 | msg=$output 33 | msg="${msg//&/&}" 34 | msg="${msg// 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. See 19 | 20 | myname="${0##*/}" 21 | 22 | usage() { 23 | cat <<-USAGE 24 | Usage: $myname [options] 25 | USAGE 26 | if [[ "$1" ]] ; then 27 | cat >&2 <<- USAGE 28 | Try '$myname --help' for more information. 29 | USAGE 30 | exit 1 31 | fi 32 | cat <<-USAGE 33 | 34 | Displays useful information for ATI/AMD video adapters using fglrx. 35 | 36 | Information include current core and memory clocks, GPU load (usage), 37 | temperature and fan speed. 38 | 39 | Options: 40 | -h|--help - show this page. 41 | -v|--verbose - print detailed info 42 | 43 | Copyright (C) 2013 Rodrigo Silva (MestreLion) 44 | License: GPLv3 or later. See 45 | USAGE 46 | exit 0 47 | } 48 | 49 | # Option handling 50 | for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && usage ; done 51 | while (( $# )); do 52 | case "$1" in 53 | -v|--verbose ) verbose=1 ;; 54 | # --var=* ) var="${1#*=}" ;; 55 | # --var ) shift ; var="$1" ;; 56 | # -- ) shift ; break ;; 57 | # -* ) invalid "$1" ;; 58 | # -* ) opts+=( "$1" ) ;; 59 | # * ) opterr "$1" ;; 60 | esac 61 | shift 62 | done 63 | 64 | # if not for formatting, the whole info could be displayed in a single command: 65 | #aticonfig --odgc --odgt --pplib-cmd "get fanspeed 0" --pplib-cmd "get faninfo 0" 66 | 67 | gputemp=$(aticonfig --odgt | awk -F ' - ' '/Temperature/{print $2}') 68 | fanspeed=$(aticonfig --pplib-cmd "get fanspeed 0" | awk -F ': |%' '/^Result:/{print $3}') 69 | fanmaxrpm=$(aticonfig --pplib-cmd "get faninfo 0" | awk -F '0 - | RPM' '{print $2}') 70 | fanrpm=$((fanmaxrpm * fanspeed / 100)) 71 | odgc=$(aticonfig --odgc) 72 | 73 | 74 | if [[ "$verbose" ]]; then 75 | echo "$odgc" 76 | echo " Fan speed : ${fanspeed}% (${fanrpm}/${fanmaxrpm} RPM)" 77 | else 78 | awk -F ' - | : ' 'NR==2{print $2} /load/{print}' <<< "$odgc" 79 | echo " Fan speed : ${fanspeed}%, ${fanrpm} RPM" 80 | fi 81 | echo " Temperature : ${gputemp}" 82 | 83 | exit 84 | 85 | # for the future... 86 | while true; do 87 | 88 | temp=${gputemp%%.*} # "convert" to integer 89 | 90 | if ((temp <= 40)); then speed=15 91 | elif ((temp <= 45)); then speed=25 92 | elif ((temp <= 50)); then speed=35 93 | elif ((temp <= 55)); then speed=45 94 | elif ((temp <= 60)); then speed=55 95 | elif ((temp <= 65)); then speed=65 96 | elif ((temp <= 70)); then speed=75 97 | elif ((temp <= 75)); then speed=85 98 | else speed=100 99 | fi 100 | 101 | echo 'aticonfig --pplib-cmd "set fanspeed 0 $speed"' 102 | 103 | break 104 | sleep 60 105 | done 106 | -------------------------------------------------------------------------------- /backup-data: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # backup-data - back up data partitions using borg-backup 4 | # 5 | # Copyright (C) 2024 Rodrigo Silva (MestreLion) 6 | # License: GPLv3 or later, at your choice. See 7 | #------------------------------------------------------------------------------ 8 | set -Eeuo pipefail # Exit on most errors. 9 | trap '>&2 echo "error: line $LINENO, status $?: $BASH_COMMAND"' ERR 10 | # See https://fvue.nl/wiki/Bash:_Error_handling for caveats 11 | #------------------------------------------------------------------------------ 12 | 13 | # HINT: To initialize a borg repository: `borg init "$BORG_REPO" -e repokey` 14 | # HINT: To aid fix path encoding in data partitions converted from NTFS to EXT4: 15 | # convmv -r -f cp1252 -t utf8 "$source" && 16 | # convmv -r -t cp1252 -f utf8 --fixdouble "$source" 17 | # -r: recursive 18 | # -f cp1252 / -t utf8: encoding FROM and TO 19 | # --fixdouble: fix "UTF-8 encoded in CP1252" 20 | 21 | # TODO: 22 | # - Consider -x | --one-file-system 23 | # - Consider cd to _source_ instead of _repo_ 24 | 25 | 26 | # Config file location 27 | config=${XDG_CONFIG_HOME:-$HOME/.config}/backup-data.conf 28 | 29 | # Config arrays 30 | declare -a options=( 31 | --progress 32 | --stats 33 | ) 34 | declare -a excludes=( 35 | 'lost+found' 36 | '.Trash*' 37 | ) 38 | 39 | # Default archive name 40 | default_archive='.::{now}' 41 | 42 | #------------------------------------------------------------------------------ 43 | 44 | self="${0##*/}" 45 | 46 | fatal() { if (($#)); then echo "$@" >&2; usage 1 >&2; fi; } 47 | usage() { echo "Usage: ${self} [SOURCE_DIR [REPO_DIR [PASSWORD]]]"; exit ${1:-0}; } 48 | exists() { type "$@" >/dev/null 2>&1; } 49 | escape() { printf '%q' "$1"; } 50 | 51 | 52 | #------------------------------------------------------------------------------ 53 | 54 | if ! exists borg; then 55 | sudo apt-get install borg 56 | fi 57 | 58 | if ! [[ -f "$config" ]]; then 59 | cat > "$config" <<-EOF 60 | # backup-data config file 61 | # Sourced by bash, mind the syntax! 62 | 63 | # Full path of directory to backup. 64 | # Mandatory, but can also be set on each run by command line argument 1. 65 | source= 66 | 67 | # Full path to backup repository (destination directory). 68 | # Mandatory, but can also be set by envvar BORG_REPO or command-line argument 2. 69 | # Will be the current directory during 'borg create' execution 70 | repository= 71 | 72 | # Repository password, if any. 73 | # Can also be set by envvar BORG_PASSPHRASE or command-line argument 3. 74 | # Leaving this blank in a password-protected repositoy will prevent 75 | # non-interactive use, as borg will prompt for one. 76 | password= 77 | 78 | # Archive name. If empty will use '$default_archive' by default. 79 | archive= 80 | 81 | # Directory or device to auto-mount, usually containing the backup repository. 82 | # May require an entry on /etc/fstab for the device, usually with options set 83 | # as 'defaults,user,noauto'. 84 | mount= 85 | 86 | # If the above mount requires sudo or not. 0 = no, 1 = yes. 87 | sudo_mount=1 88 | 89 | # 'borg create' extra options. 90 | # Must be a Bash array, and the following is already included by default: 91 | # ${options[@]} 92 | # (change '+=' to '=' in the assignment below to remove default options) 93 | options=( 94 | ) 95 | 96 | # Extra paths to exclude from backup. Each entry will be prepended with 97 | # '--exclude ' and included to 'borg create' options. 98 | # Since Borg 1.2.3, all paths must be relative to source directory, so 99 | # do NOT use leading slashes! 100 | # Must be a bash array, and the following is already excluded by default: 101 | # ${excludes[@]} 102 | # (change '+=' to '=' in the assignment below to remove default excludes) 103 | excludes+=( 104 | ) 105 | EOF 106 | echo "warning: config file not found, blank one created at: $config" >&2 107 | if [[ -t 1 ]]; then 108 | editor "$config" 109 | else 110 | echo "edit it and try again" >&2 111 | exit 1 112 | fi 113 | fi 114 | 115 | source "$config" || fatal "could not read config file: $config" 116 | 117 | # FIXME: env var should take priority over config file. Currently it overrides it. 118 | source=${source:-${1:-}} 119 | export BORG_REPO=${2:-${BORG_REPO:-${repository:-}}} 120 | export BORG_PASSPHRASE=${3:-${BORG_PASSPHRASE:-${password:-}}} 121 | 122 | [[ "$source" ]] || fatal "source directory not set" 123 | [[ "$BORG_REPO" ]] || fatal "backup repository path not set" 124 | 125 | archive=${archive:-$default_archive} 126 | mount=${mount:-} 127 | sudo_mount=${sudo_mount:-1} 128 | 129 | for exclude in "${excludes[@]}"; do 130 | options+=(--exclude "$exclude") 131 | done 132 | 133 | # FIXME: maybe test [[ -d "$BORG_REPO" ]] instead of [[ -d "$mount" ]]? 134 | # Afterall, no mount needed if target dir is already accessible 135 | # FIXME: Add a flag if a mount was performed, and conditionally unmount it after backup 136 | if [[ "$mount" ]] && ! [[ -d "$mount" ]]; then 137 | if ((sudo_mount)); then sudo=sudo; else sudo=env; fi 138 | $sudo mount "$mount" 139 | fi 140 | 141 | # borg exits with code 1 on mere warnings (file permissions), 2 for actual errors 142 | cd "$BORG_REPO" && 143 | borg create "${options[@]}" "$archive" "${source%/}"/ || (( $? >= 2 )) 144 | -------------------------------------------------------------------------------- /backup-home: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # backup-home - back up home folder using rdiff-backup 4 | # 5 | # Copyright (C) 2019 Rodrigo Silva (MestreLion) 6 | # License: GPLv3 or later, at your choice. See 7 | #------------------------------------------------------------------------------ 8 | 9 | set -Eeuo pipefail # Exit on most errors. 10 | trap '>&2 echo "error: line $LINENO, status $?: $BASH_COMMAND"' ERR 11 | # See https://fvue.nl/wiki/Bash:_Error_handling for caveats 12 | 13 | # Factory default options, configurable by config file 14 | # See notes on default config file creation 15 | dest=${1:-} 16 | mount= 17 | sudo_mount=0 18 | excludes=( 19 | "$HOME"/.cache 20 | "$HOME"/.thumbnails 21 | "$HOME"/.local/share/Trash 22 | '**/.Trash-*' 23 | '**/*cache*/*' 24 | '**/Temp/*' 25 | '**/Temporary Internet Files/*' 26 | ) 27 | options=( 28 | --print-statistics 29 | # --verbosity 5 # default is 3, completely silent in a normal run 30 | --terminal-verbosity 5 # default is --verbosity level. 31 | --exclude-other-filesystems 32 | --exclude-special-files # Exclude all device files, fifo files, socket files, and symbolic links. 33 | --include-symbolic-links # Re-include symbolic links 34 | ) 35 | 36 | # Config file location 37 | config=${XDG_CONFIG_HOME:-$HOME/.config}/backup-home.conf 38 | 39 | myname="${0##*/}" 40 | 41 | fatal() { [[ "${1:-}" ]] && echo "$myname: error: $@" >&2 ; exit 1; } 42 | exists() { type "$@" >/dev/null 2>&1; } 43 | escape() { printf '%q' "$1"; } 44 | 45 | if ! exists rdiff-backup; then 46 | sudo apt install -y rdiff-backup 47 | fi 48 | 49 | if ! [[ -f "$config" ]]; then 50 | echo "warning: config file not found, creating blank one at $config" >&2 51 | cat > "$config" <<-EOF 52 | # backup-home config file 53 | # Sourced by bash, mind the syntax! 54 | 55 | # Full path to backup destination directory 56 | # Can also be set on each run by command line argument 57 | target=$(escape "$dest") 58 | 59 | # Mountpoint to auto-mount, usually backup destination dir or a parent 60 | # Usually requires an entry on /etc/fstab for the device, set to 'noauto' 61 | # Leave blank to disable automount 62 | mount= 63 | 64 | # If auto-mount and its mountpoint require sudo or not. 0 = no, 1 = yes 65 | sudo_mount=0 66 | 67 | # rdiff-backup general options 68 | # Must be a Bash array 69 | options=( 70 | --print-statistics 71 | --terminal-verbosity 5 72 | --exclude-special-files # Exclude all device files, fifo files, socket files, and symbolic links. 73 | --include-symbolic-links # Re-include symbolic links 74 | ) 75 | 76 | # Paths to exclude from backup. Each entry will be prepended with 77 | # '--exclude=' and included to rdiff-backup options 78 | # Must be a Bash array 79 | excludes=( 80 | "\$HOME"/.cache 81 | "\$HOME"/.thumbnails 82 | "\$HOME"/.local/share/Trash 83 | '**/.Trash-*' 84 | '**/*cache*/*' 85 | '**/Temp/*' 86 | '**/Temporary Internet Files/*' # Wine "bottles" 87 | ) 88 | 89 | EOF 90 | fi 91 | 92 | source "$config" || fatal "could not read config file $config" 93 | 94 | dest=${dest:-$target} 95 | [[ "$dest" ]] || fatal "backup destination directory not set" 96 | 97 | for exclude in "${excludes[@]}"; do 98 | options+=(--exclude="$exclude") 99 | done 100 | 101 | if [[ "$mount" ]]; then 102 | if ((sudo_mount)); then sudo=sudo; else sudo=env; fi 103 | $sudo mount "$mount" 104 | fi 105 | 106 | cd "$HOME" && 107 | rdiff-backup "${options[@]}" -- "$HOME" "$dest" 108 | -------------------------------------------------------------------------------- /backup-system: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # backup-system: Full system backup using rdiff-backup 4 | # 5 | # Copyright (C) 2022 Rodrigo Silva (MestreLion) 6 | # License: GPLv3 or later, at your choice. See 7 | # 8 | # Scheduling: 9 | # echo '@weekly root /path/to/this 2>> /var/log/backup-system.stderr.log' | 10 | # sudo tee /etc/cron.d/backup-system 11 | # 12 | # When using sudo must use full path to this. 13 | # If running in an (user) shell: sudo "$(type -p backup-system)" 14 | # 15 | # Alternatives: 16 | # Simple, single-dir backup: 17 | # source=/media/"$USER"/a 18 | # target=/media/"$USER"/b 19 | # rsync -a --info=progress2 --no-inc-recursive "${source%\/}"/ "${target%\/}"/ 20 | # tar backup: 21 | # cd "$source" && sudo tar --one-file-system -cvpzf "$target"/backup.tar.xz 22 | # Mirror: 23 | # sudo rsync -axS --info=progress2 --no-inc-recursive --delete "${source%\/}"/ "${target%\/}"/ 24 | # 25 | # To allow user inspection / monitoring: 26 | # sudo chmod +rx "$target"{,/rdiff-backup-data{,/backup.log}} && 27 | # sudo chmod +r "$target"/rdiff-backup-data/backup.log 28 | # ------------------------------------------------------------------------------ 29 | 30 | system=$(lsb_release -sir | tr -d '.\n') 31 | myself=${0##*/} 32 | 33 | source=/ 34 | target=/backup/${system,,} 35 | 36 | # rdiff-backup verbosity levels: 37 | # 3 - completely silent in a normal run 38 | # 4 - info on start and end, no actual on-going progress 39 | # 5 - all info from 4 plus one file per line progress 40 | # If (log) --verbosity is 5, you can monitor log even if --terminal-verbosity is 3: 41 | # tail -f "$target"/rdiff-backup-data/backup.log 42 | 43 | options=( 44 | --verbosity 5 # default is 3, completely silent in a normal run 45 | --terminal-verbosity 3 # default is --verbosity level. 46 | --include-symbolic-links # would be excluded by --exclude-special-files 47 | --exclude-special-files # Exclude all device files, fifo files, socket files, and symbolic links. 48 | --exclude-other-filesystems 49 | ) 50 | 51 | excludes=( 52 | '/dev/*' 53 | '/lost+found' 54 | '/media/*' # not really needed with --exclude-other-filesystems 55 | '/proc/*' 56 | '/run/*' 57 | '/sys/*' 58 | '/tmp/*' 59 | '/swapfile' 60 | 61 | # Users' homes (temporarily NOT backed up!) 62 | '/home/*' 63 | # '/home/*/.local/share/Trash/*' 64 | # '/home/*/.cache/*' 65 | # '/home/*/.thumbnails/*' # Not present in Ubuntu 22.04+ 66 | ) 67 | 68 | # to restore /swapfile: 69 | # sudo fallocate -l 1G /swapfile 70 | # sudo chmod 600 /swapfile 71 | # sudo mkswap /swapfile 72 | # sudo swapon /swapfile 73 | 74 | # ------------------------------------------------------------------------------ 75 | 76 | is_root() { [[ "$(id -u)" -eq 0 ]]; } 77 | fatal() { [[ "${1:-}" ]] && echo "$myself: error: $@" >&2 ; exit 1; } 78 | exists() { type "$@" >/dev/null 2>&1; } 79 | 80 | usage() { 81 | if [[ "${1:-}" ]] ; then exec >&2; fi 82 | cat <<-USAGE 83 | Usage: ${myself} [SOURCE] [TARGET] [extra-rdiff-options] 84 | USAGE 85 | if [[ "${1:-}" ]] ; then 86 | cat <<- USAGE 87 | Try '$myself --help' for more information. 88 | USAGE 89 | exit 1 90 | fi 91 | cat <<-USAGE 92 | 93 | Backup the root filesystem using rdiff-backup 94 | 95 | Excludes mounts and other filesystems. Must run as root. 96 | 97 | SOURCE defaults to: ${source} 98 | TARGET defaults to: ${target} 99 | 100 | Default excludes: 101 | ${excludes[@]} 102 | 103 | Copyright (C) 2022 Rodrigo Silva (MestreLion) 104 | License: GPLv3 or later. See 105 | USAGE 106 | exit 0 107 | } 108 | for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && usage; done 109 | 110 | source=${1:-$source} 111 | target=${2:-$target} 112 | shift 2 || true 113 | 114 | # ------------------------------------------------------------------------------ 115 | 116 | if ! is_root; then 117 | echo "Must run as root" >&2 118 | exit 1 119 | fi 120 | 121 | options+=( "$@" ) 122 | for exclude in "${excludes[@]}"; do 123 | options+=(--exclude="$exclude") 124 | done 125 | 126 | rdiff-backup "${options[@]}" -- "$source" "$target" 127 | -------------------------------------------------------------------------------- /boinc-manager: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # boinc-manager - wrapper for boincmgr to auto-start boinc and fix some issues 4 | # 5 | # Copyright (C) 2012 Rodrigo Silva (MestreLion) 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. See 19 | # 20 | # Workaround the annoying bug where boinc client daemon starts too soon in the 21 | # boot sequence, before GPU driver (or X, or DE) is active, causing boinc not 22 | # to find the GPU. 23 | # 24 | # Also fixes a Manager limitation of not starting the client daemon by itself. 25 | # 26 | # It is recommended to change the Manager launcher at 27 | # /usr/share/applications/boinc-manager.desktop to execute this script instead 28 | # of /usr/bin/boincmgr. Or, better yet, copy the .desktop file to 29 | # ~/.local/share/applications and edit it there. Use the following commands: 30 | # desktop="share/applications/boinc-manager.desktop" 31 | # sed '/^Exec=/s/=.*/=boinc-manager/' "/usr/$desktop" > "$HOME/.local/$desktop" 32 | 33 | boinc=/etc/init.d/boinc-client 34 | boincdir=/var/lib/boinc-client 35 | 36 | cd "$boincdir" 37 | 38 | if "$boinc" status | grep -q 'stopped$' || 39 | { boinccmd --get_messages | grep -qi "No usable GPUs found" && 40 | lsmod | grep -qi "fglrx" ; } 41 | then 42 | pkexec "$boinc" restart 43 | fi 44 | 45 | /usr/bin/boincmgr "$@" 46 | 47 | exit 48 | 49 | # For reference: a test for boinc restart to fix 'AMD GPU not found' bug 50 | boinc=/etc/init.d/boinc-client 51 | if [ -x "$boinc" ] && # init script exists and is enabled 52 | "$boinc" status | grep -qi ': running$' && # boinc client is running 53 | lsmod | grep -qi "fglrx" && # AMD/ATI proprietary driver is enabled 54 | boinccmd --get_messages | grep -qi "No usable GPUs found" ; # but GPU is not detected by boinc 55 | then 56 | pkexec "$boinc" restart 57 | fi 58 | -------------------------------------------------------------------------------- /cksum16: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Calculates the CRC-16 checksum of a string 4 | # like cksum does for CRC32 5 | # 6 | # Copyright (C) 2011 Rodrigo Silva (MestreLion) 7 | # License: GPLv3 or later, at your choice. See 8 | # 9 | # References: 10 | # 0x10 blog: 11 | # Wine's winemenubuilder: 12 | # The wise, friendly and helpful #bash gurus: 13 | # 14 | # NOTE: Newlines are properly handled, but last newline is stripped off 15 | # NOTE: NUL chars are stripped off before computing 16 | # TODO: Test how non-ASCI chars are handled 17 | # FIXME: Decent usage explaining options and behaviour 18 | 19 | self="${0##*/}" 20 | 21 | error() { 22 | local msg="$1" 23 | printf "%s: %s\nTry '%s --help' for more information\n" \ 24 | "$self" "$msg" "$self" >&2 25 | exit 1 26 | } 27 | usage() { 28 | printf "Print CRC-16 checksum (and optionally the byte count) of STRING\n\n" 29 | printf "Usage: %s [--hex|--dec|--format FORMAT] [--count] [STRING]\n\n" "$self" 30 | printf "Default format is decimal. If no string or -, reads from stdin\n" 31 | printf "NULs and last newline are ignored. Use for texts, not binary data.\n" 32 | exit 33 | } 34 | crc16() 35 | ( 36 | export LC_ALL=C 37 | 38 | local string="$1" 39 | local format="${2:-"%d"}" 40 | local crc=0 41 | local i j xor_poly 42 | 43 | for ((i=0; i<${#string}; i++)); do 44 | 45 | c=$(printf "%d" "'${string:i:1}") 46 | for ((j=0; j<8; c>>=1, j++)); do 47 | 48 | (( xor_poly = (c ^ crc) & 1 )) 49 | (( crc >>= 1 )) 50 | (( xor_poly )) && (( crc ^= 0xA001 )) 51 | 52 | done 53 | done 54 | printf "$format" "$crc" 55 | ) 56 | 57 | while [[ $# -gt 0 ]]; do 58 | arg="$1"; shift 59 | case "$arg" in 60 | -h|--help ) usage ;; 61 | -x|--hex ) format="%04X" ;; 62 | -d|--dec ) format="%d" ;; 63 | -f|--format) format="$1"; shift ;; 64 | -c|--count ) count=1 ;; 65 | -- ) string="$1" ; break ;; 66 | - ) string=$( cat ) ; done=1 ; break ;; 67 | -* ) error "unrecognized option '$arg'" ;; 68 | * ) string="$arg" ; done=1 ; break ;; 69 | esac 70 | done 71 | 72 | [[ "$done" || "$string" ]] || string=$( cat ) 73 | 74 | # Expected command-line behaviour table: 75 | # => str = stdin 76 | # - => str = stdin 77 | # something => str = something 78 | # -- => str = stdin 79 | # -- someth => str = something 80 | 81 | [[ "$string" ]] || error "missing string" 82 | 83 | crc16 "$string" "$format" 84 | [[ "$count" ]] && printf " %d" "${#string}" 85 | printf "\n" 86 | 87 | #Original function from winemenubuilder.c (for reference) 88 | #static unsigned short crc16(const char* string) 89 | #{ 90 | # unsigned short crc = 0; 91 | # int i, j, xor_poly; 92 | # 93 | # for (i = 0; string[i] != 0; i++) 94 | # { 95 | # char c = string[i]; 96 | # for (j = 0; j < 8; c >>= 1, j++) 97 | # { 98 | # xor_poly = (c ^ crc) & 1; 99 | # crc >>= 1; 100 | # if (xor_poly) 101 | # crc ^= 0xa001; 102 | # } 103 | # } 104 | # return crc; 105 | #} 106 | -------------------------------------------------------------------------------- /clearsign: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # clearsign - Signs a single file using GnuPG (gpg) 4 | # in clearsign mode (non-detached, ASCII-armored) 5 | # Uses zenity for GUI. Nautilus-scripts compatible. 6 | # 7 | # Copyright (C) 2011 Rodrigo Silva - 8 | # 9 | # This program is free software: you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation, either version 3 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | # 22 | # Huge thanks to all the gurus and friends in 23 | # and the contributors of 24 | # 25 | # Usage: clearsign FILE 26 | # 27 | # TODO: add more output options: 28 | # Detached binary (file.ext.sig) - "gpg --detach-sign" 29 | # Detached text (file.ext.asc) - "gpg --detach-sign --armor" 30 | # Non-Detached binary (file.ext.gpg) - "gpg --sign" 31 | # Non-Detached binary-to-text (file.ext.asc) - "gpg --sign --armor" 32 | # 33 | # TODO: add help, usage, verbose, debug, force, etc 34 | # TODO: test if zenity and gpg avaliable 35 | # TODO: allow multiple files and directories 36 | # TODO: update common lib and use it 37 | # TODO: read (and pre-select) default key from searhorse 38 | # TODO: use proper icon 39 | # FIXME: gnupg creates blank dir.asc if file is actually a dir 40 | 41 | 42 | # User input 43 | FILE="$1" # globs not allowed.. for now 44 | OUTPUT="${FILE}.asc" # user may only change if already exists 45 | 46 | # Constants 47 | SELF="${0##*/}" 48 | SELF_GUI="Sign file" 49 | WIDTH_MAX=790 50 | WIDTH_BASE=250 51 | WIDTH_UNIT=8 #char 52 | 53 | HEIGHT_MAX=600 54 | HEIGHT_BASE=130 55 | HEIGHT_UNIT=25 #line 56 | 57 | # Variables 58 | max_chars=0 59 | window_width=0 60 | window_height=0 61 | 62 | 63 | # Functions 64 | 65 | fatal() { : ; } 66 | 67 | fatalgui() 68 | { 69 | local message="$1" 70 | local errorcode="${2:-1}" 71 | local dump="$3" 72 | 73 | [[ -n "$dump" ]] && echo "$dump" >&2 74 | [[ -n "$message" ]] && echo "$SELF: ${message/%['!''.'':']/}" >&2 75 | 76 | zenity --error --title="$SELF_GUI" \ 77 | --text="${message:+$message\n\n}${dump:+$dump\n\n}" #"Exiting with error code ${errorcode}" 78 | 79 | exit $errorcode 80 | } 81 | 82 | min() { (( $1 < $2 )) && printf %d "$1" || printf %d "$2"; } 83 | max() { (( $1 > $2 )) && printf %d "$1" || printf %d "$2"; } 84 | 85 | 86 | # =========================================== MAIN 87 | 88 | # Check input file 89 | [[ -r "$FILE" ]] || fatalgui "File to sign is missing or is not readable." 90 | 91 | # Check more than 1 file 92 | [[ $# = 1 ]] || { 93 | zenity --question --title="Multiple files" \ 94 | --text="Multiple files were selected, but only this will be signed:\n\n${FILE}\n\nProceed?" \ 95 | || exit 0 96 | } 97 | 98 | # Grab the list of keys 99 | keys=$( 100 | gpg --list-keys --with-colons --keyid-format short 2>&1 101 | ) || fatalgui "Error when retrieving list of keys:" $? "$keys" 102 | 103 | # Empy array to hold the keys 104 | array=() 105 | 106 | # Loop the list 107 | while IFS=":" read -r -s keyType keyTrust keySize _ keyId keyDate _ _ _ keyUser _ keyFlags _ ; do 108 | 109 | # Check for (pub)lic keys that are able to (s)ign and are not (D)isabled 110 | if [[ "$keyType" = "pub" && "$keyFlags" = *s* && ! "$keyFlags" = *D* && "$keyTrust" = u ]] ; then 111 | 112 | # populate the array 113 | array+=("$keyId" "$keyUser" "${keyId:(-8)}" "$keyDate" "$keySize") 114 | 115 | # Save the number of chars of the longest user string 116 | (( ${#keyUser} > $max_chars )) && max_chars=${#keyUser} 117 | 118 | #DEBUG echo "$keyType|$keySize|${keyId:(-8)}|$keyDate|${#keyUser}|$max_chars|$keyUser" 119 | fi 120 | 121 | done <<< "$keys" 122 | 123 | # Check if suitable keys were found 124 | [[ ${#array[@]} = 0 ]] && fatalgui "No suitable keys for signing were found." 125 | 126 | # Set window height and weight 127 | window_width=$( min $WIDTH_MAX $(( $WIDTH_BASE + $WIDTH_UNIT * $max_chars )) ) 128 | window_height=$( min $HEIGHT_MAX $(($HEIGHT_BASE + $HEIGHT_UNIT * ${#array[@]}/5)) ) 129 | 130 | # Choose key 131 | key=$( 132 | zenity --list --title="Choose Signer" --text="Sign file as:" --hide-column=1 \ 133 | --width=$window_width --height=$window_height \ 134 | --window-icon="/usr/share/pixmaps/seahorse-plugins/22x22/seahorse-key.png" \ 135 | --column="id" --column="User" --column="Key" --column="Date" --column="Size" \ 136 | "${array[@]}" 137 | ) || exit 0 138 | 139 | 140 | # default output already exists? 141 | [[ -f "$OUTPUT" ]] && { 142 | 143 | # prompt for another output file 144 | OUTPUT=$( 145 | zenity --file-selection --save --filename="$OUTPUT" \ 146 | --window-icon="/usr/share/pixmaps/seahorse-plugins/22x22/seahorse-key.png" \ 147 | --title="Choose Signed File Name for ${FILE##*/}" \ 148 | --confirm-overwrite --file-filter "*.asc" 149 | ) || exit 0 150 | } 151 | 152 | 153 | # Do it! :D 154 | dump=$( 155 | gpg --clearsign --batch --yes --default-key="$key" --output="$OUTPUT" "$FILE" 2>&1 156 | ) || fatalgui "Error when signing $FILE:" $? "$dump" 157 | 158 | 159 | exit 0 160 | -------------------------------------------------------------------------------- /cloud-copy-update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # cloud-copy-update - update and clean up Copy.com mirror directory 4 | # 5 | # Copyright (C) 2014 Rodrigo Silva (MestreLion) 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. See 19 | # 20 | 21 | myname="${0##*/}" 22 | mydir=$(dirname "$(readlink -f "$0")") 23 | verbose=1 24 | greenC=$(tput setaf 2; tput bold) 25 | redC=$(tput setaf 1; tput bold) 26 | endC=$(tput sgr0) 27 | 28 | fatal() { [[ "$1" ]] && echo "$myname: error: $1" >&2 ; exit ${2:-1} ; } 29 | argerr() { printf "%s: %s\n" "$myname" "${1:-error}" >&2 ; usage 1 ; } 30 | invalid() { argerr "invalid option: $1" ; } 31 | message() { ((verbose)) && echo && echo && echo "${greenC}*** ${1}${endC}" ; } 32 | 33 | 34 | usage() { 35 | cat <<-USAGE 36 | Usage: $myname [options] 37 | USAGE 38 | if [[ "$1" ]] ; then 39 | cat >&2 <<- USAGE 40 | Try '$myname --help' for more information. 41 | USAGE 42 | exit 1 43 | fi 44 | cat <<-USAGE 45 | 46 | Update and clean up Copy.com online directory 47 | 48 | Options: 49 | -h|--help - show this page. 50 | -q|--quiet - do not print informative messages 51 | 52 | Copyright (C) 2014 Rodrigo Silva (MestreLion) 53 | License: GPLv3 or later. See 54 | USAGE 55 | exit 0 56 | } 57 | 58 | # Option handling 59 | files=() 60 | for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && usage ; done 61 | 62 | while (( $# )); do 63 | case "$1" in 64 | -q|--quiet ) verbose=0 ;; 65 | -* ) invalid "$1" ;; 66 | * ) argerr "$1" ;; 67 | esac 68 | shift 69 | done 70 | 71 | config=${XDG_CONFIG_HOME:-$HOME/.config}/$myname/$myname.conf 72 | 73 | { copydir=$(<"$config"); } 2>/dev/null 74 | 75 | if ! [[ -d "$copydir" ]]; then 76 | echo "Copy.com local directory location not found: '$copydir'" 77 | echo "Please check the config file at '$config'" 78 | exit 1 79 | fi 80 | 81 | message "Mirroring local dir" 82 | rsync -axSv --delete "$HOME"/.local/ "$copydir" 83 | 84 | message "Cleaning up the Trash" 85 | rm -rf "$copydir"/share/Trash 86 | 87 | #echo "Cleaning up wineprefixes" 88 | #for bottle in "$copydir"/share/wineprefixes/*; do 89 | # rm -f "$bottle"/dosdevices/* 90 | # for userdir in "$bottle"/drive_c/users/"$USER"/*; do 91 | # if [[ -h "$userdir" ]]; then 92 | # rm -f "$userdir" 93 | # fi 94 | # done 95 | #done 96 | 97 | message "Removing absolute dir symlinks" 98 | while read -r symlink; do 99 | target=$(readlink "$symlink") 100 | if [[ "${target:0:1}" == "/" ]]; then 101 | rm -fv "$symlink" 102 | fi 103 | done < <(find "$copydir" -type l -xtype d) 104 | 105 | 106 | message "Deleting broken symlinks" 107 | find -L "$copydir" -type l -delete 108 | -------------------------------------------------------------------------------- /cp-deep: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # cp-deep - Copy file from SOURCE(s) to DESTINATION, creating path if needed 4 | # 5 | # Copyright (C) 2011 Rodrigo Silva (MestreLion) 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | # Huge thanks to all the gurus and friends in irc://irc.freenet.org/#bash 21 | # and the contributors of http://mywiki.wooledge.org/ 22 | # Special thanks to dualbus, geirha and sn18. 23 | # 24 | # Description: 25 | # 26 | # cp-deep works like regular cp, copying files from SOURCE(S) to DESTINATION 27 | # But it also creates destination path if it does not exist - using mkdir 28 | # with --parent DEST - thus allowing copied files to be "deep" in the tree 29 | # 30 | # 31 | # USE WITH CAUTION! PAY ATTENTION TO TRAILLING "/" IN DEST!!! 32 | # 33 | # 34 | # Original cp allows optional use of trailing "/" in DEST, 35 | # as it checks if DEST is an existing dir to decide whether DEST means 36 | # "copy file to /foo/bar/" or "copy to /foo/ and rename file to bar" 37 | # 38 | # Since cpdeep allows DEST dir to be created, one must explicitly use 39 | # trailing "/" in DEST when dir is to be created and file not renamed. So: 40 | # 41 | # cp-deep file /foo/bar/ = create /foo/bar and copy file there = /foo/bar/file 42 | # cp-deep file /foo/bar = create /foo and copy file as bar = /foo/bar 43 | # 44 | # To avoid common errors, explicit use of trailing "/" is not needed when: 45 | # -SOURCE are multiple files (DEST assumed to be dir regardless of trailing /) 46 | # -DEST exists and is a dir = copy SOURCE there, do not rename 47 | # -DEST exists and is a file = copy SOURCE over DEST (SOURCE must be single file) 48 | # 49 | # So be sure to properly include or not trailling "/" when SOURCE is single file 50 | # and DEST does not exist 51 | 52 | (( $# >= 2 )) || { 53 | echo "${0##*/}: missing parameters. usage: ${0##*/} SOURCE... DEST" >&2 54 | exit 1 55 | } 56 | 57 | dest="${@:(-1)}" # Last argument 58 | 59 | # Special handling of DEST only needed when SOURCE is a single file 60 | # and there is at least one "/" in it. For same dir copies, no mkdir needed 61 | [[ $# = 2 ]] && { [[ "$dest" = */* ]] && dest="${dest%/*}/" || dest="" ; } 62 | 63 | [[ "$dest" ]] && { mkdir --parent -- "$dest" || exit ; } 64 | 65 | cp --no-preserve=mode,ownership "$@" 66 | -------------------------------------------------------------------------------- /cpf: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env php 2 | 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. See 19 | 20 | myname=${0##*/} 21 | block=1Mi 22 | size=0 23 | autosudo=1 24 | force=0 25 | eta=1 26 | 27 | 28 | fatal() { [[ "$1" ]] && echo "$myname: error: $@" >&2 ; exit 1; } 29 | message() { printf "%s\n" "$1"; } 30 | argerr() { printf "%s: %s\n" "$myname" "${1:-error}" >&2 ; usage 1; } 31 | invalid() { argerr "invalid option: $1" ; } 32 | missing() { argerr "missing ${2:+$2 }argument${1:+ from $1}." ; } 33 | sizefmt() { [[ "$1" ]] || missing "${3:-SIZE}" "${2:-}"; 34 | echo $(numfmt --from=auto -- "$1" || fatal); } 35 | 36 | usage() { 37 | cat <<-USAGE 38 | Usage: $myname [options] INPUT OUTPUT 39 | USAGE 40 | if [[ "$1" ]] ; then 41 | cat >&2 <<- USAGE 42 | Try '$myname --help' for more information. 43 | USAGE 44 | exit 1 45 | fi 46 | cat <<-USAGE 47 | 48 | dd wrapper with progress status 49 | 50 | Options: 51 | -h|--help - show this page. 52 | -f|--force - force operation even on mounted partitions 53 | -S|--no-sudo - do not use 'sudo' even if OUTPUT is not writable by user 54 | 55 | -s|--size SIZE - number of BYTES (*NOT* blocks!) to copy. 56 | 0 copies the whole input [Default: $size] 57 | -B|--block-size SIZE - copy SIZE blocks at a time. [Default: $block] 58 | 59 | All SIZE units are parsed through 'numfmt' auto mode, so SI suffixes such 60 | as K, M, G are allowed. '1K' means 1000; use 'Ki' (and 'Mi', 'Gi', etc) 61 | for 1024-based units. 62 | 63 | Copyright (C) 2013 Rodrigo Silva (MestreLion) 64 | License: GPLv3 or later. See 65 | USAGE 66 | exit 0 67 | } 68 | 69 | # Option handling 70 | files=() 71 | for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && usage ; done 72 | while (($#)); do 73 | case "$1" in 74 | -f|--force ) force=1;; 75 | -S|--no-sudo) autosudo=0;; 76 | -B|--block-size) shift; block=$1;; 77 | -s|--size ) shift; size=$1 ;; 78 | --block-size=*) block=${1#*=};; 79 | --size=* ) size=${1#*=} ;; 80 | --) shift; break;; 81 | -*) invalid "$1";; 82 | * ) files+=( "$1" );; 83 | esac 84 | shift || break 85 | done 86 | files+=( "$@" ) 87 | input=${files[0]} 88 | output=${files[1]} 89 | 90 | [[ "$input" ]] || missing "" "INPUT" 91 | [[ "$output" ]] || missing "" "OUTPUT" 92 | 93 | sudo=() 94 | if ((autosudo)) && [[ -e "$output" && ! -w "$output" ]]; then sudo=(sudo); fi 95 | 96 | size=$( sizefmt "$size" '--size' ) || exit 97 | block=$(sizefmt "$block" '--block-size') || exit 98 | 99 | if ! ((force)); then 100 | for file in "$input" "$output"; do 101 | if [[ -b "$file" ]] && grep -q "^$file" /proc/mounts; then 102 | fatal "$file seems to be (or contain) mounted partition(s)." \ 103 | "Un-mount it first or use --force." 104 | fi 105 | done 106 | fi 107 | 108 | args=(of="$output" bs="$block" oflag=nocache,sync) 109 | 110 | if !((eta)); then 111 | args+=(if="$input" status=progress) 112 | if ((size)); then 113 | args+=(iflag=count_bytes count="$size") 114 | fi 115 | cmd=("${sudo[@]}" dd "${args[@]}") 116 | echo "${cmd[@]}" >&2 117 | "${cmd[@]}" 118 | exit 119 | fi 120 | args+=(status=none) 121 | 122 | pvargs=(--buffer-size "$block") 123 | if ((size)); then 124 | pvargs+=(--size "$size" --stop-at-size) 125 | fi 126 | 127 | pvsudo=() 128 | if ((autosudo)) && [[ -e "$input" && ! -w "$input" ]]; then pvsudo=(sudo); fi 129 | 130 | echo "${pvsudo[@]}" pv "${pvargs[@]}" -- "$input" '|' "${sudo[@]}" dd "${args[@]}" 131 | "${pvsudo[@]}" pv "${pvargs[@]}" -- "$input" | "${sudo[@]}" dd "${args[@]}" 132 | -------------------------------------------------------------------------------- /debextract: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # debextract - Wrapper to "dpkg-deb -x" for multiple files 4 | # 5 | # Copyright (C) 2012 Rodrigo Silva (MestreLion) 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see 19 | # 20 | # Wrapper to extract multiple debian packages (*.deb). It automatically chooses 21 | # a destination directory based on the deb's filename and also extracts the 22 | # control information files (the DEBIAN directory inside the package) 23 | 24 | usage() { 25 | cat <<- USAGE 26 | Usage: $self [${main} options] [options] FILE... 27 | USAGE 28 | if [[ "$1" ]] ; then 29 | cat <<- USAGE 30 | Try '$self --help' for more information. 31 | USAGE 32 | exit 1 33 | fi 34 | cat <<-USAGE 35 | 36 | Extracts Debian Package files (.deb) to a directory matching their filenames 37 | 38 | Options: 39 | -h|--help - show this page. 40 | -v|--verbose - print more details about what is being done. Also enables 41 | verbosity for ${main}. Use -X/+X to enable or disable this 42 | -X|--vextract - turns ON verbosity for ${main}. Useful if -v is not set 43 | +X - turns OFF verbosity for ${main}. Useful if -v is set 44 | --destdir DIR - sets a directory for extraction of all packages. If ommited 45 | or blank, destination will be each package's current 46 | directory. In all cases, package filename will be appended 47 | to the final destination path. 48 | --nocontrol - do not extract the control files. (DEBIAN directory) 49 | --controldir DIR - set the destination directory for the control files, 50 | relative to the extracted package directory. Ignored if 51 | --nocontrol is set. Default is DEBIAN. 52 | --onerror ACTION - What to do if an error occur when executing $main for a 53 | given file. Valid ACTION values are: 54 | skip - skip error and continue with next file, if any 55 | quit - quit immediately, do not extract any further files 56 | ask - if not last file, ask user what to do. Default action 57 | Regardless of the action chosen, in case of any error 58 | $self will always exit with ${main}'s last unsucessfull 59 | exit code 60 | ${main} options: 61 | - see ${main} --help or man ${main} 62 | 63 | FILE... - package file(s) to extract, multiple files accepted 64 | 65 | The destination directory for extraction of each package will be the package 66 | filename without the .deb extension. Files other than *.deb will be 67 | silently ignored. 68 | 69 | Copyright (C) 2012 Rodrigo Silva (MestreLion) 70 | License: GPLv3 or later. See 71 | USAGE 72 | exit 0 73 | } 74 | 75 | opterror() { echo "$self: $1" ; usage 1 ; } 76 | missing() { opterror "missing ${1:+$1 }operand" ; } 77 | 78 | testaction() { 79 | [[ "$1" ]] || missing "action" 80 | actions=( skip quit ask ) 81 | for action in "${actions[@]}"; do [[ "$action" == "$1" ]] && return ; done 82 | opterror "invalid action '$1'. valid options are: ${actions[*]}" 83 | } 84 | 85 | handleerror() { 86 | code=$1 87 | (( verbose )) && echo "$self: error $code in $main" 88 | (( $2 > 1 )) || return 0 # Noting to handle if this is the last file 89 | case "$action" in 90 | skip) return 0 ;; 91 | quit) return 1 ;; 92 | ask ) 93 | local choice 94 | read -rp "(Q)uit, (S)kip, or Skip (A)ll ? " choice 95 | case "$choice" in 96 | [Aa]*) action="skip" ; return 0 ;; 97 | [Ss]*) return 0 ;; 98 | *) return 1 ;; # Educating users not to blindly hit Enter :) 99 | esac 100 | esac 101 | } 102 | 103 | declare -a opts=() 104 | self="${0##*/}" 105 | main="dpkg-deb" 106 | action="ask" 107 | destdir="" 108 | control=1 109 | controldir="DEBIAN" 110 | verbose=0 111 | dverb=0 112 | dquiet=0 113 | code=0 114 | ext="--extract" 115 | 116 | # Loop options 117 | while (( $# )); do 118 | case "$1" in 119 | -h|--help ) usage ;; 120 | -v|--verbose ) verbose=1 ;; 121 | -X|--vextract ) dverb=1 ;; 122 | +X ) dquiet=1 ;; 123 | -x|--extract ) ;; #I'm not so naive.Silently ignore 124 | --nocontrol ) control=0 ;; 125 | --controldir=*) controldir="${1#*=}" ;; 126 | --controldir ) shift ; controldir="$1" ;; 127 | --destdir=* ) destdir="${1#*=}" ;; 128 | --destdir ) shift ; destdir="$1" ;; 129 | --onerror=* ) testaction "${1#*=}" ;; 130 | --onerror ) shift ; testaction "$1" ;; 131 | -- ) shift ; break ;; 132 | -* ) opts+=( "$1" ) ;; 133 | * ) break ;; 134 | esac 135 | shift 136 | done 137 | 138 | # Basic parser tests 139 | [[ "$controldir" ]] || missing "control directory" 140 | 141 | # Handle dpkg verbosity (done via extract command) 142 | if ((verbose && !dquiet)) || (( !verbose && dverb )); then ext="--vextract"; fi 143 | 144 | # Loop file arguments 145 | (( $# )) || missing "file" 146 | while (( $# )); do 147 | filename=${1##*/} 148 | filepath=${1%"$filename"} 149 | filetitle=${filename%.*} 150 | fileext=${filename#"$filetitle"} 151 | [[ "${fileext,,}" == ".deb" ]] || { shift ; continue ; } 152 | 153 | if [[ "$destdir" ]] ; then 154 | path="${destdir}/${filetitle}" 155 | else 156 | path="${filepath}${filetitle}" 157 | fi 158 | mkdir -p "$path" # make it easy for dpkg 159 | cmd1=("$main" "${opts[@]}" "$ext" -- "$1" "${path//\/\///}" ) 160 | cmd2=("$main" "${opts[@]}" --control -- "$1" "${path//\/\///}/$controldir") 161 | if (( control )) ; then 162 | (( verbose )) && echo "$self: executing ${cmd1[@]} && ${cmd2[@]}" 163 | "${cmd1[@]}" && "${cmd2[@]}" || handleerror $? $# || break 164 | else 165 | (( verbose )) && echo "$self: executing ${cmd1[@]}" 166 | "${cmd1[@]}" || handleerror $? $# || break 167 | fi 168 | shift 169 | done 170 | 171 | (( verbose )) && (( code )) && 172 | echo "$self: error(s) occurred, exiting with $main last error's code, $code" 173 | 174 | exit $code 175 | -------------------------------------------------------------------------------- /dwww-man: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # dwww-man - wrapper for dwww to go straight to a command's man page 4 | # 5 | # Copyright (C) 2012 Rodrigo Silva (MestreLion) 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. See 19 | 20 | fatal() { [[ "$1" ]] && printf "%s\n" "$1" >&2 ; exit ${2:-1} ; } 21 | 22 | usage() { 23 | myname="${0##*/}" 24 | cat <<-USAGE 25 | Usage: $myname [options] [[section] page] 26 | USAGE 27 | if [[ "$1" ]] ; then 28 | cat >&2 <<- USAGE 29 | Try '$myname --help' for more information. 30 | USAGE 31 | exit 1 32 | fi 33 | cat <<-USAGE 34 | 35 | Wrapper for dwww to go straight to a man page. With no arguments, open 36 | dwww's main man page. 37 | 38 | Options: 39 | -h|--help - show this page. 40 | 41 | Examples: 42 | $myname printf 43 | $myname 3 printf 44 | 45 | Copyright (C) 2012 Rodrigo Silva (MestreLion) 46 | License: GPLv3 or later. See 47 | USAGE 48 | exit 0 49 | } 50 | 51 | # parse args for help option 52 | for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && usage ; done 53 | 54 | # ensure dwww is installed 55 | dwww=$(type -p dwww 2>&1) || fatal "dwww is not installed" 56 | 57 | # source a no-op modified dwww to set all relevant vars 58 | source <(awk '/^[ \t]*exec/ {print ": #" $0; next} 1' "$dwww") 59 | 60 | # set manpage url 61 | if [[ "$1" ]]; then 62 | manpage=$(man -w -- "${@:1:2}") || exit 63 | [[ "$manpage" ]] || exit 64 | IFS= read -r manpage <<<"$manpage" 65 | url="cgi-bin/dwww$(urlencode "$manpage")?type=man" 66 | else 67 | url="dwww/man" 68 | fi 69 | 70 | # open browser - xdg-open is better than "$www_browser" 71 | exec xdg-open "$prot://$DWWW_SERVERNAME/$url" 72 | -------------------------------------------------------------------------------- /environment: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Print all environment and command line arguments. 4 | 5 | env | sort 6 | 7 | echo 8 | echo "\$0=$0" 9 | 10 | i=0 11 | while (($#)) && ((++i)); do echo "\$$i=$1"; shift; done 12 | -------------------------------------------------------------------------------- /geoip: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | try: 4 | import GeoIP 5 | except ImportError: 6 | sys.exit("GeoIP module not found, try 'pip3 install GeoIP' and ryn again") 7 | 8 | 9 | def main(argv=None): 10 | if argv is None: 11 | argv = sys.argv[1:] 12 | 13 | try: 14 | path = argv[0] 15 | except IndexError: 16 | print("Usage: geoip ") 17 | return 18 | 19 | geo = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) 20 | with open(path) as fp: 21 | for line in fp: 22 | ip = line.strip() 23 | print("%s\t%s" % (geo.country_code_by_addr(ip), 24 | geo.country_name_by_addr(ip),)) 25 | 26 | 27 | if __name__ == '__main__': 28 | sys.exit(main()) 29 | -------------------------------------------------------------------------------- /hdinfo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | myname=${0##*/} 4 | 5 | usage() { 6 | echo "$myname: prints info about a Hard Disk" >&2 7 | echo "Usage: $myname DEVICE" >&2 8 | echo "Example: $myname /dev/sda" >&2 9 | exit "${1:-0}" 10 | } 11 | 12 | if [[ -z "${1:-}" ]] || (( $# > 1 )); then 13 | usage 14 | fi 15 | 16 | 17 | case "$1" in 18 | -h|--help) usage;; 19 | *) device=$1;; 20 | esac 21 | 22 | if ! [[ -b "$device" ]]; then 23 | echo "$myname: error: '$device' is not a block device" >&2 24 | usage 1 25 | fi 26 | 27 | # -------------- 28 | 29 | printcmd() { 30 | echo "-----------------------------------------------------------------" 31 | echo "\$ $@" 32 | echo 33 | } 34 | 35 | echo "hdinfo $device" 36 | 37 | printcmd fdisk p,x,p,d 38 | printf 'p\nx\np\nd\nq\n' | sudo fdisk "$device" 39 | 40 | printcmd hdparm -iI 41 | sudo hdparm -iI "$device" 42 | 43 | printcmd parted print 44 | sudo parted "$device" print 45 | -------------------------------------------------------------------------------- /home/README.md: -------------------------------------------------------------------------------- 1 | To install [`bash_aliases_min`](./bash_aliases_min) (and [`pythonrc.py`](./pythonrc.py)), 2 | run [`install-bash_aliases.sh`](./install-bash_aliases.sh): 3 | 4 | ```bash 5 | bash <(wget -qO- https://github.com/MestreLion/scripts/raw/main/home/install-bash_aliases.sh) 6 | ``` 7 | 8 | For `root`, to install [`bash_aliases_root`](./bash_aliases_root) instead: 9 | 10 | ```bash 11 | sudo su -c 'bash <(wget -qO- https://github.com/MestreLion/scripts/raw/main/home/install-bash_aliases.sh)' 12 | ``` 13 | -------------------------------------------------------------------------------- /home/bash-completion/.gitignore: -------------------------------------------------------------------------------- 1 | completions/ 2 | -------------------------------------------------------------------------------- /home/bash-completion/bash-completion.txt: -------------------------------------------------------------------------------- 1 | If you're reading this as a symlink to ~/.local/share/bash-completion, 2 | this is a friendly reminder that you customized your BASH_COMPLETION_USER_DIR, 3 | most likely in ~/.profile, so this path is no longer used by bash completions. 4 | 5 | The custom path for lazy completions in this environment is: 6 | $BASH_COMPLETION_USER_DIR/completions 7 | 8 | # ----------------------------------------------------------------------------- 9 | 10 | If instead you want to symlink this file to the default BASH_COMPLETION_USER_DIR 11 | path to serve as the future friendly reminder seen above, run this command from 12 | the same directory as this file: 13 | ln -srT -- "$(pwd)"/bash-completion.txt "${XDG_DATA_HOME:-$HOME/.local/share}"/bash-completion 14 | -------------------------------------------------------------------------------- /home/bash-completion/bash_completion: -------------------------------------------------------------------------------- 1 | # Bash completion static file 2 | # Sourced by /usr/share/bash-completion/bash_completion in ~/.bashrc 3 | # via BASH_COMPLETION_USER_FILE set in ./profile 4 | 5 | # This file is for static, eager completions loading, the user equivalent of the 6 | # system-wide /etc/bash_completion. An additional location for static completions 7 | # is BASH_COMPLETION_COMPAT_DIR, by default /etc/bash_completion.d, loaded before 8 | # BASH_COMPLETION_USER_FILE, with no user counterpart. That's why this file also 9 | # sources ./bash_completion.d/* 10 | 11 | # A better alternative for eager loading is lazy loading, also called dynamic 12 | # or on-demand, where the completion for a given command is only loaded when the 13 | # user types and hits for the first time. It requires a diectory with 14 | # one file per command to be completed 15 | 16 | # Lazy-loading directories are: 17 | # - system-wide completions: /usr/share/bash-completion/completions 18 | # - user-defined completions: BASH_COMPLETION_USER_DIR/completions, where 19 | # BASH_COMPLETION_USER_DIR is by default XDG_DATA_HOME/bash-completion, 20 | # so by default it evaluates to ~/.local/share/bash-completion/completions 21 | 22 | # Moved to install.sh 23 | #create_systemctl_aliases() { 24 | # local target=/usr/share/bash-completion/completions/systemctl 25 | # local comps=${xdg_data}/bash-completion/completions 26 | # xdg_create "$target" "$comps" 27 | # if ! [[ -r "$comps"/status echo > ln -s -- "$target" "$comps"/status 28 | # ln -s -- status "$comps"/"$cmd" 29 | # local cmd; } 30 | #create_systemctl_aliases; unset create_systemctl_aliases 31 | 32 | # copies a completion definition for a command to other command(s) 33 | complete-copy() { 34 | local cmd="$1" 35 | shift 36 | if complete -p "$cmd" &>/dev/null && type "$@" &>/dev/null; then 37 | eval $(complete -p "$cmd") "$@" 38 | fi 39 | } 40 | 41 | # package names 42 | # See /usr/share/bash-completion/completions/apt-cache._apt_cache_packages() 43 | _comp_pkg_names() { 44 | local cur; _get_comp_words_by_ref cur 45 | COMPREPLY=( $(apt-cache --no-generate pkgnames -- "$cur" 2>/dev/null) ) 46 | return 0 47 | } 48 | 49 | # Files from a given dir. 50 | # NOT to be directly assigned to a command, but to be used by other completions, 51 | # hence the double underscore. E.g.: _comp_xxx() { __comp_dir_files "/etc/xxx"; } 52 | __comp_dir_files() { 53 | local dirpath=${1:-.} 54 | local cur prev words cword 55 | _init_completion || return 56 | COMPREPLY=( $(compgen -W '$(ls "${dirpath}"/*)' -- ${cur}) ) 57 | } 58 | # ... or use `complete -G '/etc/xxx/*' xxx` and drop both _comp_xxx() and this 59 | 60 | # This is intencionally distinct from BASH_COMPLETION_USER_DIR, as a per-user 61 | # counterpart for static, *eager* loading 62 | # FIXME: Any particular reason for *wanting* a static, eager loading dir? 63 | for script in "$(dirname "${BASH_SOURCE[0]}")"/bash_completion.d/*; do 64 | if [[ ${script##*/} != @(*~|*.bak|README*) && 65 | -f "$script" && -r "$script" ]] 66 | then 67 | source "$script" 68 | fi 69 | done 70 | unset script 71 | -------------------------------------------------------------------------------- /home/bash-completion/bash_completion.d/README: -------------------------------------------------------------------------------- 1 | User counterpart of /etc/bash_completion.d, for eagerly-loaded completions 2 | Place any personal bash completion files here 3 | See ../bash_completion file for more info 4 | -------------------------------------------------------------------------------- /home/bash-completion/bash_completion.d/askubuntu: -------------------------------------------------------------------------------- 1 | _have askubuntu-package && 2 | complete -F _comp_pkg_names askubuntu-package 3 | -------------------------------------------------------------------------------- /home/bash-completion/bash_completion.d/dwww-man: -------------------------------------------------------------------------------- 1 | # _have() is defined in /etc/share/bash-completion/bash-completion, it also 2 | # states have() is deprecated, so _have() it is. 3 | # exists() is only defined at $SCRIPTS/home/bashrc, which comes later in load order. 4 | if ! _have dwww-man || ! _have man; then 5 | return 6 | fi 7 | 8 | # Hardcoding _completion_loader() here, but could be obtained parsing `complete -p -D` 9 | if ! complete -p man &>/dev/null && declare -F _completion_loader >/dev/null; then 10 | _completion_loader man 11 | fi 12 | 13 | # This assumes complete-copy() is already defined at $SCRIPTS/home/bash_completion. 14 | # Which should be true for both eager static dir loading of BASH_COMPLETION_DIR_USER, 15 | # sourced by $SCRIPTS/home/bash_completion itself, or lazy dynamic loading at 16 | # BASH_COMPLETION_USER_DIR, as it loads on-demand at runtime, after everything loads 17 | complete-copy man dwww-man 18 | -------------------------------------------------------------------------------- /home/bash-completion/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Create on-demand loading completions for some aliases from ../bash_aliases* 3 | 4 | # Definitions and bootstrap ---------------------------------------------------- 5 | 6 | xdg_data=${XDG_DATA_HOME:-$HOME/.local/share} 7 | user_dir=${BASH_COMPLETION_USER_DIR:-${xdg_data}/bash-completion} 8 | comp_dir=${user_dir}/completions 9 | here=$(dirname -- "$(readlink -f -- "$0")") 10 | 11 | exists() { type "$@" &>/dev/null; } 12 | escape() { printf '%q' "$@"; } 13 | create_dirs() { 14 | local path=$1 15 | local mode=${2:-} 16 | local opts=(); if [[ "$mode" ]]; then opts+=(--mode "$mode"); fi 17 | if ! [[ -d "$path" ]]; then mkdir --parents "${opts[@]}" -- "$path"; fi 18 | } 19 | 20 | 21 | # Main dirs 22 | create_dirs "$xdg_data" 700 23 | create_dirs "$comp_dir" 24 | 25 | # Static completions 26 | if ! [[ "$user_dir" == "$here" ]]; then 27 | create_dirs "$user_dir"/bash_completion.d 28 | cp --no-clobber -r -t "$user_dir" -- "$here"/bash_completion{,.d} 29 | fi 30 | 31 | # ------------------------------------------------------------------------------ 32 | 33 | systemctl_aliases() { 34 | local target=/usr/share/bash-completion/completions/systemctl 35 | local cmds=(start stop restart reload) 36 | cat > "$comp_dir"/status <<-EOF 37 | # Created by ${here}/install.sh 38 | 39 | # Alternative: 40 | #source -- $(escape "$target") &>/dev/null || return 1 41 | #complete -F _systemctl -- status ${cmds[@]} 42 | 43 | __load_completion systemctl || return 1 44 | eval \$(complete -p systemctl) status ${cmds[@]} 45 | EOF 46 | for cmd in "${cmds[@]}"; do 47 | ln -f -s -- status "$comp_dir"/"$cmd" 48 | done 49 | } && systemctl_aliases 50 | 51 | # TODO: use an associative array to unify pipx and pip installers 52 | argcomplete_aliases() { 53 | local cmds=( 54 | pipx 55 | ) 56 | local cmd 57 | for cmd in "${cmds[@]}"; do 58 | if ! exists "$cmd"; then continue; fi 59 | printf '# Created by %s/install.sh\n' "$here" | 60 | cat - <(register-python-argcomplete "$cmd") > "$comp_dir"/"$cmd" 61 | done 62 | } 63 | if exists register-python-argcomplete; then argcomplete_aliases; fi 64 | 65 | # TODO: use ( $(compgen -c pip | grep -P '^pip\d[.\d]*$' | sort -ruV) ) for all pip variants 66 | if exists pip; then 67 | printf '# Created by %s/install.sh\n' "$here" | 68 | cat - <(pip completion --bash) > "$comp_dir"/pip 69 | fi 70 | -------------------------------------------------------------------------------- /home/bashrc: -------------------------------------------------------------------------------- 1 | # Commands meant to run at every shell 2 | # 3 | # To be sourced by ~/.bashrc 4 | # 5 | # To run, add these lines to ~/.bashrc: 6 | # 7 | # if [ -f "$SCRIPTS/home/bashrc" ] ; then 8 | # . "$SCRIPTS/home/bashrc" 9 | # fi 10 | 11 | # Supporting Functions --------------------------------------------------------- 12 | 13 | exists() { type "$@" &>/dev/null; } 14 | snipfile(){ local n="{${3:-5},}" s; s="/^# *>$n *${2:-}/"; awk "$s,/<$n/&&!$s" "$1"; } 15 | 16 | # ------------------------------------------------------------------------------ 17 | 18 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'XDG defs') 19 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'XDG bashrc') 20 | 21 | # ------------------------------------------------------------------------------ 22 | 23 | # Enable bash-completion, if not already enabled by ~/.bashrc 24 | if [ -z "${BASH_COMPLETION_VERSINFO:-}" ] && 25 | [ -f /usr/share/bash-completion/bash_completion ] && 26 | ! shopt -oq posix 27 | then 28 | source /usr/share/bash-completion/bash_completion 29 | fi 30 | 31 | if [ -f "$SCRIPTS/home/bash_aliases" ] ; then 32 | source "$SCRIPTS/home/bash_aliases" 33 | fi 34 | 35 | if [ -f "$HOME/work/wine-tools/wine-tools-bashrc" ] ; then 36 | source "$HOME/work/wine-tools/wine-tools-bashrc" 37 | fi 38 | 39 | if [ -f "$HOME/work/dosbox/dosbox-tools/dosbox-bashrc" ] ; then 40 | source "$HOME/work/dosbox/dosbox-tools/dosbox-bashrc" 41 | fi 42 | 43 | # Settings --------------------------------------------------------------------- 44 | 45 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'PS1 customization') 46 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'Settings') 47 | 48 | # Create core dump files on segmentation fault. File `core` at current process dir 49 | #ulimit -c unlimited 50 | 51 | # ------------------------------------------------------------------------------ 52 | # Cleanup and finish 53 | 54 | # shellcheck source=./bash_aliases_min 55 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'Cleanup') 56 | 57 | # shellcheck source=./bash_aliases_min 58 | source <(snipfile "$SCRIPTS/home/bash_aliases_min" 'Local bash_aliases') 59 | 60 | # So cute! 61 | exists cowfortune && { cowfortune | { exists lolcat && lolcat || cat ; } } || : 62 | -------------------------------------------------------------------------------- /home/data/gtksourceview-3.0/language-specs/groff.lang: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | test/plain 33 | *.mom;*.ms;*.me;*.mm;*.1;*.2;*.3;*.4;*.5;*.6;*.7 34 | 35 | 36 | 37 |