├── config ├── fish │ └── config.fish ├── clipit │ └── clipitrc ├── lxterminal │ └── lxterminal.conf └── kitty │ └── kitty.conf ├── reboot ├── tomatych.py ├── rundesktop ├── game-screenshot.sh ├── timer ├── knok ├── translate-selection.sh ├── duplicati-ping.py ├── vlc-now.sh ├── memory-available.sh ├── translation-insert.sh ├── center-mouse-active-window.py ├── poweroff ├── translate-yandex.sh ├── temp.sh ├── skypenotify ├── sssh ├── generate-readme.fish ├── bookmarks ├── layoutset ├── LICENSE.txt ├── random-wallpaper.sh ├── batch-rename.py ├── ex-spotify-playlist.sh ├── battery ├── control-panel ├── ec2ssh.sh ├── volume ├── doom ├── git-sync ├── print-numbers.py ├── plug ├── tray-git-status.sh ├── backup_protectedtext.py ├── status.sh ├── headlines.sh ├── notify-append ├── mus.sh ├── tray-unread.sh ├── wa ├── todo ├── sssh2 ├── snippy.sh ├── itunec ├── SHASUMS ├── aliases.bash ├── url-preview-md.py └── README.md /config/fish/config.fish: -------------------------------------------------------------------------------- 1 | # Fish config with awesome flexible prompt, unicode symbols, better fzf integration and tons of handy functions. 2 | 3 | echo "moved to " -------------------------------------------------------------------------------- /reboot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # See 6 | 7 | 8 | setsid bash -c "sleep 3 && systemctl reboot"& 9 | echo "Shutdown in 3 seconds" 10 | WIN_IDs=$(wmctrl -l | awk '{print $1}') 11 | for i in $WIN_IDs; do wmctrl -ic "$i" || true; done -------------------------------------------------------------------------------- /tomatych.py: -------------------------------------------------------------------------------- 1 | # 2 | # Description 3 | # ----------- 4 | # * Simple Hackable Pomodoro Timer with optional Slack and Habitica integrations. 5 | # * Intended to be hacked and modified to fit your specific vision of how Pomodoro timers should work. 6 | # * Moved to [separate repo](https://github.com/dmi3/tomatych) 7 | -------------------------------------------------------------------------------- /rundesktop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Execute `.desktop` file from terminal 6 | 7 | 8 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 9 | 10 | # Usage 11 | # ----- 12 | # rundesktop /usr/share/applications/firefox.desktop 13 | 14 | from gi.repository import Gio 15 | import sys 16 | 17 | def main(myname, desktop, *uris): 18 | launcher = Gio.DesktopAppInfo.new_from_filename(desktop) 19 | launcher.launch_uris(uris, None) 20 | 21 | if __name__ == "__main__": 22 | main(*sys.argv) 23 | -------------------------------------------------------------------------------- /game-screenshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Description 5 | # ----------- 6 | # Saves full screen screenshot with current window name and date to predefined folder and plays sound if successful. 7 | 8 | # Requirements 9 | # ------------ 10 | # * `sudo apt-get install scrot xdotool` 11 | 12 | # Usage 13 | # ------------ 14 | 15 | # * Bind a hotkey to `game-screenshot.sh /path/to/folder` 16 | 17 | scrot "$*/%Y_$(xdotool getwindowfocus getwindowname | tr -dc '[:alnum:]\n\r')_%m_%d_%H_%M_%S.png" \ 18 | && ffplay ~/git/stuff/documents/sounds/Comix_Zone_STRIGIL\ PACK\ IT\ IN.mp3 -autoexit -nodisp 19 | 20 | 21 | -------------------------------------------------------------------------------- /config/clipit/clipitrc: -------------------------------------------------------------------------------- 1 | # Config for [ClipIt](https://github.com/CristianHenzel/ClipIt) with sane defaults and hotheys 2 | 3 | [rc] 4 | use_copy=true 5 | use_primary=false 6 | synchronize=false 7 | automatic_paste=true 8 | show_indexes=false 9 | save_uris=true 10 | use_rmb_menu=false 11 | save_history=true 12 | history_limit=50 13 | items_menu=20 14 | statics_show=true 15 | statics_items=10 16 | hyperlinks_only=false 17 | confirm_clear=false 18 | single_line=true 19 | reverse_history=false 20 | item_length=50 21 | ellipsize=2 22 | history_key=V 23 | actions_key=F2 24 | menu_key= 25 | search_key=M 26 | offline_key= 27 | offline_mode=false 28 | -------------------------------------------------------------------------------- /timer: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Simple timer with sound and dialog window notification. To remind you to turn stove off :). 6 | # Replace pc_up.wav to any available audiofile. 7 | 8 | # Requirements 9 | # ------------ 10 | # sudo apt-get install dunst aplay 11 | 12 | # Usage 13 | # ----- 14 | # timer 6 # i.e. notify after 6 minutes 15 | 16 | echo "$(date +"%H:%M") Will notify you in $1 minutes!" 17 | sleep $1m && (notify-send -u critical "Timer done $1" & aplay ~/git/stuff/documents/sounds/pc_up.wav) & 18 | 19 | # Alternative approach - show popup instead of notification 20 | #sleep $1m && (zenity --info --text "Timer done" & cvlc /home/edmnovi/gitstuff/documents/sounds/pc_up_beep.wav vlc://quit) & 21 | 22 | -------------------------------------------------------------------------------- /knok: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Knocks to given ports with 0.5 second delay. Useful when default knockd delay 6 | # is to short for server to react. Additionally displays Bob Dylan's lyrics :) 7 | 8 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 9 | 10 | # Requirements 11 | # ------------ 12 | # 1. `sudo apt-get install knockd python3 python3-setuptools` 13 | # 2. `sudo easy_install3 sh` 14 | 15 | # Usage 16 | # ----- 17 | # `knock ip [port,port...]` 18 | 19 | 20 | from sh import knock 21 | from time import sleep 22 | import sys 23 | 24 | ip = sys.argv[1] 25 | for arg in sys.argv[2:]: 26 | sys.stdout.write(" knock") 27 | sys.stdout.flush() 28 | knock(ip,arg) 29 | sleep(0.5) 30 | print('in on heaven\'s dooor!') 31 | 32 | 33 | -------------------------------------------------------------------------------- /translate-selection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Show popup with translation of selected text. Works in any application. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ---------- 11 | # 1. Setup https://github.com/dmi3/bin/blob/master/yandex-translate.sh 12 | # 2. `sudo apt-get install zenity xsel` 13 | 14 | # Usage 15 | # ----- 16 | # * Bind script to hotkey in your DE. 17 | # * Select any text. Press hotkey. 18 | 19 | selection=`xsel -p` 20 | zenity --info --timeout 10 --text "$selection\n$(translate-yandex.sh "$selection")" 21 | 22 | # Alternative using translate-bin 23 | #zenity --info --text "$selection\n$(echo "$selection" | translate-bin -s google -t "$DEST_LANG" | sed "s/.*>//g")" 24 | 25 | 26 | -------------------------------------------------------------------------------- /duplicati-ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Ping on successful [Duplicati](https://www.duplicati.com/) backup 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Usage 10 | # ----- 11 | # Add path to this script to `run-script-after` in job `Configuration` → `Options` → `Advanched Options` 12 | # On Windows you will need to create `.bat` file containing path to this script, and add path to `.bat` file to `run-script-after` 13 | 14 | import os 15 | import urllib.request 16 | 17 | if os.environ['DUPLICATI__OPERATIONNAME'] == 'Backup': 18 | with open(os.environ['DUPLICATI__RESULTFILE']) as r: 19 | if str('ParsedResult: Success' in r.read()): 20 | urllib.request.urlopen('https://hchk.io/ URL') 21 | -------------------------------------------------------------------------------- /vlc-now.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Description 5 | # ----------- 6 | # Show file or stream currently playing in VLC. Works well with (with xfce4-genmon-plugin). See `playerctl -h` for another players. 7 | 8 | # Requirements 9 | # ------------ 10 | # * `sudo apt-get install vlc playerctl` 11 | 12 | # Usage 13 | # ------------ 14 | 15 | # * `vlc-now` 16 | 17 | # **Includes useful functions** 18 | 19 | function cutExt() { 20 | cut -d. -f1 21 | } 22 | 23 | function wrapInBrackets() { 24 | xargs -I % echo "["%"]" 25 | } 26 | 27 | function basename() { 28 | xargs -0 basename 29 | } 30 | 31 | function urlDecode() { 32 | perl -pe 's/\%(\w\w)/chr hex $1/ge' 33 | } 34 | 35 | url=$(playerctl -p vlc metadata xesam:url 2>/dev/null) && echo "$url" | urlDecode | basename | cutExt | wrapInBrackets || echo "" 36 | 37 | 38 | -------------------------------------------------------------------------------- /memory-available.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Prints free memory in gigabytes. Sends urgent notification if usage is less than defined value. 6 | # Cached memory is considered free. 7 | # Works best with [indicator-sysmonitor](https://github.com/fossfreedom/indicator-sysmonitor) and [dunst](http://developer.run/23) 8 | 9 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 10 | 11 | # Requirements 12 | # ---------- 13 | # 1. `sudo apt-get install notify-send ` 14 | 15 | 16 | available=$(awk '/^Cached/ { c=$2 } /^MemAvailable/ { a=$2 } END { printf "%.0f", (a + c)/1024 }' /proc/meminfo) 17 | 18 | if [ $available -lt 1000 ] # threshold in megabytes 19 | then 20 | notify-send "Memory is running out!" # -u critical 21 | fi 22 | 23 | echo $available | awk '{ printf "🛢️%4.1fGb", $1/1024 }' -------------------------------------------------------------------------------- /translation-insert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Decription 4 | # ---------- 5 | # Prompts for text. Then inputs translation. Works in any application. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ---------- 11 | # 1. Setup https://github.com/dmi3/bin/blob/master/yandex-translate.sh 12 | # 2. `sudo apt-get install zenity xsel` 13 | 14 | # Usage 15 | # ----- 16 | # * Bind script to hotkey in your DE. After input wait couple of seconds for translation to appear. 17 | 18 | DEST_LANG=en 19 | SRC_LANG=ru 20 | 21 | printf $(translate-yandex.sh "$(zenity --entry)") | xclip -sel clip 22 | 23 | # Alternative using translate-bin 24 | # echo $(zenity --entry) | translate-bin -s google -f "$SRC_LANG" -t "$DEST_LANG" | sed "s/.*>//g" | xclip -sel clip 25 | 26 | sh -c "xdotool key --clearmodifiers ctrl+v" 27 | 28 | -------------------------------------------------------------------------------- /center-mouse-active-window.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Moves mouse in the center of active window. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ------------ 11 | # sudo apt-get install xdotool python3-sh gir1.2-wnck-3.0 12 | 13 | # Usage 14 | # ----- 15 | # center-mouse-active-window.py 16 | 17 | 18 | import gi 19 | gi.require_version('Wnck', '3.0') 20 | from gi.repository import Wnck 21 | from sh import xdotool 22 | 23 | screen = Wnck.Screen.get_default() 24 | screen.force_update() 25 | active_window = screen.get_active_window() 26 | g = active_window.get_geometry() 27 | 28 | xdotool("mousemove", int(g.xp + g.widthp/2), int(g.yp +g.heightp/2)) 29 | # workaround for https://gitlab.freedesktop.org/xorg/xserver/-/issues/633 30 | xdotool("mousemove_relative", 1, 1) 31 | -------------------------------------------------------------------------------- /config/lxterminal/lxterminal.conf: -------------------------------------------------------------------------------- 1 | # Config for [LXTerminal](https://wiki.lxde.org/en/LXTerminal) with copy/paste on Ctrl+C/V and nicer color theme 2 | 3 | [general] 4 | fontname=Monospace 12 5 | selchars=-A-Za-z0-9,./?%&#:_ 6 | scrollback=1000 7 | bgcolor=#35353a3a4444 8 | bgalpha=65535 9 | fgcolor=#aaaaaaaaaaaa 10 | disallowbold=false 11 | cursorblinks=false 12 | cursorunderline=false 13 | audiblebell=false 14 | tabpos=top 15 | hidescrollbar=false 16 | hidemenubar=true 17 | hideclosebutton=false 18 | hidepointer=false 19 | disablef10=false 20 | disablealt=false 21 | 22 | [shortcut] 23 | new_window_accel= 24 | new_tab_accel=T 25 | close_tab_accel=F4 26 | close_window_accel=Q 27 | copy_accel=C 28 | paste_accel=V 29 | name_tab_accel=F2 30 | previous_tab_accel=Page_Up 31 | next_tab_accel= 32 | move_tab_left_accel=Left 33 | move_tab_right_accel=Right 34 | -------------------------------------------------------------------------------- /poweroff: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Gracefully closes all running X applications, then powers off the computer. 6 | # Make sure to avoid conflicts with system `poweroff` is such exists. 7 | # Useful to avoid issues when calling `poweroff` from console: 8 | # 9 | # * "The database you are trying to open is locked by another instance of KeePassXC.", 10 | # * "Well, this is embarrassing. Firefox is having trouble recovering your windows and tabs." 11 | # * Spotify forgetting current playlist 12 | # * etc 13 | 14 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 15 | 16 | # Requirements 17 | # ---------- 18 | # 1. `sudo apt-get install wmctrl` 19 | 20 | setsid bash -c "sleep 3 && systemctl poweroff"& 21 | echo "Shutdown in 3 seconds" 22 | WIN_IDs=$(wmctrl -l | awk '{print $1}') 23 | for i in $WIN_IDs; do wmctrl -ic "$i" || true; done 24 | 25 | -------------------------------------------------------------------------------- /translate-yandex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # CLI Yandex Translate API ru↔en. Automatically detects language. Translates any language to Russian, and Russian to English. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Usage 10 | # ----- 11 | # yandex-translate.sh cat is a small, typically furry, carnivorous mammal # en → ru 12 | # yandex-translate.sh die Hauskatze ist eine Unterart der Wildkatze # de → ru 13 | # yandex-translate.sh кот это маленькое, пушистое и очень хитрое млекопитающее # ru → en 14 | 15 | key=$(cat ~/git/stuff/keys/yandex_translate) # get your key https://tech.yandex.ru/keys/get/?service=trnsl&ncrnd=1455 16 | 17 | if [[ $* =~ ^.*[А-Яа-яЁё]+.*$ ]] ; then lang=en; else lang=ru; fi # if at least one Cyrillic symbol 18 | curl -s "https://translate.yandex.net/api/v1.5/tr.json/translate?key=$key&lang=$lang&" --data-urlencode "text=$*" | awk -F'"' {' print $10 '} -------------------------------------------------------------------------------- /temp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Shows CPU, System and GPU temperature 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ------------ 11 | # sudo apt-get install jq lm-sensors nvidia-smi 12 | 13 | # Usage 14 | # ----- 15 | # temp 16 | 17 | CPU=$(sensors -j | jq '."coretemp-isa-0000"."Package id 0".temp1_input') 18 | SYS=$(sensors -j | jq '."acpitz-acpi-0".temp1.temp1_input') 19 | GPU=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader) 20 | 21 | 22 | test $CPU -gt "60" && CPU="#### $CPU ####\n" 23 | test $SYS -gt "30" && SYS="#### $SYS ####\n" 24 | test $GPU -gt "75" && GPU="#### $GPU ####\n" 25 | 26 | echo "CPU:$CPU SYS:$SYS GPU:$GPU" 27 | 28 | # https://github.com/dmi3/qmk_firmware/blob/master/keyboards/handwired/onekey/kb2040/kbecho.py 29 | if type "kbecho.py" > /dev/null; then 30 | kbecho.py t "CPU:$CPU SYS:$SYS\nGPU:$GPU\n$(date +"%H:%M")" 31 | fi 32 | 33 | -------------------------------------------------------------------------------- /skypenotify: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Script to run append Skype messages in Notify OSD as shown on http://thexnews.com/uploads/notify.gif 6 | # Since `x-canonical-append` is broken in notify-send for example in Skype you will wait forever untill all messages are shown 7 | # This script makes new messages readable in same notification window 8 | # 9 | # [Readme in russian](http://thexnews.com/p/554) 10 | 11 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 12 | 13 | # Requirements 14 | # ------------ 15 | # `wget https://raw.github.com/dmi3/bin/master/notify-append -P ~/bin && chmod +x ~/bin/notify-append` 16 | 17 | # Usage 18 | # ----- 19 | # `skypenotify "%sname" "%smessage"` 20 | 21 | focused_id=`xprop -root | grep "window id" | grep _NET_ACTIVE | cut -d " " -f 5 | cut -c 3-10` 22 | app_id=`wmctrl -l | grep "$1" | cut -d " " -f 1 | cut -c 4-10` 23 | if [[ $focused_id != $app_id ]]; then 24 | #If chat window not in focus send message 25 | notify-append "$1" "$2" "skype" & 26 | fi 27 | 28 | -------------------------------------------------------------------------------- /sssh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Script to change your terminal title to user@host when connecting to ssh and changing 6 | # it back after exiting. Additionally sets green prompt on remote host. 7 | # Useful for Keepassx and visual distinction to avoid notorious "wrong window" problem. 8 | # Also works when connecting Fish → Bash 9 | # 10 | # If you want hostname from local `~/.ssh/config` file to appear in title use [sssh2](https://github.com/dmi3/bin/blob/master/sssh2). 11 | 12 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 13 | 14 | # Requirements 15 | # ------------ 16 | # `sudo apt-get install xdotool` 17 | 18 | # Usage 19 | # ----- 20 | # `sssh user@hostname` 21 | # `alias ssh=sssh` 22 | 23 | CUSTOM_PS1='PS1="\[$(tput bold)\]\[$(tput setaf 2)\][\u@\h \W]\\$ \[$(tput sgr0)\]"' 24 | CUSTOM_TITLE='echo -e "\033]0;🖧 $USER@$HOSTNAME\a"' 25 | 26 | PREV_TITLE=`xdotool getwindowfocus getwindowname` 27 | /usr/bin/ssh -t "$@" "export PROMPT_COMMAND='eval '\\''$CUSTOM_TITLE;$CUSTOM_PS1'\\'; bash --login" 28 | echo -e "\033]0;$PREV_TITLE\a" 29 | -------------------------------------------------------------------------------- /generate-readme.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/fish 2 | 3 | # Decription 4 | # ---------- 5 | # Generates this readme 6 | 7 | # Usage 8 | # ----- 9 | # echo -e "#!/bin/sh\necho \# Useful scripts for Linux users > README.md\necho \"See my [Fish config](https://github.com/dmi3/fish) for more CLI awesomness\" >> README.md\ngenerate-readme.fish --reverse >> README.md\nshasum -a 256 * | grep -v 'SHASUMS\|config' > SHASUMS" > .git/hooks/pre-commit 10 | # chmod +x .git/hooks/pre-commit 11 | 12 | 13 | if [ "$argv[1]" = "--reverse" ] 14 | set FILTER tac 15 | else 16 | set FILTER cat 17 | end 18 | 19 | for f in (git ls-files | grep -v '.md$' | grep -v '.txt$' | grep -v 'SHASUMS' | grep -v '.gitignore' | $FILTER) 20 | echo -e "\n# [$f](https://github.com/dmi3/"(basename (pwd))"/blob/master/$f)\n" 21 | grep -h -e "#\s\s" $f | grep -v "Author\|Source" | string sub -s 4 | string replace -ar "(?=Usage|Requirements|Instalation|Decription|Description)" "\n" 22 | cat $f | grep -e "^function" | string replace 'function ' '* `' | string replace ' --description' '`' 23 | echo -e "
" 24 | end 25 | 26 | git add README.md 27 | -------------------------------------------------------------------------------- /bookmarks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/fish 2 | 3 | # Decription 4 | # ---------- 5 | # Script for quickly adding and accessing bookmarks. Browser independent. 6 | # When you want to store bookmarks in plain format, use CLI, but don't want use [bm](https://github.com/tj/bm) 7 | # or [Buku](https://github.com/jarun/Buku) 8 | # Useful when set by hotkeys or [clipboard manager](https://developer.run/25) actions. 9 | 10 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 11 | 12 | # Requirements 13 | # ---------- 14 | # 1. `sudo apt-get install fzf` 15 | 16 | # Usage 17 | # ----- 18 | 19 | # * `bookmarks -a http://github.com useful site` 20 | # * `bookmarks -a %s $(zenity --entry)` Interactive 21 | # * `bookmarks` 22 | # * Bookmark currently copied link using [ClipIt](https://github.com/CristianHenzel/ClipIt) actions: `bookmarks -a %s $(zenity --entry)` 23 | 24 | set BOOKMARKS_FILE ~/git/stuff/braindump/bookmarks.md 25 | 26 | argparse 'a/add' -- $argv 27 | 28 | if set -q _flag_add 29 | echo "$argv" >> $BOOKMARKS_FILE 30 | else 31 | cat $BOOKMARKS_FILE | fzf --tac --no-sort | string match -r "(http[s]?://.*?)[\s>]" | tail -1 | read -l result; and xdg-open $result 32 | end 33 | -------------------------------------------------------------------------------- /layoutset: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Script to set keyboard layout depending if its Apple or regular keyboard + some settings 6 | 7 | # Usage 8 | # ----- 9 | # `layoutset` 10 | 11 | udevadm trigger --subsystem-match=input --action=change 12 | 13 | # Preserve layout for window 14 | # Requires `sudo apt-get install kbdd` 15 | if ! pgrep "kbdd" > /dev/null; then 16 | if hash kbdd 2>/dev/null; then 17 | kbdd 18 | fi 19 | fi 20 | 21 | # Alt+Ctrl+Backspace restart, no caps lock, toggle via alt+shift, blink caps when aliternative layout is on 22 | (setxkbmap lv && sleep 0.1s && setxkbmap -layout 'lv,ru' -option 'grp:alt_shift_toggle' -option 'terminate:ctrl_alt_bksp' -option 'ctrl:nocaps' -option 'grp_led:caps') & 23 | 24 | # Disable insert 25 | xmodmap -e "keycode 118 =" 26 | 27 | # Unset caps is set previosly 28 | xmodmap -e "clear lock" 29 | 30 | # If Apple keyboard plugged in, swap left alt and win and put tilde back to left upper corner 31 | if lsusb | grep Apple > /dev/null; then 32 | #setxkbmap -option 'altwin:swap_lalt_lwin' 33 | xmodmap -e "keycode 94 = grave asciitilde" 34 | xmodmap -e "keycode 191 = Print Sys_Req" 35 | 36 | else 37 | setxkbmap -option altwin:left_meta_win 38 | fi 39 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /random-wallpaper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Sets the wallpaper, randomly selecting one from a folder. If the wallpaper is smaller than the screen, it also changes the surrounding area to a color that matches the wallpaper's palette. 6 | 7 | # Author: Dmitry (http://dmi3.net) 8 | # Source: https://github.com/dmi3/bin 9 | 10 | # Instalation 11 | # ----------- 12 | # sudo apt-get install nitrogen coreutils 13 | 14 | # Usage 15 | # ----- 16 | # * Put some nice pictures in ~/wallpapers/ 17 | # * Call this script by cron, on login or unlock 18 | # * If you want fixed background color - put one in ~/wallpapers/bg_color 19 | # * You may want to change `--set-centered` to `--set-auto` depending on how picture should be scaled. 20 | 21 | 22 | export DISPLAY=":0" 23 | 24 | DIRECTORY=~/wallpapers/ 25 | 26 | if [ ! -d "$DIRECTORY" ]; then 27 | echo "Directory does not exist: $DIRECTORY" 28 | exit 1 29 | fi 30 | 31 | WALL=$DIRECTORY/$(ls ~/wallpapers/ | shuf -n1) 32 | 33 | if [ -f "$DIRECTORY/bg_color" ]; then 34 | COLOR=$(<"$DIRECTORY/bg_color") 35 | else 36 | COLOR=$(convert $WALL -scale 1x1\! -format '%[pixel:u]' info:- | awk -F'[(),]' '{printf "#%02X%02X%02X\n", $2, $3, $4}') 37 | fi 38 | 39 | nitrogen --save --set-color="$COLOR" --set-centered $WALL 40 | 41 | -------------------------------------------------------------------------------- /batch-rename.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Renames files given in arguments. Interactively prompts for file name. If no otherwise specified - uses first file 6 | # name + number. 7 | 8 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 9 | 10 | # Usage 11 | # ----- 12 | # rename.py file1 file2 file3 ... 13 | 14 | from sys import argv 15 | from os import rename 16 | from urllib.request import unquote 17 | from os.path import splitext, abspath, basename, dirname, isfile 18 | from sh import zenity, notify_send 19 | 20 | 21 | new = "" 22 | message = "" 23 | 24 | i = 0 25 | for f in argv[1:]: 26 | if "file://" in f: 27 | f = unquote(f)[7:] 28 | 29 | fdir = dirname(abspath(f)) 30 | name,ext = splitext(f) 31 | 32 | if new == "": 33 | new = zenity("--text", "Rename", "--entry", "--entry-text", basename(name)).strip() 34 | 35 | try: 36 | while True: 37 | i = i + 1 38 | new_name = "%s/%s %s%s" % (fdir, new, i, ext) 39 | if not isfile(new_name): 40 | break 41 | 42 | rename(f, new_name) 43 | message = "%s%s → %s\n" % (message, f, new_name) 44 | except Exception as e: 45 | notify_send("Error", "-u", "critical", e) 46 | 47 | notify_send("Renamed", message) -------------------------------------------------------------------------------- /ex-spotify-playlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Export playlists from Spotify without giving credentials to shady sites (to avoid your Spotify credentials be stolen and resold to someone in different timezone) 4 | # 5 | # Converts Spotify playlist from "Song Links" list: 6 | # 7 | # https://open.spotify.com/track/6autdCG3xl7gzoiDCEB2HN 8 | # https://open.spotify.com/track/4q6RvRkXquQ965hubV58lb 9 | # https://open.spotify.com/track/01pzLOA8rQLfoodUCLc2wj 10 | # 11 | # To "Track - Artist" list: 12 | # 13 | # Nerevar Rising - Jeremy Soule 14 | # Arcanum - NewEnglandStringQuartet 15 | # Wilderness - Matt Uelmen 16 | 17 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 18 | 19 | # Requirements 20 | # ------------ 21 | # sudo apt-get install libxml2-utils 22 | 23 | # Usage 24 | # ------------ 25 | # 1. Open Spotify app 26 | # 2. Open playlist or "Songs" view 27 | # 3. Select all tracks `Ctrl+A` 28 | # 4. Copy track urls `Ctrl+C` 29 | # 5. Paste into file and save 30 | # 6. `cat /path/to/file | ex-spotify-playlist.sh` 31 | 32 | while IFS= read -r url; do 33 | curl -s "$url" | xmllint --html --recover --xpath "concat(string(//meta[@name='music:musician_description']/@content), ' - ', string(//meta[@property='og:title']/@content))" - 2>/dev/null 34 | done 35 | -------------------------------------------------------------------------------- /battery: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Description 4 | # ---------- 5 | # One more script to show battery status as bar(s). Difference from other solutions: 6 | # 7 | # * Simplicity, duh 8 | # * Acknowledges the fact that there were sometimes more than one battery in laptop 9 | # - Will display capacity for all batteries 10 | # * Also the fact that there were sometimes no battery at all! 11 | # - No error in this case 12 | # * Old batteries usually max at ≈99, so it has same symbol as 100 13 | # * Can work with [indicator-sysmonitor](https://github.com/fossfreedom/indicator-sysmonitor) 14 | # * [Spark](https://github.com/holman/spark) could be used here, but this solution is even simpler 15 | 16 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 17 | 18 | # Usage 19 | # ----- 20 | # $ battery # multiple batteries are installed 21 | # 🔌 ▄▇ 22 | # $ battery # single battery is installed 23 | # 🔌 ▇ 24 | # $ battery # no battery is installed 25 | # 🔌 26 | 27 | grep -q 0 /sys/class/power_supply/AC/online 2> /dev/null && echo -n "🔋 " || echo -n "🔌 " 28 | 29 | for capacity in /sys/class/power_supply/BAT*/capacity; do 30 | case $(cat $capacity 2> /dev/null) in 31 | [0-9]) echo -n "▁" ;; 32 | [1-2]?) echo -n "▂" ;; 33 | [3-4]?) echo -n "▃" ;; 34 | [5-6]?) echo -n "▄" ;; 35 | [7-8]?) echo -n "▅" ;; 36 | 9?) echo -n "▇" ;; 37 | 100) echo -n "▇" ;; 38 | esac 39 | done 40 | -------------------------------------------------------------------------------- /control-panel: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Description 5 | # ----------- 6 | # GUI LXQT Settings menu 7 | 8 | 9 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 10 | 11 | # Requirements 12 | # ------------ 13 | # fzf 14 | 15 | 16 | # Usage 17 | # ------------ 18 | # control-panel 19 | 20 | bash -c "$(echo '🖶 Printers | system-config-printer 21 | 🖶 HP Printers | hp-toolbox 22 | 🖶 CUPS | xdg-open http://localhost:631/ 23 | 🗔 Openbox | subl ~/.config/openbox/lxqt-rc.xml 24 | 🗔 Openbox Config | obconf 25 | 🛠 DockbarX | dbx_preference 26 | 🔐 Passwords | seahorse 27 | ↻ Openbox Restart | openbox --reconfigure 28 | ↻ Session Restart | sudo service lightdm restart 29 | 👕 Look and Feel | lxqt-config-appearance 30 | 🏁 Autostart | lxqt-config-session 31 | 🔄 Task Manager | qps 32 | 💻 Display Settings | lxqt-config-monitor 33 | 💻 Screensaver | xscreensaver-command -prefs 34 | 👥 Users | users-admin 35 | 🎴 Wallpapers | xdg-open /usr/share/lubuntu/wallpapers/ 36 | 🗔 Qt Configuration | qtconfig-qt4 37 | 🖧 Hosts | xdg-open /etc/hosts 38 | 💾 Filesystem | xdg-open /etc/fstab 39 | 💾 Disks | gnome-disks 40 | 💾 Disk Usage | baobab 41 | 🎧 Bluetooth | blueman-manager 42 | 👤 Profile | xdg-open /etc/profile 43 | 👤 User | xdg-open /etc/rc.local 44 | 👤 Avatar | xdg-open /usr/share/sddm/faces/ 45 | 🗔 Panel | xfce4-panel -p' | fzf --no-sort --header="📋 Control Panel" | cut -d '|' -f 2)" 46 | -------------------------------------------------------------------------------- /ec2ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # * Writes all running AWS EC2 instances with defined name to [SSH config file](https://nerderati.com/2011/03/17/simplify-your-life-with-an-ssh-config-file/) 6 | # * So you write `ssh instance_name` instead of `ssh -i ~/.ssh/gate.pem ec2-user@ec2-12-345-67-89.us-east-1.compute.amazonaws.com` 7 | # * Autocompletion! 8 | # * Command history is clean and reusable for `ssh` and `scp` 9 | # * Instance IP change on reboot is not problem anymore 10 | # * Works well with [sssh2](https://github.com/dmi3/bin/blob/master/sssh2). 11 | 12 | # Author: Dmitry (http://dmi3.net) 13 | # Source: https://github.com/dmi3/bin 14 | 15 | # Instalation 16 | # ----------- 17 | # * Setup [aws-cli](https://github.com/aws/aws-cli#aws-cli) 18 | # * (Optional) Install [latest Openssh in 16.04](https://gist.github.com/stefansundin/0fd6e9de172041817d0b8a75f1ede677) 19 | # * Change credentials in `TEMPLATE` ↓ 20 | 21 | # Usage 22 | # ----- 23 | # * If you have Openssh > 7.3: 24 | # - `ec2ssh.sh | tee ~/.ssh/aws_config` 25 | # - Add [Include aws_config](https://superuser.com/a/1142813) to `~/.ssh/config` 26 | # * Else (will overwrite file) 27 | # - ec2ssh.sh | tee ~/.ssh/config 28 | 29 | TEMPLATE=" 30 | Host \$1 31 | HostName \$0 32 | User ec2-user 33 | IdentityFile ~/.ssh/gate.pem 34 | IdentitiesOnly yes" 35 | 36 | aws ec2 describe-instances \ 37 | --filter "Name=tag-key,Values=Name" "Name=tag-value,Values=*" "Name=instance-state-name,Values=running" \ 38 | --query "Reservations[*].Instances[*][NetworkInterfaces[0].Association.PublicDnsName,Tags[?Key=='Name'].Value[] | [0]]" \ 39 | --output text | xargs -L 1 bash -c "echo -e \"$TEMPLATE\"" -------------------------------------------------------------------------------- /volume: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Script to control audio volume from console, hotkeys, e.t.c. Also shows nice Notify OSD buble with current volume value 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ------------ 11 | # sudo apt-get install pulseaudio notify-osd 12 | 13 | # Usage 14 | # ----- 15 | # volume (up|down|mute) 16 | 17 | DEVICE_ID=$(cat ~/.config/pulse/*default-sink) 18 | 19 | icon=notification-audio-volume-medium 20 | if [[ $1 == "down" ]]; then 21 | #amixer set PCM 5%- 22 | #amixer -q set Master 5- unmute 23 | pactl -- set-sink-volume $DEVICE_ID "-2%" & 24 | 25 | # First string containing `Volume` after string containing $DEVICE_ID. Since PulseAudio 15 can be replaced by `pactl get-sink-volume $DEVICE_ID` 26 | volume=$(pactl list sinks | grep $DEVICE_ID -a10 | grep Volume | grep -oe "[0-9]*%" | head -1) 27 | elif [[ $1 == "up" ]]; then 28 | #amixer set PCM 5%+ 29 | #amixer -q set Master 5+ unmute 30 | pactl -- set-sink-volume $DEVICE_ID "+2%" & 31 | volume=$(pactl list sinks | grep $DEVICE_ID -a10 | grep Volume | grep -oe "[0-9]*%" | head -1) 32 | elif [[ $1 == "mute" ]]; then 33 | pactl set-sink-mute $DEVICE_ID toggle 34 | icon=notification-audio-volume-muted 35 | volume=0 36 | fi 37 | 38 | if [[ $2 != "--quiet" ]]; then 39 | notify-send --hint string:x-canonical-private-synchronous:true "Volume $volume" -i $icon -h int:value:$volume 40 | fi 41 | 42 | # https://github.com/dmi3/qmk_firmware/blob/master/keyboards/handwired/onekey/kb2040/kbecho.py 43 | if type "kbecho.py" > /dev/null; then 44 | # $volume without trailing % 45 | kbecho.py p ${volume%?} 46 | fi 47 | 48 | -------------------------------------------------------------------------------- /doom: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ---------- 5 | # Script to run gzdoom with various configurations/wads. Selectable via dmenu 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ------------ 11 | # 1. [Get latest Gzdoom](http://debian.drdteam.org/) 12 | # 2. `sudo apt-get install gzdoom dmenu python3 python3-setuptools 13 | # 3. `sudo easy_install3 sh` 14 | 15 | # Usage 16 | # ----- 17 | # doom 18 | 19 | MAP_DIR = "/media/archive/games/doom/wads/maps/" 20 | MOD_DIR = "/media/archive/games/doom/wads/mods/" 21 | DOOM_BIN = "/usr/bin/gzdoom" 22 | MODS = { 23 | "vanilla":"", 24 | "russian_overkill":"hires.pk3 bdlitev13gzdoomV2.pk3 RO_pb_2.1b.pk3 Moldova_pb_v1.1.pk3 regeneration2.wad", 25 | "brutal_doom":"hires.pk3 brutalv20b.pk3 BrutalBloodPatch20b.pk3 regeneration2.wad Cannon_Shotgun_v4.wad", 26 | } 27 | PARAMS = "+set sv_jump 2 +set sv_crouch 2 +set sv_cheats 1" # need sv_cheats to `give cannonshotgun` 28 | TIMELIMIT_MIN=15 #set 0 to play infinitely! 29 | 30 | from sh import ls,dmenu,echo,touch,kill,notify_send,Command 31 | from time import sleep 32 | from os import path 33 | 34 | doom = Command(DOOM_BIN) 35 | mod=dmenu(echo("\n".join(MODS.keys()))) 36 | mods=MOD_DIR+MODS[str(mod).strip()].replace(" "," "+MOD_DIR) 37 | wad=MAP_DIR+str(dmenu(ls(MAP_DIR,"-1","-t"))).strip() 38 | 39 | 40 | cmd=PARAMS+" -file "+mods+" "+wad 41 | touch(wad) #because we sort by last modified = first in menu 42 | args = cmd.split(" ") 43 | 44 | print(args) 45 | 46 | pid=doom(*args, _bg=True).pid 47 | 48 | if TIMELIMIT_MIN>0: 49 | sleep(TIMELIMIT_MIN*60) 50 | if path.isdir("/proc/"+str(pid)): 51 | notify_send("You have 10 seconds to save!") 52 | sleep(10) 53 | kill(pid) 54 | -------------------------------------------------------------------------------- /git-sync: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Script to simply sync all changes into git repository with one command. For example publish local changes to Github. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ---------- 11 | # 1. `sudo apt-get install git` 12 | # 2. [Setup mergetool](https://developer.atlassian.com/blog/2015/12/tips-tools-to-solve-git-conflicts/#parade-of-merge-tools) 13 | 14 | # Usage 15 | # ----- 16 | # git-sync /path/to/repo 17 | # git-sync # current dir 18 | # git-sync # if you want sync all files 19 | # git-sync -u # if you want only sync files explicitly added via `git add filename` 20 | 21 | if [ "$BASH_ARGV" != "" ] && [ -d $BASH_ARGV ]; then # if last argument is dir 22 | echo "Running in dir $BASH_ARGV." 23 | cd $BASH_ARGV 24 | fi 25 | 26 | git pull 27 | 28 | if [[ $1 == "-u" ]]; then # if first argument is -u 29 | echo "Ignoring new files." 30 | add_arg="-u" 31 | else 32 | add_arg="-A" 33 | fi 34 | git add $add_arg 35 | 36 | CHANGED=$(git diff --name-status HEAD) 37 | if [[ -z $CHANGED ]]; then 38 | echo -e "No changes to commit.\nEverything in sync." 39 | exit 0 40 | fi 41 | echo -e "Files in changelist:\n$CHANGED\nCancel and run 'git difftool HEAD'/'git diff HEAD' to review changes." 42 | 43 | read -p "Commit message (or Ctrl+C to cancel): " commit_message 44 | test -n "$commit_message" || commit_message="bump" #default value if empty 45 | git commit -a -m "$commit_message" 46 | 47 | # Try to push, if no sucess run merge and push again 48 | git push origin master \ 49 | || git pull \ 50 | || git mergetool \ 51 | && git commit -a -m "merging" \ 52 | && git push origin master 53 | 54 | exit 0 55 | 56 | 57 | -------------------------------------------------------------------------------- /print-numbers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Decription 5 | # ----------- 6 | # Font especially designed to fit 6 digits to 20x8 screens 7 | # For some reason [miniwi.flf](https://github.com/xero/figlet-fonts/blob/master/miniwi.flf) [figlet font](https://developer.run/26) is not working in tty 8 | # Useful for [Raspberry Pi 2fa](https://developer.run/45) 9 | # ``` 10 | # ▐ ██ ██ ▌▐ ██ ██ 11 | # ▐ ▐ ▐ ▌▐ ▌ ▌ 12 | # ▐ ██ ██ ██ ██ ██ 13 | # ▐ ▌ ▐ ▐ ▐ ▌▐ 14 | # ▐ ██ ██ ▐ ██ ██ 15 | # ``` 16 | 17 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 18 | 19 | # Usage 20 | # ----- 21 | # python3 numbers.py 123456 22 | 23 | 24 | 25 | import sys 26 | 27 | map = { 28 | '1': 29 | """ . 30 | ▐. 31 | ▐. 32 | ▐. 33 | ▐. 34 | ▐. 35 | """, 36 | '2': 37 | """ . 38 | ██. 39 | ▐. 40 | ██. 41 | ▌ . 42 | ██. 43 | """, 44 | '3': 45 | """ . 46 | ██. 47 | ▐. 48 | ██. 49 | ▐. 50 | ██. 51 | """, 52 | '4': 53 | """ . 54 | ▌▐. 55 | ▌▐. 56 | ██. 57 | ▐. 58 | ▐. 59 | """, 60 | '5': 61 | """ . 62 | ██. 63 | ▌ . 64 | ██. 65 | ▐. 66 | ██. 67 | """, 68 | '6': 69 | """ . 70 | ██. 71 | ▌ . 72 | ██. 73 | ▌▐. 74 | ██. 75 | """, 76 | '7': 77 | """ . 78 | ██. 79 | ▐. 80 | ▐. 81 | ▐. 82 | ▐. 83 | """, 84 | '8': 85 | """ . 86 | ██. 87 | ▌▐. 88 | ██. 89 | ▌▐. 90 | ██. 91 | """, 92 | '9': 93 | """ . 94 | ██. 95 | ▌▐. 96 | ██. 97 | ▐. 98 | ██. 99 | """, 100 | '0': 101 | """ . 102 | ██. 103 | ▌▐. 104 | ▌▐. 105 | ▌▐. 106 | ██. 107 | """, 108 | } 109 | 110 | print(sys.argv[1]) 111 | 112 | strs = [" " for x in range(6)] 113 | 114 | for n in sys.argv[1]: 115 | line = map[n].replace(".\n", "") 116 | chunks = [line[i:i+3] for i in range(0, len(line), 3)] 117 | 118 | for i,chunk in enumerate(chunks): 119 | strs[i]+=chunk 120 | 121 | for s in strs: 122 | print(s) -------------------------------------------------------------------------------- /plug: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Description 4 | # ---------- 5 | # Interactive (un)mount of hotplug devices (USB drives) from console using FZF! 6 | # Outputs path to mounted device so could be used in alias to actomatically 7 | # `cd` to mounted directory. 8 | 9 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 10 | 11 | # Requirements 12 | # ---------- 13 | # 1. `sudo apt-get install jq fzf udisks2` 14 | # 2. `alias unplug='plug -u'` 15 | # 3. `cd` to mounted directory: 16 | # - Fish shell: `alias plug='cd (command plug)'` 17 | # - Bash shell: `alias plug='cd $(command plug)'` 18 | 19 | # Usage 20 | # ----- 21 | # $ plug 22 | # > ACRONIS_MED DataTraveler_2.0 sdb1 23 | # DATA DataTraveler_3.0 sdc1 24 | # Mounted /dev/sdb1 at /media/dmi3/ACRONIS_MED. 25 | # 26 | # $ plug -u 27 | # > /media/dmi3/ACRONIS_MED ACRONIS_MED DataTraveler_2.0 sdb1 28 | # / workbuntu2020 Samsung_SSD_860_EVO_M.2_500GB sda2 29 | # /media/dmi3/ElTorito ElTorito Samsung_SSD_860_EVO_M.2_500GB sda1 30 | # Unmounted /dev/sdb1 31 | 32 | 33 | if [[ $1 == "-u" ]]; then 34 | filter="!=" 35 | else 36 | filter="==" 37 | fi 38 | 39 | DEVICE=$(lsblk -J -o HOTPLUG,NAME,LABEL,MODEL,MOUNTPOINT | jq -r ".blockdevices | .[] | . as \$p | .children | flatten | .[] | select( .hotplug == true and .mountpoint $filter null ) | [.mountpoint,.label,\$p.model,.name] | @tsv" | fzf -d$'\t' | cut -d$'\t' -f4) 40 | 41 | if [[ $1 == "-u" ]]; then 42 | sync 43 | udisksctl unmount --force -b "/dev/$DEVICE" 44 | else 45 | udisksctl mount -b "/dev/$DEVICE" > /dev/null 46 | echo $(lsblk -o MOUNTPOINT -n "/dev/$DEVICE") 47 | fi 48 | -------------------------------------------------------------------------------- /tray-git-status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # 6 | # Update tray icon depending if there are changes in Git repository. 7 | # 8 | # ⚠ Note that it does not show any icon if repository is in sync 9 | # 10 | # Check for new changes every 10 minutes. 11 | # 12 | # See also [git-sync](https://github.com/dmi3/bin#git-sync) 13 | # 14 | # See https://stackoverflow.com/a/3278427/18078777 15 | 16 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 17 | 18 | # Requirements 19 | # ---------- 20 | # 1. `sudo apt-get install yad git` 21 | # 22 | # Usage 23 | # ----- 24 | # tray-git.sh 25 | 26 | # create a FIFO file, used to manage the I/O redirection from shell 27 | PIPE=$(mktemp -u --tmpdir ${0##*/}.XXXXXXXX) 28 | mkfifo $PIPE 29 | 30 | # Settings 31 | 32 | FOLDER="$HOME/git/stuff" 33 | CHECKTIME="10m" 34 | # Clear icon and run git-sync 35 | ON_CLICK="term bash -c 'echo icon: > $PIPE && git-sync $FOLDER'" 36 | 37 | # attach a file descriptor to the file 38 | exec 3<> $PIPE 39 | 40 | # add handler to manage process shutdown 41 | function on_exit() { 42 | echo "quit" >&3 43 | rm -f $PIPE 44 | } 45 | trap on_exit EXIT 46 | 47 | # Start tray monitoring the fifo 48 | yad --notification --listen --command="$ON_CLICK" <&3 & 49 | 50 | cd $FOLDER 51 | while true 52 | do 53 | git remote update 54 | 55 | UNCOMMITTED=$(git status --porcelain=v1 2>/dev/null | wc -l) 56 | UPSTREAM="@{u}" 57 | LOCAL=$(git rev-parse @) 58 | REMOTE=$(git rev-parse "$UPSTREAM") 59 | BASE=$(git merge-base @ "$UPSTREAM") 60 | 61 | if [ $? -ne 0 ]; then 62 | ICON="error" 63 | TOOLTIP="Error" 64 | elif [ $UNCOMMITTED -ne 0 ]; then 65 | ICON="go-top" 66 | TOOLTIP="Uncommited: $UNCOMMITTED" 67 | elif [ $LOCAL = $REMOTE ]; then 68 | # no icon if in sync 69 | ICON="" 70 | elif [ $LOCAL = $BASE ]; then 71 | ICON="bottom" 72 | TOOLTIP="Pull" 73 | elif [ $REMOTE = $BASE ]; then 74 | ICON="up" 75 | TOOLTIP="Push" 76 | else 77 | ICON="dialog-question" 78 | TOOLTIP="Diverged" 79 | fi 80 | 81 | # Send commands to fifo to update tray 82 | echo "icon:$ICON" >&3 83 | echo "tooltip:$TOOLTIP" >&3 84 | 85 | sleep $CHECKTIME 86 | done 87 | 88 | -------------------------------------------------------------------------------- /backup_protectedtext.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # * Backup secrets from www.protectedtext.com to local storage 6 | # * If file is changed, keep previous version with date postfix 7 | # * Only backups once per day 8 | # * Can be decrypted using `base64 -d BACKUP_FILE | openssl aes-256-cbc -d -k PASSWORD` 9 | # * More info 10 | 11 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 12 | 13 | # Usage 14 | # ----- 15 | # Run from commandline or add to cron 16 | 17 | 18 | import urllib.request 19 | import json 20 | import os 21 | import shutil 22 | import datetime 23 | import logging 24 | import sys 25 | 26 | 27 | SECRETS = ["anything"] # name of secret i.e. `https://www.protectedtext.com/anything` → `anything` 28 | PATH = "/media/backup/" 29 | SUCESS_PING_URL = "https://hchk.io/..." # https://healthchecks.io/ url 30 | SECONDS_IN_DAY = 86400 31 | 32 | logging.basicConfig(filename=PATH + 'manager.log', 33 | level=logging.DEBUG, 34 | format='%(asctime)s %(levelname)s %(message)s') 35 | 36 | 37 | def log_except_hook(*exc_info): 38 | exc = "".join(traceback.format_exception(*exc_info)) 39 | logging.critical(exc) 40 | failure(exc) 41 | sys.excepthook = log_except_hook 42 | 43 | logging.debug("Start") 44 | for SECRET in SECRETS: 45 | SECRET_PATH = PATH + SECRET 46 | if os.path.isfile(SECRET_PATH) and (datetime.datetime.now().timestamp() - os.path.getmtime(SECRET_PATH)) < SECONDS_IN_DAY: 47 | logging.debug("Skipping as files were updated today") 48 | exit() 49 | 50 | r = urllib.request.urlopen("https://www.protectedtext.com/%s?action=getJSON" % SECRET) 51 | content = json.loads(r.read().decode("utf-8"))['eContent'] 52 | 53 | if content == "": 54 | logging.debug("There no secret " + SECRET) 55 | exit() 56 | 57 | if os.path.isfile(SECRET_PATH): 58 | f = open(SECRET_PATH, "r") 59 | latest = f.read() 60 | f.close() 61 | if latest == content: 62 | logging.debug("No changes " + SECRET) 63 | continue 64 | shutil.move(SECRET_PATH, SECRET_PATH + datetime.datetime.now().strftime("_%d_%m_%Y")) 65 | 66 | with open(SECRET_PATH, "w") as f: 67 | f.write(content) 68 | logging.debug("Wrote " + SECRET) 69 | 70 | # If app produces exception or exit(), will get error from Healthcheks 71 | urllib.request.urlopen(SUCESS_PING_URL) 72 | -------------------------------------------------------------------------------- /status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Description 4 | # ----------- 5 | # ![Status](https://developer.run/pic/status.png) 6 | # 7 | # CLI web stats dashboard. Visualizes GitHub followers, top GitHub repos and last 500 blog hits 8 | # with top pages and refferers. Works well in addition to [headlines.sh](https://github.com/dmi3/bin/blob/master/headlines.sh) and `newsbeuter -x reload -x print-unread 2> /dev/null` [Read more](https://developer.run/51) 9 | 10 | 11 | # Requirements 12 | # ------------ 13 | # * [spark](https://github.com/holman/spark) (the other spark, not the behemoth one) 14 | # * `sudo apt-get install jq` 15 | 16 | # Usage 17 | # ------------ 18 | 19 | # * Set `URL`, `GITHUB_ID, `PARSE_APP_ID` and `PARSE_MASTER_KEY` variables 20 | # * `status.sh` 21 | 22 | test "$URL" == "" && echo '$URL not set!' 23 | test "$GITHUB_ID" == "" && echo '$GITHUB_ID not set!' 24 | test "$PARSE_APP_ID" == "" && echo '$PARSE_APP_ID not set!' 25 | test "$PARSE_MASTER_KEY" == "" && echo '$PARSE_MASTER_KEY not set!' 26 | 27 | echo -ne "\n ★ Github — " 28 | curl -s "https://api.github.com/users/$GITHUB_ID" | jq -r .followers | awk '{print $0, "followers"}' 29 | curl -s "https://api.github.com/users/$GITHUB_ID/repos" | jq -r "sort_by(.stargazers_count) | reverse [] | [.html_url, .stargazers_count, .forks] | @csv" | head -6 | column -s, -t 30 | 31 | echo -ne "\n 📈 Blog " 32 | BLOG_STATS=$(curl -s -H "X-Parse-Application-Id: $PARSE_APP_ID" -H "X-Parse-Master-Key: $PARSE_MASTER_KEY" -G --data-urlencode 'order=-createdAt' --data-urlencode 'limit=500' https://parseapi.back4app.com/classes/Visitor) 33 | 34 | # Visitors diagramm 35 | echo "$BLOG_STATS" | jq -r ".results | group_by(.createdAt[0:10])[] | [group_by(.token)[]] | length " | spark 36 | # Visitors over last 5 days 37 | echo "$BLOG_STATS" | jq -r ".results | group_by(.createdAt[0:10])[] | [group_by(.token)[]] | [.[0][0].createdAt[0:10], length, (flatten | length), ([flatten | .[] | .country] | unique | join(\" \"))] | @csv" | tail -5 | column -s, -t 38 | # Top 5 pages 39 | echo 40 | echo "$BLOG_STATS" | jq -r '.results | [ group_by(.title)[] | {kw: .[0].title, count: length }] | sort_by(.count) | reverse [] | [.kw[0:50], .count] | @csv' | head -5 | column -s, -t 41 | # Top 5 refferers 42 | echo 43 | echo "$BLOG_STATS" | jq -r ".results | [ .[] | select( .ref != \"\" ) | select( .ref | contains (\"$URL\") | not ) ] | [ group_by(.ref)[] | {kw: .[0].ref, count: length }] | sort_by(.count) | reverse [] | [.kw, .count] | @csv" | head -5 | column -s, -t 44 | -------------------------------------------------------------------------------- /headlines.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # 5 | # Description 6 | # ----------- 7 | # * Prints ground shaking headlines from Hacker News in shell greeting 8 | # * Don't miss next Meltdown, be notified right away! 9 | # * Doesn't distract you if nothing important happened 10 | # * Allows open all news in browser and mark it as read 11 | # * If you prefer simpler version without additional functionality refer [to initial version](https://github.com/dmi3/bin/blob/2fb9f8a894ea4eba5edb13c7135861740de83084/headlines.sh) 12 | # * See for description and more ideas 13 | 14 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 15 | 16 | # Requirements 17 | # ------------ 18 | # sudo apt-get install jq 19 | 20 | # Usage 21 | # ------------ 22 | 23 | # * `headlines.sh` will print latest headlines 24 | # * `headlines.sh read` will open all news in browser and mark it as read (hide) 25 | # - `~/.readnews` stores titles and urls of read news 26 | # - `~/.readnews` might be useful if you want to find article later 27 | # - `~/.readnews` might be synced between computers 28 | # * `headlines.sh clear` will mark all news as read (hide) 29 | # * Add to shell greeting [see screenshot](https://developer.run/pic/headlines.png) 30 | # - 31 | # - OR `chmod 777 /var/run/motd.dynamic` on boot and `headlines.sh > /var/run/motd.dynamic` 32 | # - OR `chmod 777 /var/run/motd.dynamic` on boot and put `0 */2 * * * /path/to/headlines.sh > /var/run/motd.dynamic` to `crontab -e` 33 | # - To read and update greeting use `headlines.sh read > /var/run/motd.dynamic && clear` 34 | 35 | SINCE=$(date --date="5 days ago" +%s) 36 | MAX=3 37 | THRESHOLD=1000 38 | 39 | NEWS=$(curl -s "https://hn.algolia.com/api/v1/search_by_date?numericFilters=points>$THRESHOLD,created_at_i>$SINCE&hitsPerPage=$MAX") 40 | touch ~/.readnews 41 | 42 | if [[ "$1" == "read" ]]; then 43 | echo $NEWS | jq -r '.hits[].url' | grep -vFf ~/.readnews | xargs -L 1 -P $MAX xdg-open >/dev/null 2>&1 & 44 | fi 45 | 46 | if [ "$1" == "read" ] || [ "$1" == "clear" ] ; then 47 | echo $NEWS | jq -r '.hits[] | (.title +"\n" + .url)' | grep -vFf ~/.readnews >> ~/.readnews 48 | fi 49 | 50 | echo " 📰 HEADLINES $(date '+%Y/%m/%d %H:%S')" 51 | echo $NEWS | jq -r "if .nbHits == 0 then \"No news is good news\" else .hits[].title end" | grep -vFf ~/.readnews || echo "All read" 52 | 53 | -------------------------------------------------------------------------------- /notify-append: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Decription 4 | # ----------- 5 | # Script to run append Notify OSD messages as shown on http://thexnews.com/uploads/notify.gif 6 | # Since x-canonical-append is broken in notify-send for example in Skype you will wait forever untill all messages are shown 7 | # This script makes new messages shown in same notification window bellow the already shown 8 | # Created as addition to notify-send. Use notify-send when you want to send notification and notify-append when you want append or replace it. 9 | # [Readme in russian](http://thexnews.com/p/554) 10 | 11 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 12 | 13 | usage = """Usage: 14 | notify-append title name [icon] [-r] 15 | -r - replace previous message instead of appending to it 16 | """ 17 | 18 | import gtk,dbus,dbus.service,dbus.glib,sys 19 | 20 | class NotifyAppendService(dbus.service.Object): 21 | previous_id = 0 22 | 23 | def __init__(self): 24 | bus_name = dbus.service.BusName('net.dmi3.Notify', bus = dbus.SessionBus()) 25 | dbus.service.Object.__init__(self, bus_name, '/net/dmi3/Notify') 26 | 27 | @dbus.service.method(dbus_interface='net.dmi3.Notify') 28 | def notify(self, title, text, icon = "", replace = False): 29 | item = "org.freedesktop.Notifications" 30 | path = "/org/freedesktop/Notifications" 31 | interface = "org.freedesktop.Notifications" 32 | app_name = "Notify Append" 33 | id_num_to_replace = self.previous_id if replace else 0 34 | actions_list = '' 35 | hint = {"x-canonical-append":"allowed"} 36 | time = 1000 # Doesn't matter 37 | 38 | bus = dbus.SessionBus() 39 | notif = bus.get_object(item, path) 40 | notify = dbus.Interface(notif, interface) 41 | self.previous_id = notify.Notify(app_name, id_num_to_replace, icon, title, text, actions_list, hint, time) 42 | 43 | if __name__ == "__main__": 44 | replace = "-r" in sys.argv 45 | if replace: 46 | sys.argv.remove("-r") 47 | 48 | if len(sys.argv)==3: 49 | sys.argv.append("") 50 | elif len(sys.argv)<3: 51 | print(usage) 52 | sys.exit() 53 | 54 | if dbus.SessionBus().request_name("net.dmi3.Notify") != dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER: 55 | notify = dbus.SessionBus().get_object("net.dmi3.Notify", "/net/dmi3/Notify").get_dbus_method("notify") 56 | notify(sys.argv[1],sys.argv[2],sys.argv[3],replace) 57 | else: 58 | service = NotifyAppendService() 59 | service.notify(sys.argv[1],sys.argv[2],sys.argv[3],replace) 60 | gtk.main() #to keep script running 61 | -------------------------------------------------------------------------------- /mus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # Setups MUS (Minimal Usable System). Targets very slow machines with very broken disks and very bad internet, so checks everything. 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Usage 10 | # ----- 11 | # /usr/bin/GET https://raw.githubusercontent.com/dmi3/bin/master/mus.sh > ~/mus.sh && chmod +x ~/mus.sh && ~/mus.sh 12 | 13 | #SIZE=wget --spider https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-10.0.0-amd64-lxde.iso 2>&1 | grep Length | cut -d ' ' -f 2 14 | #SIZE=stat -c '%s' imagename.iso 15 | SIZE=2986344448 16 | 17 | #MD5SUM=curl -s https://cdimage.debian.org/debian-cd/current-live/amd64/bt-hybrid/MD5SUMS | grep lxde.iso | cut -d ' ' -f 1 18 | #MD5SUME="bd025c7ac8556055d7766be8cab5b479 -" 19 | #MD5SUM=curl -s https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/10.8.0-live+nonfree/amd64/iso-hybrid/MD5SUMS | grep lxde+nonfree.iso | cut -d ' ' -f 1 20 | MD5SUME="a1eb37782ef6f3537132a80c49b91d93 -" 21 | 22 | #lsblk | grep RM=1 23 | echo "Checking image md5sum" 24 | MD5SUMA=$(sudo head -c $SIZE /dev/sr0 | md5sum) 25 | 26 | test "$MD5SUME" = "$MD5SUMA" && echo "ok" || echo "Not ok. Expected '$MD5SUME' Got '$MD5SUMA'" 27 | read -p "Continue? (or Ctrl+C)" 28 | 29 | sudo apt-get update 30 | sudo apt-get install curl wget bash-completion firefox-esr encfs keepassxc 31 | sudo apt-get install hplip 32 | 33 | killall clipit 34 | wget -q --show-progress https://raw.githubusercontent.com/dmi3/bin/master/config/clipit/clipitrc -O ~/.config/clipit/clipitrc 35 | nohup clipit& 36 | 37 | #wget -q --show-progress https://github.com/keepassxreboot/keepassxc/releases/download/2.4.3/KeePassXC-2.4.3-x86_64.AppImage 38 | #wget -q --show-progress https://github.com/keepassxreboot/keepassxc/releases/download/2.4.3/KeePassXC-2.4.3-x86_64.AppImage.DIGEST -O ->> /tmp/SHASUMS 39 | #chmod +x KeePassXC-*-x86_64.AppImage 40 | 41 | wget -q --show-progress https://raw.githubusercontent.com/dmi3/bin/master/config/lxterminal/lxterminal.conf -O ~/.config/lxterminal/lxterminal.conf 42 | wget -q --show-progress https://raw.githubusercontent.com/dmi3/bin/master/aliases.bash -O ~/aliases.bash 43 | wget -q --show-progress https://raw.githubusercontent.com/dmi3/bin/master/layoutset -O ~/layoutset 44 | 45 | wget -q --show-progress https://raw.githubusercontent.com/dmi3/bin/master/MD5SUMS -O /tmp/SHASUMS 46 | sha256sum -c --ignore-missing /tmp/SHASUMS 47 | read -p "Continue? (or Ctrl+C)" 48 | 49 | echo "source ~/aliases.bash" >> ~/.bashrc 50 | 51 | 52 | 53 | ~/layoutset 54 | 55 | echo "You can restart terminal now" 56 | -------------------------------------------------------------------------------- /tray-unread.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # 5 | # Decription 6 | # ---------- 7 | # 8 | # Update tray icon depending on script result. Current example shows unread mail count for Evolution mail (for those poor souls who need exchange but don't have web client), but actually it can check and notify about literally anything! 9 | # 10 | # Another example [shows Git repository status](https://github.com/dmi3/bin#tray-git-statussh). 11 | # 12 | # On click simulates some keypresses to mark all mail as read. 13 | # 14 | # Read more: 15 | # * 16 | # * 17 | 18 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 19 | 20 | # Requirements 21 | # ---------- 22 | # 1. `sudo apt-get install yad` 23 | # 2. For Evolution `sudo apt-get install sqlite3 wmctrl xdotool` 24 | 25 | # Usage 26 | # ----- 27 | # tray-unread.sh 28 | 29 | # create a FIFO file, used to manage the I/O redirection from shell 30 | PIPE=$(mktemp -u --tmpdir ${0##*/}.XXXXXXXX) 31 | mkfifo $PIPE 32 | 33 | # attach a file descriptor to the file 34 | exec 3<> $PIPE 35 | 36 | # add handler to manage process shutdown 37 | function on_exit() { 38 | echo "quit" >&3 39 | rm -f $PIPE 40 | } 41 | trap on_exit EXIT 42 | 43 | CHECKTIME=10 44 | MARK_AS_READ="bash -c 'wmctrl -a \" — Evolution\" && xdotool search --onlyvisible --class evolution windowfocus key ctrl+1 sleep 1 key ctrl+a key ctrl+k'" 45 | 46 | # Start tray monitoring the fifo 47 | yad --notification --listen --command="$MARK_AS_READ" <&3 & 48 | 49 | while true 50 | do 51 | # Replace next with script of your choice 52 | UNREAD=$(for i in ~/.cache/evolution/mail/*; do 53 | test $(basename $i) = "trash" && continue 54 | sqlite3 "$i/folders.db" "select count(*) read from INBOX where read == 0" 55 | done | awk '{ SUM += $1} END { print SUM }') 56 | 57 | # Set icon depending $UNREAD = 0 58 | if [ "$UNREAD" == $((0)) ]; then 59 | ICON="mail-read-symbolic" 60 | CHECKTIME=10 61 | else 62 | # Blink icon to get attention 63 | if [ "$ICON" == "mail-unread-symbolic" ]; then 64 | ICON="mail-read-symbolic" 65 | else 66 | ICON="mail-unread-symbolic" 67 | fi 68 | CHECKTIME=1 69 | fi 70 | 71 | # In case Evolution is not running - show error icon 72 | pgrep -x evolution > /dev/null || ICON="error" 73 | 74 | # Send commands to fifo to update tray 75 | echo "icon:$ICON" >&3 76 | echo "tooltip:Unread: $UNREAD" >&3 77 | 78 | sleep $CHECKTIME 79 | done 80 | 81 | -------------------------------------------------------------------------------- /wa: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Description 4 | # ----------- 5 | # 6 | # 7 | # 8 | # 9 | # Using Wolfram Alpha in command line. See [blog post](http://developer.run/37) for description and more ideas. 10 | 11 | 12 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 13 | 14 | # Requirements 15 | # ------------ 16 | # * Make sure to configure variables in script 17 | # * Put [api key](https://products.wolframalpha.com/api/) in `APPID` 18 | # * For `VIEWER`, you can use text only api and **optionaly** use [terminal that supports images](https://developer.run/40) 19 | # **or** `sudo apt-get install imagemagick` to view images. 20 | # * Configure `BG` and `FG` variables depending on color scheme 21 | 22 | # Usage 23 | # ------------ 24 | # ➤ wa helsinki to dublin plane 25 | # 2 hours 20 minutes 26 | # ➤ wa time in dublin 27 | # 5:37:57 pm GMT; Friday, January 27, 2017 28 | # ➤ wa 15.36 english money to eur 29 | # 14.35 euros 30 | # ➤ wa days till nov 16 31 | # 293 days 32 | # ➤ wa 154Mbit/s to MB/s 33 | # 19.2 megabytes per second 34 | # ➤ wa brick red hex 35 | # #AB0303 36 | # ➤ wa weather in moscow 37 | # 9 degrees Celsius and cloudy, with light winds✖ 38 | # ➤ wa plot x=y^2 39 | # [...draws plot if supported] 40 | # ➤ # many many more usages... https://www.wolframalpha.com/examples/ 41 | 42 | 43 | APPID=$(cat ~/git/stuff/keys/wolfram_alpha 2>/dev/null) # Get one at https://products.wolframalpha.com/api/ 44 | VIEWER="kitty +kitten icat" # Use `VIEWER="display"` from imagemagick if terminal does not support images 45 | BG="transparent" # Transparent background 46 | FG="white" # Match color to your terminal 47 | test "$APPID" == "" && echo "\$APPID not set in ${BASH_SOURCE[0]}" 48 | 49 | RESPONSE=$(curl -s "https://api.wolframalpha.com/v1/result?appid=$APPID&units=metric&" --data-urlencode "i=$*" | tee /dev/tty) 50 | 51 | # Remove next if you are fine with text only api, and don't want to see any images 52 | test "No short answer available" = "$RESPONSE"\ 53 | && echo ", downloading full answer..."\ 54 | && curl -s "https://api.wolframalpha.com/v1/simple?appid=$APPID&units=metric&foreground=$FG&background=$BG" --data-urlencode "i=$*" | $VIEWER || exit 0 55 | -------------------------------------------------------------------------------- /todo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/fish 2 | 3 | # Wunderlist CLI for adding todos 4 | # =============================== 5 | 6 | # Decription 7 | # ---------- 8 | # Wrapper for [wl](https://github.com/robdimsdale/wl/releases) for adding todos with more convenient syntax 9 | # [Read More](http://developer.run/15) 10 | 11 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 12 | 13 | # Instalation 14 | # ----------- 15 | # 1. ⚠ Make sure [Fish shell](http://fishshell.com/#platform_tabs) > 2.3.0 16 | # 2. `curl https://raw.githubusercontent.com/dmi3/bin/master/todo --create-dirs -o ~/bin/todo` 17 | # 3. `curl https://raw.githubusercontent.com/dmi3/bin/master/config/fish/completions/todo.fish --create-dirs -o ~/.config/fish/completions/todo.fish` 18 | # 4. 19 | # 5. `[CREATE APP]` (Put https://wunderlist.com to both `APP URL` and `AUTH CALLBACK URL`) 20 | # 6. Set enviroment variables in this script ↓ (line 31) 21 | # 7. Add more list shortcuts ↓ (line 39) 22 | 23 | 24 | # Usage 25 | # ----- 26 | # todo buy stuff --life --on next monday 27 | # todo resolve issue --work --star 28 | # todo --work meet customer --on jan 7 29 | 30 | set -x WL_CLIENT_ID 0000000 # CLIENT ID from https://developer.wunderlist.com/apps 31 | set -x WL_ACCESS_TOKEN 0000000 # [CREATE ACCESS TOKEN] in https://developer.wunderlist.com/apps 32 | set LIST 0000000 # Default list (get id by running `wl inbox`) 33 | 34 | set STAR false 35 | set DATEFMT "+%Y-%m-%d" 36 | set DATE (date $DATEFMT) 37 | 38 | contains -- "--life" $argv; and set LIST 0000000 39 | contains -- "--work" $argv; and set LIST 0000000 40 | # Add more lists here (use `wl lists` to get ids) 41 | contains -- "--star" $argv; and set STAR true 42 | contains -- "--tomorrow" $argv; and set DATE (date $DATEFMT --date="tomorrow") 43 | contains -- "--on" $argv; and set DATE (date $DATEFMT --date=(string replace -r -- ".*--on\s" "" "$argv")) # date --date="next Friday" 44 | 45 | set TITLE (string replace -ra "\-\-\w*\s?" "" -- "$argv" | string trim) #remove arguments starting with -- 46 | 47 | math (echo $version | tr -d .)"<231" > /dev/null; and echo "⚠ Please upgrade fish shell to at least 2.3.0" 48 | 49 | if not type -q wl 50 | set WL_VERSION (curl -Ls -o /dev/null -w "%{url_effective}" https://github.com/robdimsdale/wl/releases/latest | xargs basename | string trim -c "v") 51 | echo "⚠ wl is not found. Installing $WL_VERSION." 52 | curl -L https://github.com/robdimsdale/wl/releases/download/v$WL_VERSION/wl-linux-amd64-$WL_VERSION -o /tmp/wl 53 | chmod +x /tmp/wl; sudo -p "Root password to install wl: " mv /tmp/wl /usr/local/bin/wl; 54 | end 55 | 56 | set result (wl create-task --title="$TITLE" --dueDate=$DATE --listID=$LIST --starred=$STAR) 57 | 58 | if test $status -eq 0 59 | echo $result | grep 'title\|starred\|due_date' 60 | else 61 | echo $result 62 | end 63 | 64 | -------------------------------------------------------------------------------- /sssh2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ----------- 5 | # Like [sssh](https://github.com/dmi3/bin/blob/master/sssh), in addition: 6 | # * `hostname` parameter of [ssh command](https://manpage.me/?q=ssh) will appear in title. 7 | # - Useful when calling by nickname from local `~/.ssh/config` i.e. `ssh server_nickname`, and change of server hostname is not an option. 8 | # * If command supports tunneling, display it in title 9 | # - I.e. `ssh -L 80:localhost:80 server_nickname` will set title `user@[80]server_nickname` 10 | # - Avoid accidental closing of such tabs 11 | # * Appends some useful [aliases](https://github.com/dmi3/fish/blob/master/aliases.fish) to existing `~/.bashrc` 12 | # * Preserves command history on multiple sessions 13 | # 14 | # Usage 15 | # ----- 16 | # See [sssh](https://github.com/dmi3/bin/blob/master/sssh) 17 | 18 | get_first_non_option() { 19 | SKIP_NEXT=false 20 | for arg in "$@"; do 21 | if [[ $arg == -* ]] ; then 22 | SKIP_NEXT=true 23 | elif [[ $arg == *:*:* ]] ; then 24 | echo $arg | cut -d: -f1 | xargs -I "{}" printf "[{}]" 25 | SKIP_NEXT=false 26 | elif $SKIP_NEXT ; then 27 | SKIP_NEXT=false 28 | else 29 | echo $arg; return 0 30 | fi 31 | done 32 | } 33 | 34 | NICKNAME=$(get_first_non_option "$@") 35 | 36 | CUSTOM_TITLE="🖧 \$USER@$NICKNAME" 37 | CUSTOM_PS1='$(tput bold)\]\[$(tput setaf 2)\][\u@'$NICKNAME' \w]\n🖧 \[$(tput sgr0)\]' 38 | CUSTOM_RC=" 39 | alias sudo=\"sudo \" 40 | alias ll=\"ls -lh\" 41 | alias ff=\"find \$PWD -iname\" 42 | alias mkdir=\"mkdir -pv\" 43 | alias path=\"readlink -e\" 44 | alias untar=\"tar -vxzf\" 45 | alias sizeof=\"du -hs\" 46 | alias fs=\"df -h -x squashfs -x tmpfs -x devtmpfs\" 47 | alias myip=\"curl ifconfig.co\" 48 | alias getmicro=\"curl https://getmic.ro | bash && sudo mv ./micro /usr/local/bin/\" 49 | alias getsssh2=\"wget https://raw.githubusercontent.com/dmi3/bin/master/sssh2 && chmod +x sssh2 && sudo mv ./sssh2 /usr/local/bin/\" 50 | alias micro=\"micro -mouse false \" 51 | alias temp=\"watch sudo vcgencmd measure_temp\" 52 | run() { 53 | chmod +x \"\$1\" 54 | exec \"./\$1\" & 55 | } 56 | mkcd () { 57 | mkdir \"\$1\" 58 | cd \"\$1\" 59 | } 60 | bak () { 61 | cp \"\$1\" \"\$1.bak\" 62 | } 63 | shopt -s histappend 64 | export HISTCONTROL=ignoreboth 65 | export PROMPT_COMMAND=\"history -a; PS1=\\\"$CUSTOM_PS1\\\"\" 66 | test -e /usr/share/doc/fzf/examples/key-bindings.bash && source /usr/share/doc/fzf/examples/key-bindings.bash 67 | type sssh2 &> /dev/null && alias ssh=sssh2 68 | echo -e \"\033]0;$CUSTOM_TITLE\a\" 69 | " 70 | PREV_TITLE=`xdotool getwindowfocus getwindowname` 71 | 72 | echo -e "\033]0;$NICKNAME\a" 73 | 74 | /usr/bin/ssh -t "$@" " 75 | SSSH_RC=\$(mktemp) 76 | cp ~/.bashrc \$SSSH_RC 77 | echo '$CUSTOM_RC' >> \$SSSH_RC 78 | bash --rcfile \$SSSH_RC 79 | rm \$SSSH_RC" 80 | 81 | echo -e "\033]0;$PREV_TITLE\a" 82 | -------------------------------------------------------------------------------- /snippy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Decription 4 | # ---------- 5 | # System wide text snippet expander. Simulates cut→replace→paste so works in almost any application. Examples: 6 | # * Type `->`, press hotkey, get `→`. 7 | # * Type `thx`, press hotkey, get `Thank you`. 8 | # 9 | # Original idea by [sessy](https://bbs.archlinux.org/viewtopic.php?id=71938) and [Linux Magazine](http://www.linux-magazine.com/Issues/2014/162/Workspace-Text-Expander) with following improvements: 10 | # * Works as keybinding in Compiz/Unity/Openbox 11 | # * Does not go crazy if keybinding includes Ctrl, Alt, Shift... 12 | # * Works in Sublime Text/IntelliJ Idea/Chrome/Slack 13 | # * Expands snippets without preceding space i.e. `30eur` to `30€` 14 | # - If snippet needs preceding space or start of line - use regexp `\b` i.e. `s/\bv$/✔/g;` converts `v` to `✔` only if its separate symbol 15 | # * Expands snippets with symbols i.e. `->` to `→` 16 | # * Expands commands i.e. `now` to formatted todays date, `mon` to to formatted next mondays date 17 | # * Stores all snippets in one file 18 | # * Works with Ubuntu 16.04 19 | 20 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 21 | 22 | # Requirements 23 | # ---------- 24 | # `sudo apt-get install xdotool xclip xsel` 25 | 26 | # Usage 27 | # ----- 28 | # * Bind script to hotkey in your DE, for example Shift+Tab. 29 | # * Add new snippets after line 30, in format `s/SHORCUT$/REPLACEMENT/g;` 30 | 31 | snippets=" 32 | s/<->$/⇄/g; 33 | s/-^$/↑/g; 34 | s/<-$/←/g; 35 | s/->$/→/g; 36 | s/-$/—/g; 37 | s/~$/≈/g; 38 | s/!$/⚠/g; 39 | s/\bv$/✔/g; 40 | s/\bx$/✖/g; 41 | s/\?$/❓/g; 42 | s/>$/❯/g; 43 | s/+-$/±/g; 44 | s/tm$/™/g; 45 | s/larr$/←/g; 46 | s/rarr$/→/g; 47 | s/darr$/↓/g; 48 | s/uarr$/↑/g; 49 | s/copy$/©/g; 50 | s/eur$/€/g; 51 | s/20$/⓴/g; 52 | s/19$/⓳/g; 53 | s/18$/⓲/g; 54 | s/17$/⓱/g; 55 | s/16$/⓰/g; 56 | s/15$/⓯/g; 57 | s/14$/⓮/g; 58 | s/13$/⓭/g; 59 | s/12$/⓬/g; 60 | s/11$/⓫/g; 61 | s/10$/➓/g; 62 | s/9$/➒/g; 63 | s/8$/➑/g; 64 | s/7$/➐/g; 65 | s/6$/➏/g; 66 | s/5/➎/g; 67 | s/4$/➍/g; 68 | s/3$/➌/g; 69 | s/2$/➋/g; 70 | s/1$/➊/g; 71 | s/0$/⓿/g; 72 | s/sim$/simultaneously/g; 73 | s/unf$/unfortunately/g; 74 | s/env$/environment/g; 75 | s/suc$/successful/g; 76 | s/misc$/miscellaneous/g; 77 | s/thx$/Thank you\./g; 78 | s/br$/Regards,\nDmitry/g; 79 | s/bus$/business/g; 80 | s/now$/$(date +'%a %d\/%m\/%y')/g; 81 | s/mon$/$(date +'%a %d\/%m\/%y' --date='next mon')/g; 82 | s/tue$/$(date +'%a %d\/%m\/%y' --date='next tue')/g; 83 | s/wed$/$(date +'%a %d\/%m\/%y' --date='next wed')/g; 84 | s/thu$/$(date +'%a %d\/%m\/%y' --date='next thu')/g; 85 | s/fri$/$(date +'%a %d\/%m\/%y' --date='next fri')/g; 86 | s/sat$/$(date +'%a %d\/%m\/%y' --date='next sat')/g; 87 | s/sun$/$(date +'%a %d\/%m\/%y' --date='next sun')/g;" 88 | 89 | xdotool --clearmodifiers keyup Control_L Control_R Shift_L Shift_R Alt_L Alt_R 90 | sleep 0.1 91 | xdotool key ctrl+shift+Left 92 | sleep 0.05 93 | xdotool key ctrl+x 94 | sleep 0.05 95 | selection=`xsel -b` 96 | echo -n "$selection" | sed "$snippets" | xclip -sel clip 97 | xdotool key ctrl+v 98 | -------------------------------------------------------------------------------- /itunec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Mounts USB device, syncs new podcast in gpodder then umounts device 6 | 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Requirements 10 | # ------------ 11 | # 1. `sudo apt-get install python3 id3v2` 12 | # 2. `wget https://raw.github.com/dmi3/bin/master/notify-append -P ~/bin && chmod +x ~/bin/notify-append` 13 | 14 | # Usage 15 | # ----- 16 | # 1. set LABEL to label of your player filesystem (for example `SANSA CLIP` to find label type `ls -l /dev/disk/by-label/`) 17 | # 2. set GPODDER_DIR to directory where gpodder download podcasts 18 | # 3. run `itunec` when you want to sync 19 | # or 20 | # 1. gpodder -> Podcasts -> Prefences -> Devices; set Device type to `Filesystem-based` and `Mountpoint` path where device is mounted by default 21 | # 2. gpodder -> Podcasts -> Prefences -> Edit config -> cmd_all_download_complete -> itunec 22 | 23 | LABEL = "AUDIOS" 24 | GPODDER_DIR = "/media/archive/incoming/gpodder/" 25 | 26 | import os,sys,time 27 | from sh import ls,udisks,ErrorReturnCode_1,traceback,gpo,zenity,find,notify_append,id3v2 28 | 29 | def fix_tags(dirsa): 30 | for root, subFolders, files in os.walk(dirsa): 31 | for f in files: 32 | if f.count(".mp3")>0 and not is_russian(root): 33 | show_title=os.path.basename(root) 34 | path=os.path.join(root,f) 35 | 36 | try: 37 | if (id3v2("-l",path).count("TAL") == 0): 38 | id3v2("-A",show_title,path) 39 | except UnicodeDecodeError: 40 | print("Error reading %s" % path) 41 | 42 | 43 | def is_russian(s): 44 | for letter in "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ": 45 | if s.count(letter)>0: 46 | return True 47 | return False 48 | 49 | def notify(text): 50 | notify_append("Itunec",text) 51 | 52 | def gpodder_has_new_episodes(): 53 | return not find(GPODDER_DIR,"-name","*.mp3")=="" 54 | 55 | try: 56 | if not gpodder_has_new_episodes(): 57 | notify("No new episodes") 58 | sys.exit() 59 | 60 | #Find device by LABEL 61 | devices = ls("-l","/dev/disk/by-label/") 62 | device = next(x for x in devices if LABEL in x) 63 | devid = device.split("/")[-1] 64 | devpath = "/dev/"+devid.replace("\n","") 65 | 66 | #Mount device 67 | mntmsg = udisks("--mount",devpath) 68 | wasmnt = "is mounted" in mntmsg 69 | if not wasmnt: 70 | notify(mntmsg) 71 | 72 | fix_tags(GPODDER_DIR) 73 | notify("Starting synchronization") 74 | gpo("sync") 75 | 76 | time.sleep(3) 77 | 78 | #Umount device 79 | if not wasmnt: 80 | mntmsg = udisks("--unmount",devpath) 81 | if mntmsg == "": 82 | zenity("--info","--text","Its now safe to remove "+LABEL) 83 | else: 84 | notify(mntmsg) 85 | else: 86 | zenity("--info","--text","Sync done") 87 | 88 | except StopIteration: 89 | notify("Unable to find device "+LABEL) 90 | except ErrorReturnCode_1: 91 | notify("Unable to mount device "+LABEL) 92 | except Exception: 93 | notify("Unknown problem during sync") 94 | traceback.print_exc() 95 | 96 | -------------------------------------------------------------------------------- /SHASUMS: -------------------------------------------------------------------------------- 1 | ca2abdf695884c77ea4b4a5b64ca7b732d9d9dbade4eebc1c2e76c53e9e3bc83 LICENSE.txt 2 | 720e699a484f7cceb97f456f13dd87e293074f67777668f58d7632a7ed8102cb README.md 3 | 339a546f886dbe054916443ef53058fc13adba57840759a4ac7fba83fa11ec1c aliases.bash 4 | 648e9493a3f0707a671a8bec8cfa3c96acb5a590e662f972fc5eafef45f265a0 backup_protectedtext.py 5 | a6ea715abdbe52a6762c89e57b5d27d3674dd2aefde56f386ec7c6307f53b4b2 batch-rename.py 6 | fe71e869fb35644f0443428ebe182edf547d974fef234b76b115c8df1b22fb48 battery 7 | 5d623aae39ce89d82734bfe74b4bcfe1a1bab428611f6f877e8845a35fd84d30 bookmarks 8 | 22da6198c3bd376e21622f1a00c4b00d04772e4299e494d8c0186ec79251ec4e center-mouse-active-window.py 9 | 3abf36463419a8f309e58303484c3c26d1dd5b91d821bfb475ccc7a0b96eb2c1 control-panel 10 | 7b13c8cfa7056c47a8b173a7bed090e65d4398d4cd19dea7a6f2b24447ac1663 doom 11 | 8a1bb8c03e1e59264c29d1cbc9ac737b36f2417aa8d4e2eb7239d23390bdd56c duplicati-ping.py 12 | 7425269bbdd19d59ba9b7c1f7266d1b3aa38b0641b3077a97be1e50cbf9460c9 ec2ssh.sh 13 | dcd67d8e3838b4765e6a362c1909a0cb47746220ac93fc3c1e0a5735865dcc1c ex-spotify-playlist.sh 14 | 59dc0d67a3fc26e060fe2c5082bf39bedaf22e9c71d42873d0315d32d40dfd26 game-screenshot.sh 15 | c9ebc2b748147ed0266fa62d314e926bf0812a1ff05d227027e96fbd4d27d79f generate-readme.fish 16 | 264becc5996c3a52eed06ab92fe21d398576874eb5f57ea0f3754751056bfc10 git-sync 17 | 61f126b3776cd923946d22a83b0193f70c3dd7daa6e3b91827e1766ad02bb915 headlines.sh 18 | ee4b6279c4a0c220047642e3cb7f9a311b401a991cda576f51573eac569ab5a1 itunec 19 | 7dada745e6608fddb72c3a7c0dcc7bf8667c09031f9a5fd2de70ce8a59d9d2e2 knok 20 | 4e1628d991fd5039f40db35d7eb2e1dee59f9fbb9850b7feb11d6687d1d36058 layoutset 21 | 8478040ec6cdd0eb17a261922fa4d7d015a1fc3878e8c4c6bf70bd11a42455d7 memory-available.sh 22 | 5ccefba464f811e4d38f154f1adf34a998ef43c0f2e9ed83f23eb8e0488c71a9 mus.sh 23 | 513050ff957c253cf93a1c199578f650221a0e29c091eacb3c7500b206d6418a notify-append 24 | ff9c36e36862e0a724f949577bc9ff51621507c86914e606b26b23b73f9d8ca4 plug 25 | 1d56b9a55df1ff3b9605e64386de3f14be9d4891ee8ec6523fd058b4a11358c0 poweroff 26 | 0d59b09c03a5f7070c4be91a3bd29d3ff7541d093b7650d9e976617d9ecaa75c print-numbers.py 27 | de08f64edfbc8ac6cdfb1707c48ea111083be12d57c18cf52c16a5bb8e0b4192 reboot 28 | 85613ebcacd33171a53df60522bf893ce572d60bb0e4f1dc06d6dcbe4e8d669f rundesktop 29 | abfc84665f5c61c31e195af20dd8a24d25e3d16b8bf657b766d2d555ff6a0a0d skypenotify 30 | 90d03cbc9f4f92a4c936de79b615dd1d8a06560bf9603da3d11ba516717cb3a5 snippy.sh 31 | cdcb273bcb1a61d20d7bb08086522d95428f3a0e6a7cc0bc00a37a4654093aa1 sssh 32 | ff84759b8aed886c99bc5f5872d4525b3ed04be6a46cbf34592a64e8c3653a6b sssh2 33 | 9575024de64538eb441590c0c354e2d345d0712377328088471b3d1d6e46db18 status.sh 34 | 773a1880395b617b7d87120d9cf159f0c949b6e25628171563f31fa6dbbb121a temp.sh 35 | 6a55b355f4bb8f1c44339d7b2e2c64681912b9c895dd0c4f2b19ac3b0737eafd timer 36 | d136fc3df8c9e202feff83e8da9ebfd589644eb64ca1a4c0045a3de749290e91 todo 37 | b45f01fda084f4eb505e8eb6ab4a9de7ab0f0c84cf344c52e56ae4304dfbb923 tomatych.py 38 | 9c0af29df38d68d3e3e1d817b3cd6b0659311631833487aedd7fb5dd2c635d0f translate-selection.sh 39 | 458ba52702f984d1517bfea393dc2bdee6d990064684773a29e71c079e7f0139 translate-yandex.sh 40 | b51f73fdd47451e6f32479463841f283421b6d8130aa3bcc59f6fe479fb8dd54 translation-insert.sh 41 | 02d72d6b4668066c64bc1c4e7813bbbeb96c7ab28e48f83e008153ff5f090759 tray-git-status.sh 42 | 131bbeb6c5f9cf6fc1d4ef484edfe003936fab9c5f2cbbba1abf570847f7160c tray-unread.sh 43 | 1d876fd3425c83099dcac7f83ec511442a0480a371afe35408c270fdfd548126 url-preview-md.py 44 | db13d158c52164edad8000f12d61a5d203af3ce819b54a67438a5994cdadb3b7 vlc-now.sh 45 | d52b5d82c0d2a4b9e857ed572c9c9f880eb045204a70cc7ae897f21aef158555 volume 46 | 5db3f259919cfc0dc8204509fc22b43a74defab022ee8bd1a84d966e5a74b6d9 wa 47 | f375a4809660a7e420bb6b5b5e4936644e30a19adea8abcf681ba71a69c724b0 wimg.sh 48 | -------------------------------------------------------------------------------- /aliases.bash: -------------------------------------------------------------------------------- 1 | # Decription 2 | # ----------- 3 | # Some handy bash aliases and settings. 4 | # 5 | # ⚠ You may find more useful commands in [Fish shell aliases](https://github.com/dmi3/fish#aliasesfish) (which is easily portable to Bash) 6 | # 7 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 8 | 9 | # Usage 10 | # ----- 11 | # 1. `wget https://raw.githubusercontent.com/dmi3/bin/aliases.bash --no-check-certificate -O ~/bin/aliases.bash` 12 | # 2. `echo "source ~/bin/aliases.bash" >> ~/.bashrc` 13 | # 3. To make bash more usable you probably want to install https://github.com/mrzool/bash-sensible 14 | # 4. To make this work across remote machines, you also may want to install https://github.com/Russell91/sshrc 15 | 16 | # Create missing directories in path 17 | alias mkdir='mkdir -pv' 18 | 19 | # Print full file path 20 | alias path='readlink -e' 21 | 22 | # Remove directories but ask nicely 23 | alias rmm='rm -rvI' 24 | 25 | # Copy directories but ask nicely 26 | alias cpp='cp -R' 27 | 28 | # add current directory to path 29 | alias add-to-path='set -U fish_user_paths (pwd) $fish_user_paths' 30 | 31 | # Human readable sizes (i.e. Mb, Gb etc) 32 | alias df='df -h' 33 | alias du='du -ch' 34 | alias free='free -m' 35 | 36 | alias xs='cd' 37 | 38 | alias ...='cd ../..' 39 | 40 | # Free space on physical drives 41 | alias fs='df -h -x squashfs -x tmpfs -x devtmpfs' 42 | 43 | # Lists disks 44 | alias disks='lsblk -o HOTPLUG,NAME,SIZE,MODEL,TYPE | awk "NR == 1 || /disk/"' 45 | 46 | # List partitions 47 | alias partitions='lsblk -o HOTPLUG,NAME,LABEL,MOUNTPOINT,SIZE,MODEL,PARTLABEL,TYPE | grep -v loop' 48 | 49 | # Size of file or directory 50 | alias sizeof="du -hs" 51 | 52 | # Connect to wifi 53 | alias connect=nmtui 54 | 55 | # Prevent locking untill next reboot 56 | alias lockblock='killall xautolock; xset s off; xset -dpms; echo ok' 57 | 58 | # Save file with provided name 59 | alias wget='wget --content-disposition' 60 | 61 | # Resolve aliases after sudo 62 | alias sudo='sudo ' 63 | 64 | alias ff="find $PWD -iname" 65 | alias untar="tar -vxzf" 66 | 67 | alias myip='curl ifconfig.co' 68 | alias getmicro='curl https://getmic.ro | bash && sudo mv ./micro /usr/local/bin/' 69 | 70 | # Aliases 71 | mkcd () { 72 | mkdir "$1" 73 | cd "$1" 74 | } 75 | 76 | # Open file in GUI associated application 77 | alias open=xdg-open 78 | 79 | alias ll='ls -lh' 80 | 81 | # Serves current directory on 8080 port 82 | alias server-here='twistd -no web --path=.' 83 | 84 | # Human readable sizes (i.e. Mb, Gb etc) 85 | alias df='df -h' 86 | alias du='du -ch' 87 | alias free='free -g' 88 | 89 | # Adding repositories without prompt, automatically adding sudo 90 | add-apt-repository() { 91 | sudo add-apt-repository --yes $* 92 | sudo apt-get update 93 | } 94 | 95 | # Prepend `sudo` to `nano` command if file is not editable by current user 96 | nano() { 97 | if [ -w "$1" ] 98 | then 99 | /bin/nano $* 100 | else 101 | sudo /bin/nano $* 102 | fi 103 | } 104 | 105 | # Make file executable, then run it 106 | run() { 107 | chmod +x "$1" 108 | exec "./$1" & 109 | } 110 | 111 | bak () { 112 | mv "$1" "$(basename $1).bak" 113 | } 114 | 115 | # If Sublime Text installed - use it istead of Gedit 116 | if hash subl 2>/dev/null; then 117 | alias gedit=subl 118 | fi 119 | 120 | # Add sudo if forgotten 121 | if [ $UID -ne 0 ]; then 122 | alias susp='sudo /usr/sbin/pm-suspend' 123 | alias apt-get='sudo apt-get' 124 | alias dpkg='sudo dpkg' 125 | alias apt='sudo apt' 126 | fi 127 | 128 | alias poweroff='shutdown -P now' 129 | alias reboot='shutdown -r now' 130 | 131 | 132 | # Send terminate on Ctrl+Shift+C to free Ctrl+C for copy 133 | stty intr \^C 134 | 135 | # Setup prompt 136 | PS1='\[$(tput bold)\]\[\033[38;5;243m\][\w❯\n$ \[$(tput sgr0)\]' 137 | 138 | # History settings 139 | shopt -s histappend 140 | shopt -s cmdhist 141 | HISTSIZE=500000 142 | HISTFILESIZE=100000 143 | HISTCONTROL="erasedups:ignoreboth" 144 | PROMPT_COMMAND='history -a' 145 | export HISTIGNORE="&:[ ]*:exit:ls:bg:fg:history:clear" 146 | 147 | # Use FZF if installed 148 | test -e /usr/share/doc/fzf/examples/key-bindings.bash && source /usr/share/doc/fzf/examples/key-bindings.bash 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | # Config for [Kitty](https://sw.kovidgoyal.net/kitty/) with custom hotkeys, nicer color scheme and some useful tweaks 2 | # Refer to [original documentation](https://sw.kovidgoyal.net/kitty/conf.html) for more options 3 | 4 | # Use Fish shell 5 | shell /usr/bin/fish 6 | 7 | # The console editor [micro](https://micro-editor.github.io/) to use when editing the kitty config file or similar tasks. 8 | editor micro 9 | 10 | # Allow other programs to control kitty. 11 | allow_remote_control yes 12 | 13 | # The value of the TERM environment variable to set. Set for compatibility 14 | term xterm-256color 15 | 16 | # Font config 17 | font_family JetBrains Mono 18 | font_size 13.0 19 | disable_ligatures always 20 | 21 | # Do not open URLs just by a single click 22 | mouse_map left click ungrabbed no-op 23 | 24 | # The modifier keys to press when clicking with the mouse on URLs to open the URL 25 | mouse_map ctrl+left click ungrabbed mouse_handle_click selection link prompt 26 | 27 | # Disable the audio bell. Useful in environments that require silence. 28 | enable_audio_bell no 29 | 30 | # Draw only the minimum borders needed. 31 | draw_minimal_borders yes 32 | 33 | # The color for the border of the active window 34 | active_border_color #eee 35 | 36 | # Fade the text in inactive windows by the specified amount 37 | inactive_text_alpha 0.6 38 | 39 | # Which edge to show the tab bar on, top or bottom 40 | tab_bar_edge top 41 | 42 | # The tab bar style 43 | tab_bar_style powerline 44 | tab_powerline_style slanted 45 | 46 | # Full width tab bar 47 | tab_bar_background #999999 48 | 49 | 50 | # Color theme: relaxed (see https://developer.run/36 about theming) 51 | active_tab_font_style normal 52 | active_tab_background #667a90 53 | foreground #d9d9d9 54 | background #353a44 55 | color0 #151515 56 | color8 #636363 57 | color1 #bc5653 58 | color9 #bc5653 59 | color2 #909d63 60 | color10 #a0ac77 61 | color3 #ebc17a 62 | color11 #ebc17a 63 | color4 #6a8799 64 | color12 #7eaac7 65 | color5 #b06698 66 | color13 #b06698 67 | color6 #c9dfff 68 | color14 #acbbd0 69 | color7 #d9d9d9 70 | color15 #f7f7f7 71 | 72 | # Hotkeys 73 | clear_all_shortcuts yes 74 | 75 | # Reload config on f5 76 | map f5 load_config_file 77 | 78 | # Copy paste consistent with other programs 79 | map ctrl+shift+c no_op 80 | map ctrl+c copy_to_clipboard 81 | map ctrl+v paste_from_clipboard 82 | map shift+insert paste_from_clipboard 83 | 84 | # Send SIGINT (Ctrl+C) on ctrl+shift+c (see https://developer.run/36) 85 | map ctrl+shift+c send_text all \x03 86 | 87 | # See https://sw.kovidgoyal.net/kitty/conf/#scrollback 88 | scrollback_lines 10000 89 | # F1 to open current screen in editor (Sublime Text) for search 90 | map F1 show_scrollback 91 | # Filter out ANSI escape sequences first 92 | scrollback_pager sh -c 'perl -pe "s/\e\[?.*?[mG]//g" | subl -' 93 | # When opening in Sublime text, set text limit to 50MB 94 | scrollback_pager_history_size 50 95 | 96 | # Hotkeys: tabs/windows 97 | map ctrl+` new_window_with_cwd 98 | map ctrl+f4 close_window 99 | map super+tab next_window 100 | map alt+enter move_window_to_top 101 | map ctrl+pgup prev_tab 102 | map ctrl+pgdn next_tab 103 | map ctrl+t new_tab !neighbor 104 | 105 | map alt+right move_tab_forward 106 | map alt+left move_tab_backward 107 | map f2 set_tab_title 108 | map shift+f6 set_tab_title 109 | 110 | map ctrl+1 goto_tab 1 111 | map ctrl+2 goto_tab 2 112 | map ctrl+3 goto_tab 3 113 | map ctrl+4 goto_tab 4 114 | map ctrl+5 goto_tab 5 115 | map ctrl+6 goto_tab 6 116 | map ctrl+7 goto_tab 7 117 | map ctrl+8 goto_tab 8 118 | map ctrl+9 goto_tab 9 119 | 120 | # Hotkeys: layout management 121 | map alt+` next_layout 122 | 123 | # Hotkeys: font size 124 | map ctrl+equal change_font_size all +2.0 125 | map ctrl+minus change_font_size all -2.0 126 | map ctrl+0 change_font_size all 0 127 | 128 | # Clear screen (universal, will work over ssh, python etc) 129 | map ctrl+l combine : clear_terminal active : send_text normal \x0c 130 | 131 | # No nagging about updates 132 | update_check_interval 0 133 | 134 | # Disable "The text to be pasted contains terminal control codes." 135 | paste_actions quote-urls-at-prompt,confirm-if-large 136 | -------------------------------------------------------------------------------- /url-preview-md.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Decription 4 | # ----------- 5 | # Wrapper around [webpreview](https://pypi.org/project/webpreview/). Takes url, downloads a preview image 6 | # (or image iself, if url points to image) and returns formatted markdown with page title and description. 7 | # Useful with clipboard manager. [Read more](https://developer.run/70) 8 | 9 | # Requirements 10 | # ------------ 11 | # pip install webpreview 12 | 13 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin) 14 | 15 | # Usage 16 | # ----- 17 | # $ url-preview-md.py img_directory url 18 | # $ url-preview-md.py ~/img http://developer.run/70 19 | # [Markdown Url Preview](http://developer.run/70) Markdown Url Preview in text editor. 20 | # ![](/home/dmi3/img/2023_09_01_developer.run_url-preview-md.png) 21 | # 22 | # If you have raindrop.io api key, add it as last argument to try it if webpreview finds nothing useful 23 | # $ url-preview-md.py ~/img http://developer.run/70 e2b0e47c-8a03-11ef-b1b2-13950b80fc62 24 | 25 | 26 | import os 27 | import re 28 | import sys 29 | import shutil 30 | import requests 31 | from urllib.parse import urlparse, urljoin, quote_plus 32 | from datetime import datetime 33 | from webpreview import webpreview 34 | from webpreview.models import WebPreview 35 | 36 | d = os.path.expanduser(sys.argv[1]) 37 | os.makedirs(d, exist_ok = True) 38 | 39 | url = sys.argv[2] 40 | raindrop_api_key = sys.argv[3] if len(sys.argv) > 3 else None 41 | 42 | headers = {"Accept": "*/*", "Origin": "https://google.com", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"} 43 | exclusions = ["amazon.", "x.com", "twitter.com", "youtube.com"] 44 | timeout = 3 45 | 46 | if url.startswith("file://"): 47 | file_path = url[7:] 48 | file_name = os.path.basename(file_path) 49 | path = os.path.join(d, file_name) 50 | shutil.copy(file_path, path) 51 | print("\n![](%s)" % path) 52 | exit() 53 | 54 | p = WebPreview(url, None, None, None) 55 | 56 | if all(x not in url for x in exclusions): 57 | try: 58 | p = webpreview(url, headers=headers, timeout=timeout) 59 | 60 | # If link is image - use it 61 | if p.title == None and p.description == None and p.image == None: 62 | h = requests.head(url, allow_redirects=True, headers = headers, timeout=timeout) 63 | 64 | content_type = h.headers.get('content-type') 65 | if content_type != None and content_type.startswith('image/'): 66 | p.image = url 67 | except: 68 | print("Unable to fetch url:" + url) 69 | 70 | # if failed or url was excluded - try external service 71 | try: 72 | if raindrop_api_key != None and p.image == None: 73 | response = requests.get( 74 | f"https://api.raindrop.io/rest/v1/import/url/parse?url={url}", 75 | headers={"Authorization": f"Bearer {raindrop_api_key}"}, 76 | timeout=timeout 77 | ) 78 | data = response.json() 79 | 80 | item = data['item'] 81 | 82 | img = item.get('cover') 83 | title = item.get('title') 84 | description = item.get('excerpt')[:400] 85 | 86 | p = WebPreview(url, title, description, img) 87 | except: 88 | print("Unable to fetch url:" + url) 89 | exit() 90 | 91 | image = "" 92 | if (p.image): 93 | try: 94 | u = p.image 95 | if not u.startswith("http"): 96 | u = urljoin(url, p.image) 97 | r = requests.get(u, allow_redirects=True, headers = headers, timeout=timeout) 98 | a = urlparse(url) 99 | i = urlparse(u) 100 | filename = "_".join([datetime.now().strftime("%Y_%m_%d"), a.netloc, os.path.basename(i.path)]) 101 | filename = re.sub(r"[^A-Za-z0-9._-]+", "", filename) 102 | filename, ext = os.path.splitext(filename.lstrip("/")) 103 | if ext == "": 104 | ext = ".png" 105 | 106 | path = os.path.join(d, filename + ext) 107 | pcnt = 1 108 | 109 | while os.path.exists(path): 110 | path = os.path.join(d, "%s_%s%s" % (filename, pcnt, ext)) 111 | pcnt += 1 112 | 113 | open(path, 'wb').write(r.content) 114 | image = "\n![](%s)" % path 115 | except requests.exceptions.RequestException: 116 | image = " Unable to fetch image: " + u 117 | except: 118 | image = " Unable to save image (check that name and path is correct): " + path 119 | 120 | descr = "" 121 | if (p.description): 122 | descr = " " + p.description 123 | 124 | a = "<%s>" % url 125 | if (p.title): 126 | a = "[%s](%s)" % (p.title, url) 127 | 128 | print(a + descr + image) 129 | 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Useful scripts for Linux users 2 | See my [Fish config](https://github.com/dmi3/fish) for more CLI awesomness 3 | 4 | # [wa](https://github.com/dmi3/bin/blob/master/wa) 5 | 6 | 7 | Description 8 | ----------- 9 | 10 | 11 | 12 | 13 | Using Wolfram Alpha in command line. See [blog post](http://developer.run/37) for description and more ideas. 14 | 15 | Requirements 16 | ------------ 17 | * Make sure to configure variables in script 18 | * Put [api key](https://products.wolframalpha.com/api/) in `APPID` 19 | * For `VIEWER`, you can use text only api and **optionaly** use [terminal that supports images](https://developer.run/40) 20 | **or** `sudo apt-get install imagemagick` to view images. 21 | * Configure `BG` and `FG` variables depending on color scheme 22 | 23 | Usage 24 | ------------ 25 | ➤ wa helsinki to dublin plane 26 | 2 hours 20 minutes 27 | ➤ wa time in dublin 28 | 5:37:57 pm GMT; Friday, January 27, 2017 29 | ➤ wa 15.36 english money to eur 30 | 14.35 euros 31 | ➤ wa days till nov 16 32 | 293 days 33 | ➤ wa 154Mbit/s to MB/s 34 | 19.2 megabytes per second 35 | ➤ wa brick red hex 36 | #AB0303 37 | ➤ wa weather in moscow 38 | 9 degrees Celsius and cloudy, with light winds✖ 39 | ➤ wa plot x=y^2 40 | [...draws plot if supported] 41 | ➤ # many many more usages... https://www.wolframalpha.com/examples/ 42 |
43 | 44 | # [volume](https://github.com/dmi3/bin/blob/master/volume) 45 | 46 | 47 | Decription 48 | ----------- 49 | Script to control audio volume from console, hotkeys, e.t.c. Also shows nice Notify OSD buble with current volume value 50 | 51 | Requirements 52 | ------------ 53 | sudo apt-get install pulseaudio notify-osd 54 | 55 | Usage 56 | ----- 57 | volume (up|down|mute) 58 | # $volume without trailing % 59 | kbecho.py p ${volume%?} 60 |
61 | 62 | # [vlc-now.sh](https://github.com/dmi3/bin/blob/master/vlc-now.sh) 63 | 64 | 65 | Description 66 | ----------- 67 | Show file or stream currently playing in VLC. Works well with (with xfce4-genmon-plugin). See `playerctl -h` for another players. 68 | 69 | Requirements 70 | ------------ 71 | * `sudo apt-get install vlc playerctl` 72 | 73 | Usage 74 | ------------ 75 | * `vlc-now` 76 | **Includes useful functions** 77 | * `cutExt() { 78 | * `wrapInBrackets() { 79 | * `basename() { 80 | * `urlDecode() { 81 |
82 | 83 | # [url-preview-md.py](https://github.com/dmi3/bin/blob/master/url-preview-md.py) 84 | 85 | 86 | Decription 87 | ----------- 88 | Wrapper around [webpreview](https://pypi.org/project/webpreview/). Takes url, downloads a preview image 89 | (or image iself, if url points to image) and returns formatted markdown with page title and description. 90 | Useful with clipboard manager. [Read more](https://developer.run/70) 91 | 92 | Requirements 93 | ------------ 94 | pip install webpreview 95 | 96 | Usage 97 | ----- 98 | $ url-preview-md.py img_directory url 99 | $ url-preview-md.py ~/img http://developer.run/70 100 | [Markdown Url Preview](http://developer.run/70) Markdown Url Preview in text editor. 101 | ![](/home/dmi3/img/2023_09_01_developer.run_url-preview-md.png) 102 | If you have raindrop.io api key, add it as last argument to try it if webpreview finds nothing useful 103 | $ url-preview-md.py ~/img http://developer.run/70 e2b0e47c-8a03-11ef-b1b2-13950b80fc62 104 |
105 | 106 | # [tray-unread.sh](https://github.com/dmi3/bin/blob/master/tray-unread.sh) 107 | 108 | 109 | 110 | Decription 111 | ---------- 112 | 113 | Update tray icon depending on script result. Current example shows unread mail count for Evolution mail (for those poor souls who need exchange but don't have web client), but actually it can check and notify about literally anything! 114 | Another example [shows Git repository status](https://github.com/dmi3/bin#tray-git-statussh). 115 | 116 | On click simulates some keypresses to mark all mail as read. 117 | 118 | Read more: 119 | * 120 | * 121 | 122 | Requirements 123 | ---------- 124 | 1. `sudo apt-get install yad` 125 | 2. For Evolution `sudo apt-get install sqlite3 wmctrl xdotool` 126 | 127 | Usage 128 | ----- 129 | tray-unread.sh 130 |
131 | 132 | # [tray-git-status.sh](https://github.com/dmi3/bin/blob/master/tray-git-status.sh) 133 | 134 | 135 | Decription 136 | ---------- 137 | 138 | Update tray icon depending if there are changes in Git repository. 139 | ⚠ Note that it does not show any icon if repository is in sync 140 | Check for new changes every 10 minutes. 141 | See also [git-sync](https://github.com/dmi3/bin#git-sync) 142 | 143 | See https://stackoverflow.com/a/3278427/18078777 144 | 145 | Requirements 146 | ---------- 147 | 1. `sudo apt-get install yad git` 148 | 149 | Usage 150 | ----- 151 | tray-git.sh 152 |
153 | 154 | # [translation-insert.sh](https://github.com/dmi3/bin/blob/master/translation-insert.sh) 155 | 156 | 157 | Decription 158 | ---------- 159 | Prompts for text. Then inputs translation. Works in any application. 160 | 161 | Requirements 162 | ---------- 163 | 1. Setup https://github.com/dmi3/bin/blob/master/yandex-translate.sh 164 | 2. `sudo apt-get install zenity xsel` 165 | 166 | Usage 167 | ----- 168 | * Bind script to hotkey in your DE. After input wait couple of seconds for translation to appear. 169 |
170 | 171 | # [translate-yandex.sh](https://github.com/dmi3/bin/blob/master/translate-yandex.sh) 172 | 173 | 174 | Decription 175 | ---------- 176 | CLI Yandex Translate API ru↔en. Automatically detects language. Translates any language to Russian, and Russian to English. 177 | 178 | Usage 179 | ----- 180 | yandex-translate.sh cat is a small, typically furry, carnivorous mammal # en → ru 181 | yandex-translate.sh die Hauskatze ist eine Unterart der Wildkatze # de → ru 182 | yandex-translate.sh кот это маленькое, пушистое и очень хитрое млекопитающее # ru → en 183 |
184 | 185 | # [translate-selection.sh](https://github.com/dmi3/bin/blob/master/translate-selection.sh) 186 | 187 | 188 | Decription 189 | ---------- 190 | Show popup with translation of selected text. Works in any application. 191 | 192 | Requirements 193 | ---------- 194 | 1. Setup https://github.com/dmi3/bin/blob/master/yandex-translate.sh 195 | 2. `sudo apt-get install zenity xsel` 196 | 197 | Usage 198 | ----- 199 | * Bind script to hotkey in your DE. 200 | * Select any text. Press hotkey. 201 |
202 | 203 | # [tomatych.py](https://github.com/dmi3/bin/blob/master/tomatych.py) 204 | 205 | 206 | 207 | Description 208 | ----------- 209 | * Simple Hackable Pomodoro Timer with optional Slack and Habitica integrations. 210 | * Intended to be hacked and modified to fit your specific vision of how Pomodoro timers should work. 211 | * Moved to [separate repo](https://github.com/dmi3/tomatych) 212 |
213 | 214 | # [todo](https://github.com/dmi3/bin/blob/master/todo) 215 | 216 | Wunderlist CLI for adding todos 217 | =============================== 218 | 219 | Decription 220 | ---------- 221 | Wrapper for [wl](https://github.com/robdimsdale/wl/releases) for adding todos with more convenient syntax 222 | [Read More](http://developer.run/15) 223 | 224 | Instalation 225 | ----------- 226 | 1. ⚠ Make sure [Fish shell](http://fishshell.com/#platform_tabs) > 2.3.0 227 | 2. `curl https://raw.githubusercontent.com/dmi3/bin/master/todo --create-dirs -o ~/bin/todo` 228 | 3. `curl https://raw.githubusercontent.com/dmi3/bin/master/config/fish/completions/todo.fish --create-dirs -o ~/.config/fish/completions/todo.fish` 229 | 4. 230 | 5. `[CREATE APP]` (Put https://wunderlist.com to both `APP URL` and `AUTH CALLBACK URL`) 231 | 6. Set enviroment variables in this script ↓ (line 31) 232 | 7. Add more list shortcuts ↓ (line 39) 233 | 234 | Usage 235 | ----- 236 | todo buy stuff --life --on next monday 237 | todo resolve issue --work --star 238 | todo --work meet customer --on jan 7 239 |
240 | 241 | # [timer](https://github.com/dmi3/bin/blob/master/timer) 242 | 243 | 244 | Decription 245 | ----------- 246 | Simple timer with sound and dialog window notification. To remind you to turn stove off :). 247 | Replace pc_up.wav to any available audiofile. 248 | 249 | Requirements 250 | ------------ 251 | sudo apt-get install dunst aplay 252 | 253 | Usage 254 | ----- 255 | timer 6 # i.e. notify after 6 minutes 256 |
257 | 258 | # [temp.sh](https://github.com/dmi3/bin/blob/master/temp.sh) 259 | 260 | 261 | Decription 262 | ---------- 263 | Shows CPU, System and GPU temperature 264 | 265 | Requirements 266 | ------------ 267 | sudo apt-get install jq lm-sensors nvidia-smi 268 | 269 | Usage 270 | ----- 271 | temp 272 |
273 | 274 | # [status.sh](https://github.com/dmi3/bin/blob/master/status.sh) 275 | 276 | 277 | Description 278 | ----------- 279 | ![Status](https://developer.run/pic/status.png) 280 | 281 | CLI web stats dashboard. Visualizes GitHub followers, top GitHub repos and last 500 blog hits 282 | with top pages and refferers. Works well in addition to [headlines.sh](https://github.com/dmi3/bin/blob/master/headlines.sh) and `newsbeuter -x reload -x print-unread 2> /dev/null` [Read more](https://developer.run/51) 283 | 284 | Requirements 285 | ------------ 286 | * [spark](https://github.com/holman/spark) (the other spark, not the behemoth one) 287 | * `sudo apt-get install jq` 288 | 289 | Usage 290 | ------------ 291 | * Set `URL`, `GITHUB_ID, `PARSE_APP_ID` and `PARSE_MASTER_KEY` variables 292 | * `status.sh` 293 |
294 | 295 | # [sssh2](https://github.com/dmi3/bin/blob/master/sssh2) 296 | 297 | 298 | Decription 299 | ----------- 300 | Like [sssh](https://github.com/dmi3/bin/blob/master/sssh), in addition: 301 | * `hostname` parameter of [ssh command](https://manpage.me/?q=ssh) will appear in title. 302 | - Useful when calling by nickname from local `~/.ssh/config` i.e. `ssh server_nickname`, and change of server hostname is not an option. 303 | * If command supports tunneling, display it in title 304 | - I.e. `ssh -L 80:localhost:80 server_nickname` will set title `user@[80]server_nickname` 305 | - Avoid accidental closing of such tabs 306 | * Appends some useful [aliases](https://github.com/dmi3/fish/blob/master/aliases.fish) to existing `~/.bashrc` 307 | * Preserves command history on multiple sessions 308 | 309 | Usage 310 | ----- 311 | See [sssh](https://github.com/dmi3/bin/blob/master/sssh) 312 |
313 | 314 | # [sssh](https://github.com/dmi3/bin/blob/master/sssh) 315 | 316 | 317 | Decription 318 | ----------- 319 | Script to change your terminal title to user@host when connecting to ssh and changing 320 | it back after exiting. Additionally sets green prompt on remote host. 321 | Useful for Keepassx and visual distinction to avoid notorious "wrong window" problem. 322 | Also works when connecting Fish → Bash 323 | If you want hostname from local `~/.ssh/config` file to appear in title use [sssh2](https://github.com/dmi3/bin/blob/master/sssh2). 324 | 325 | Requirements 326 | ------------ 327 | `sudo apt-get install xdotool` 328 | 329 | Usage 330 | ----- 331 | `sssh user@hostname` 332 | `alias ssh=sssh` 333 |
334 | 335 | # [snippy.sh](https://github.com/dmi3/bin/blob/master/snippy.sh) 336 | 337 | 338 | Decription 339 | ---------- 340 | System wide text snippet expander. Simulates cut→replace→paste so works in almost any application. Examples: 341 | * Type `->`, press hotkey, get `→`. 342 | * Type `thx`, press hotkey, get `Thank you`. 343 | Original idea by [sessy](https://bbs.archlinux.org/viewtopic.php?id=71938) and [Linux Magazine](http://www.linux-magazine.com/Issues/2014/162/Workspace-Text-Expander) with following improvements: 344 | * Works as keybinding in Compiz/Unity/Openbox 345 | * Does not go crazy if keybinding includes Ctrl, Alt, Shift... 346 | * Works in Sublime Text/IntelliJ Idea/Chrome/Slack 347 | * Expands snippets without preceding space i.e. `30eur` to `30€` 348 | - If snippet needs preceding space or start of line - use regexp `\b` i.e. `s/\bv$/✔/g;` converts `v` to `✔` only if its separate symbol 349 | * Expands snippets with symbols i.e. `->` to `→` 350 | * Expands commands i.e. `now` to formatted todays date, `mon` to to formatted next mondays date 351 | * Stores all snippets in one file 352 | * Works with Ubuntu 16.04 353 | 354 | Requirements 355 | ---------- 356 | `sudo apt-get install xdotool xclip xsel` 357 | 358 | Usage 359 | ----- 360 | * Bind script to hotkey in your DE, for example Shift+Tab. 361 | * Add new snippets after line 30, in format `s/SHORCUT$/REPLACEMENT/g;` 362 |
363 | 364 | # [skypenotify](https://github.com/dmi3/bin/blob/master/skypenotify) 365 | 366 | 367 | Decription 368 | ----------- 369 | Script to run append Skype messages in Notify OSD as shown on http://thexnews.com/uploads/notify.gif 370 | Since `x-canonical-append` is broken in notify-send for example in Skype you will wait forever untill all messages are shown 371 | This script makes new messages readable in same notification window 372 | [Readme in russian](http://thexnews.com/p/554) 373 | 374 | Requirements 375 | ------------ 376 | `wget https://raw.github.com/dmi3/bin/master/notify-append -P ~/bin && chmod +x ~/bin/notify-append` 377 | 378 | Usage 379 | ----- 380 | `skypenotify "%sname" "%smessage"` 381 |
382 | 383 | # [rundesktop](https://github.com/dmi3/bin/blob/master/rundesktop) 384 | 385 | 386 | Decription 387 | ----------- 388 | Execute `.desktop` file from terminal 389 | 390 | Usage 391 | ----- 392 | rundesktop /usr/share/applications/firefox.desktop 393 |
394 | 395 | # [reboot](https://github.com/dmi3/bin/blob/master/reboot) 396 | 397 | 398 | Decription 399 | ---------- 400 | See 401 |
402 | 403 | # [random-wallpaper.sh](https://github.com/dmi3/bin/blob/master/random-wallpaper.sh) 404 | 405 | 406 | Decription 407 | ---------- 408 | Sets the wallpaper, randomly selecting one from a folder. If the wallpaper is smaller than the screen, it also changes the surrounding area to a color that matches the wallpaper's palette. 409 | 410 | Instalation 411 | ----------- 412 | sudo apt-get install nitrogen coreutils 413 | 414 | Usage 415 | ----- 416 | * Put some nice pictures in ~/wallpapers/ 417 | * Call this script by cron, on login or unlock 418 | * If you want fixed background color - put one in ~/wallpapers/bg_color 419 |
420 | 421 | # [print-numbers.py](https://github.com/dmi3/bin/blob/master/print-numbers.py) 422 | 423 | 424 | Decription 425 | ----------- 426 | Font especially designed to fit 6 digits to 20x8 screens 427 | For some reason [miniwi.flf](https://github.com/xero/figlet-fonts/blob/master/miniwi.flf) [figlet font](https://developer.run/26) is not working in tty 428 | Useful for [Raspberry Pi 2fa](https://developer.run/45) 429 | ``` 430 | ▐ ██ ██ ▌▐ ██ ██ 431 | ▐ ▐ ▐ ▌▐ ▌ ▌ 432 | ▐ ██ ██ ██ ██ ██ 433 | ▐ ▌ ▐ ▐ ▐ ▌▐ 434 | ▐ ██ ██ ▐ ██ ██ 435 | ``` 436 | 437 | Usage 438 | ----- 439 | python3 numbers.py 123456 440 |
441 | 442 | # [poweroff](https://github.com/dmi3/bin/blob/master/poweroff) 443 | 444 | 445 | Decription 446 | ---------- 447 | Gracefully closes all running X applications, then powers off the computer. 448 | Make sure to avoid conflicts with system `poweroff` is such exists. 449 | Useful to avoid issues when calling `poweroff` from console: 450 | * "The database you are trying to open is locked by another instance of KeePassXC.", 451 | * "Well, this is embarrassing. Firefox is having trouble recovering your windows and tabs." 452 | * Spotify forgetting current playlist 453 | * etc 454 | 455 | Requirements 456 | ---------- 457 | 1. `sudo apt-get install wmctrl` 458 |
459 | 460 | # [plug](https://github.com/dmi3/bin/blob/master/plug) 461 | 462 | 463 | Description 464 | ---------- 465 | Interactive (un)mount of hotplug devices (USB drives) from console using FZF! 466 | Outputs path to mounted device so could be used in alias to actomatically 467 | `cd` to mounted directory. 468 | 469 | Requirements 470 | ---------- 471 | 1. `sudo apt-get install jq fzf udisks2` 472 | 2. `alias unplug='plug -u'` 473 | 3. `cd` to mounted directory: 474 | - Fish shell: `alias plug='cd (command plug)'` 475 | - Bash shell: `alias plug='cd $(command plug)'` 476 | 477 | Usage 478 | ----- 479 | $ plug 480 | > ACRONIS_MED DataTraveler_2.0 sdb1 481 | DATA DataTraveler_3.0 sdc1 482 | Mounted /dev/sdb1 at /media/dmi3/ACRONIS_MED. 483 | $ plug -u 484 | > /media/dmi3/ACRONIS_MED ACRONIS_MED DataTraveler_2.0 sdb1 485 | / workbuntu2020 Samsung_SSD_860_EVO_M.2_500GB sda2 486 | /media/dmi3/ElTorito ElTorito Samsung_SSD_860_EVO_M.2_500GB sda1 487 | Unmounted /dev/sdb1 488 |
489 | 490 | # [notify-append](https://github.com/dmi3/bin/blob/master/notify-append) 491 | 492 | 493 | Decription 494 | ----------- 495 | Script to run append Notify OSD messages as shown on http://thexnews.com/uploads/notify.gif 496 | Since x-canonical-append is broken in notify-send for example in Skype you will wait forever untill all messages are shown 497 | This script makes new messages shown in same notification window bellow the already shown 498 | Created as addition to notify-send. Use notify-send when you want to send notification and notify-append when you want append or replace it. 499 | [Readme in russian](http://thexnews.com/p/554) 500 |
501 | 502 | # [mus.sh](https://github.com/dmi3/bin/blob/master/mus.sh) 503 | 504 | 505 | Decription 506 | ---------- 507 | Setups MUS (Minimal Usable System). Targets very slow machines with very broken disks and very bad internet, so checks everything. 508 | 509 | Usage 510 | ----- 511 | /usr/bin/GET https://raw.githubusercontent.com/dmi3/bin/master/mus.sh > ~/mus.sh && chmod +x ~/mus.sh && ~/mus.sh 512 |
513 | 514 | # [memory-available.sh](https://github.com/dmi3/bin/blob/master/memory-available.sh) 515 | 516 | 517 | Decription 518 | ---------- 519 | Prints free memory in gigabytes. Sends urgent notification if usage is less than defined value. 520 | Cached memory is considered free. 521 | Works best with [indicator-sysmonitor](https://github.com/fossfreedom/indicator-sysmonitor) and [dunst](http://developer.run/23) 522 | 523 | Requirements 524 | ---------- 525 | 1. `sudo apt-get install notify-send ` 526 |
527 | 528 | # [layoutset](https://github.com/dmi3/bin/blob/master/layoutset) 529 | 530 | 531 | Decription 532 | ----------- 533 | Script to set keyboard layout depending if its Apple or regular keyboard + some settings 534 | 535 | Usage 536 | ----- 537 | `layoutset` 538 |
539 | 540 | # [knok](https://github.com/dmi3/bin/blob/master/knok) 541 | 542 | 543 | Decription 544 | ----------- 545 | Knocks to given ports with 0.5 second delay. Useful when default knockd delay 546 | is to short for server to react. Additionally displays Bob Dylan's lyrics :) 547 | 548 | Requirements 549 | ------------ 550 | 1. `sudo apt-get install knockd python3 python3-setuptools` 551 | 2. `sudo easy_install3 sh` 552 | 553 | Usage 554 | ----- 555 | `knock ip [port,port...]` 556 |
557 | 558 | # [itunec](https://github.com/dmi3/bin/blob/master/itunec) 559 | 560 | 561 | Decription 562 | ----------- 563 | Mounts USB device, syncs new podcast in gpodder then umounts device 564 | 565 | Requirements 566 | ------------ 567 | 1. `sudo apt-get install python3 id3v2` 568 | 2. `wget https://raw.github.com/dmi3/bin/master/notify-append -P ~/bin && chmod +x ~/bin/notify-append` 569 | 570 | Usage 571 | ----- 572 | 1. set LABEL to label of your player filesystem (for example `SANSA CLIP` to find label type `ls -l /dev/disk/by-label/`) 573 | 2. set GPODDER_DIR to directory where gpodder download podcasts 574 | 3. run `itunec` when you want to sync 575 | or 576 | 1. gpodder -> Podcasts -> Prefences -> Devices; set Device type to `Filesystem-based` and `Mountpoint` path where device is mounted by default 577 | 2. gpodder -> Podcasts -> Prefences -> Edit config -> cmd_all_download_complete -> itunec 578 |
579 | 580 | # [headlines.sh](https://github.com/dmi3/bin/blob/master/headlines.sh) 581 | 582 | 583 | 584 | Description 585 | ----------- 586 | * Prints ground shaking headlines from Hacker News in shell greeting 587 | * Don't miss next Meltdown, be notified right away! 588 | * Doesn't distract you if nothing important happened 589 | * Allows open all news in browser and mark it as read 590 | * If you prefer simpler version without additional functionality refer [to initial version](https://github.com/dmi3/bin/blob/2fb9f8a894ea4eba5edb13c7135861740de83084/headlines.sh) 591 | * See for description and more ideas 592 | 593 | Requirements 594 | ------------ 595 | sudo apt-get install jq 596 | 597 | Usage 598 | ------------ 599 | * `headlines.sh` will print latest headlines 600 | * `headlines.sh read` will open all news in browser and mark it as read (hide) 601 | - `~/.readnews` stores titles and urls of read news 602 | - `~/.readnews` might be useful if you want to find article later 603 | - `~/.readnews` might be synced between computers 604 | * `headlines.sh clear` will mark all news as read (hide) 605 | * Add to shell greeting [see screenshot](https://developer.run/pic/headlines.png) 606 | - 607 | - OR `chmod 777 /var/run/motd.dynamic` on boot and `headlines.sh > /var/run/motd.dynamic` 608 | - OR `chmod 777 /var/run/motd.dynamic` on boot and put `0 */2 * * * /path/to/headlines.sh > /var/run/motd.dynamic` to `crontab -e` 609 | - To read and update greeting use `headlines.sh read > /var/run/motd.dynamic && clear` 610 |
611 | 612 | # [git-sync](https://github.com/dmi3/bin/blob/master/git-sync) 613 | 614 | 615 | Decription 616 | ---------- 617 | Script to simply sync all changes into git repository with one command. For example publish local changes to Github. 618 | 619 | Requirements 620 | ---------- 621 | 1. `sudo apt-get install git` 622 | 2. [Setup mergetool](https://developer.atlassian.com/blog/2015/12/tips-tools-to-solve-git-conflicts/#parade-of-merge-tools) 623 | 624 | Usage 625 | ----- 626 | git-sync /path/to/repo 627 | git-sync # current dir 628 | git-sync # if you want sync all files 629 | git-sync -u # if you want only sync files explicitly added via `git add filename` 630 |
631 | 632 | # [generate-readme.fish](https://github.com/dmi3/bin/blob/master/generate-readme.fish) 633 | 634 | 635 | Decription 636 | ---------- 637 | Generates this readme 638 | 639 | Usage 640 | ----- 641 | echo -e "#!/bin/sh\necho \# Useful scripts for Linux users > README.md\necho \"See my [Fish config](https://github.com/dmi3/fish) for more CLI awesomness\" >> README.md\ngenerate-readme.fish --reverse >> README.md\nshasum -a 256 * | grep -v 'SHASUMS\|config' > SHASUMS" > .git/hooks/pre-commit 642 | chmod +x .git/hooks/pre-commit 643 |
644 | 645 | # [game-screenshot.sh](https://github.com/dmi3/bin/blob/master/game-screenshot.sh) 646 | 647 | 648 | Description 649 | ----------- 650 | Saves full screen screenshot with current window name and date to predefined folder and plays sound if successful. 651 | 652 | Requirements 653 | ------------ 654 | * `sudo apt-get install scrot xdotool` 655 | 656 | Usage 657 | ------------ 658 | * Bind a hotkey to `game-screenshot.sh /path/to/folder` 659 |
660 | 661 | # [ex-spotify-playlist.sh](https://github.com/dmi3/bin/blob/master/ex-spotify-playlist.sh) 662 | 663 | Export playlists from Spotify without giving credentials to shady sites (to avoid your Spotify credentials be stolen and resold to someone in different timezone) 664 | 665 | Converts Spotify playlist from "Song Links" list: 666 | 667 | https://open.spotify.com/track/6autdCG3xl7gzoiDCEB2HN 668 | https://open.spotify.com/track/4q6RvRkXquQ965hubV58lb 669 | https://open.spotify.com/track/01pzLOA8rQLfoodUCLc2wj 670 | 671 | To "Track - Artist" list: 672 | 673 | Nerevar Rising - Jeremy Soule 674 | Arcanum - NewEnglandStringQuartet 675 | Wilderness - Matt Uelmen 676 | 677 | Requirements 678 | ------------ 679 | sudo apt-get install libxml2-utils 680 | 681 | Usage 682 | ------------ 683 | 1. Open Spotify app 684 | 2. Open playlist or "Songs" view 685 | 3. Select all tracks `Ctrl+A` 686 | 4. Copy track urls `Ctrl+C` 687 | 5. Paste into file and save 688 | 6. `cat /path/to/file | ex-spotify-playlist.sh` 689 |
690 | 691 | # [ec2ssh.sh](https://github.com/dmi3/bin/blob/master/ec2ssh.sh) 692 | 693 | 694 | Decription 695 | ---------- 696 | * Writes all running AWS EC2 instances with defined name to [SSH config file](https://nerderati.com/2011/03/17/simplify-your-life-with-an-ssh-config-file/) 697 | * So you write `ssh instance_name` instead of `ssh -i ~/.ssh/gate.pem ec2-user@ec2-12-345-67-89.us-east-1.compute.amazonaws.com` 698 | * Autocompletion! 699 | * Command history is clean and reusable for `ssh` and `scp` 700 | * Instance IP change on reboot is not problem anymore 701 | * Works well with [sssh2](https://github.com/dmi3/bin/blob/master/sssh2). 702 | 703 | Instalation 704 | ----------- 705 | * Setup [aws-cli](https://github.com/aws/aws-cli#aws-cli) 706 | * (Optional) Install [latest Openssh in 16.04](https://gist.github.com/stefansundin/0fd6e9de172041817d0b8a75f1ede677) 707 | * Change credentials in `TEMPLATE` ↓ 708 | 709 | Usage 710 | ----- 711 | * If you have Openssh > 7.3: 712 | - `ec2ssh.sh | tee ~/.ssh/aws_config` 713 | - Add [Include aws_config](https://superuser.com/a/1142813) to `~/.ssh/config` 714 | * Else (will overwrite file) 715 | - ec2ssh.sh | tee ~/.ssh/config 716 |
717 | 718 | # [duplicati-ping.py](https://github.com/dmi3/bin/blob/master/duplicati-ping.py) 719 | 720 | 721 | Decription 722 | ----------- 723 | Ping on successful [Duplicati](https://www.duplicati.com/) backup 724 | 725 | Usage 726 | ----- 727 | Add path to this script to `run-script-after` in job `Configuration` → `Options` → `Advanched Options` 728 | On Windows you will need to create `.bat` file containing path to this script, and add path to `.bat` file to `run-script-after` 729 |
730 | 731 | # [doom](https://github.com/dmi3/bin/blob/master/doom) 732 | 733 | 734 | Decription 735 | ---------- 736 | Script to run gzdoom with various configurations/wads. Selectable via dmenu 737 | 738 | Requirements 739 | ------------ 740 | 1. [Get latest Gzdoom](http://debian.drdteam.org/) 741 | 2. `sudo apt-get install gzdoom dmenu python3 python3-setuptools 742 | 3. `sudo easy_install3 sh` 743 | 744 | Usage 745 | ----- 746 | doom 747 |
748 | 749 | # [control-panel](https://github.com/dmi3/bin/blob/master/control-panel) 750 | 751 | 752 | Description 753 | ----------- 754 | GUI LXQT Settings menu 755 | 756 | Requirements 757 | ------------ 758 | fzf 759 | 760 | Usage 761 | ------------ 762 | control-panel 763 |
764 | 765 | # [config/lxterminal/lxterminal.conf](https://github.com/dmi3/bin/blob/master/config/lxterminal/lxterminal.conf) 766 | 767 | Config for [LXTerminal](https://wiki.lxde.org/en/LXTerminal) with copy/paste on Ctrl+C/V and nicer color theme 768 |
769 | 770 | # [config/kitty/kitty.conf](https://github.com/dmi3/bin/blob/master/config/kitty/kitty.conf) 771 | 772 | Config for [Kitty](https://sw.kovidgoyal.net/kitty/) with custom hotkeys, nicer color scheme and some useful tweaks 773 | Refer to [original documentation](https://sw.kovidgoyal.net/kitty/conf.html) for more options 774 |
775 | 776 | # [config/fish/config.fish](https://github.com/dmi3/bin/blob/master/config/fish/config.fish) 777 | 778 | Fish config with awesome flexible prompt, unicode symbols, better fzf integration and tons of handy functions. 779 |
780 | 781 | # [config/clipit/clipitrc](https://github.com/dmi3/bin/blob/master/config/clipit/clipitrc) 782 | 783 | Config for [ClipIt](https://github.com/CristianHenzel/ClipIt) with sane defaults and hotheys 784 |
785 | 786 | # [center-mouse-active-window.py](https://github.com/dmi3/bin/blob/master/center-mouse-active-window.py) 787 | 788 | 789 | Decription 790 | ----------- 791 | Moves mouse in the center of active window. 792 | 793 | Requirements 794 | ------------ 795 | sudo apt-get install xdotool python3-sh gir1.2-wnck-3.0 796 | 797 | Usage 798 | ----- 799 | center-mouse-active-window.py 800 |
801 | 802 | # [bookmarks](https://github.com/dmi3/bin/blob/master/bookmarks) 803 | 804 | 805 | Decription 806 | ---------- 807 | Script for quickly adding and accessing bookmarks. Browser independent. 808 | When you want to store bookmarks in plain format, use CLI, but don't want use [bm](https://github.com/tj/bm) 809 | or [Buku](https://github.com/jarun/Buku) 810 | Useful when set by hotkeys or [clipboard manager](https://developer.run/25) actions. 811 | 812 | Requirements 813 | ---------- 814 | 1. `sudo apt-get install fzf` 815 | 816 | Usage 817 | ----- 818 | * `bookmarks -a http://github.com useful site` 819 | * `bookmarks -a %s $(zenity --entry)` Interactive 820 | * `bookmarks` 821 | * Bookmark currently copied link using [ClipIt](https://github.com/CristianHenzel/ClipIt) actions: `bookmarks -a %s $(zenity --entry)` 822 |
823 | 824 | # [battery](https://github.com/dmi3/bin/blob/master/battery) 825 | 826 | 827 | Description 828 | ---------- 829 | One more script to show battery status as bar(s). Difference from other solutions: 830 | * Simplicity, duh 831 | * Acknowledges the fact that there were sometimes more than one battery in laptop 832 | - Will display capacity for all batteries 833 | * Also the fact that there were sometimes no battery at all! 834 | - No error in this case 835 | * Old batteries usually max at ≈99, so it has same symbol as 100 836 | * Can work with [indicator-sysmonitor](https://github.com/fossfreedom/indicator-sysmonitor) 837 | * [Spark](https://github.com/holman/spark) could be used here, but this solution is even simpler 838 | 839 | Usage 840 | ----- 841 | $ battery # multiple batteries are installed 842 | 🔌 ▄▇ 843 | $ battery # single battery is installed 844 | 🔌 ▇ 845 | $ battery # no battery is installed 846 | 🔌 847 |
848 | 849 | # [batch-rename.py](https://github.com/dmi3/bin/blob/master/batch-rename.py) 850 | 851 | 852 | Decription 853 | ----------- 854 | Renames files given in arguments. Interactively prompts for file name. If no otherwise specified - uses first file 855 | name + number. 856 | 857 | Usage 858 | ----- 859 | rename.py file1 file2 file3 ... 860 |
861 | 862 | # [backup_protectedtext.py](https://github.com/dmi3/bin/blob/master/backup_protectedtext.py) 863 | 864 | 865 | Decription 866 | ----------- 867 | * Backup secrets from www.protectedtext.com to local storage 868 | * If file is changed, keep previous version with date postfix 869 | * Only backups once per day 870 | * Can be decrypted using `base64 -d BACKUP_FILE | openssl aes-256-cbc -d -k PASSWORD` 871 | * More info 872 | 873 | Usage 874 | ----- 875 | Run from commandline or add to cron 876 |
877 | 878 | # [aliases.bash](https://github.com/dmi3/bin/blob/master/aliases.bash) 879 | 880 | 881 | Decription 882 | ----------- 883 | Some handy bash aliases and settings. 884 | ⚠ You may find more useful commands in [Fish shell aliases](https://github.com/dmi3/fish#aliasesfish) (which is easily portable to Bash) 885 | 886 | 887 | Usage 888 | ----- 889 | 1. `wget https://raw.githubusercontent.com/dmi3/bin/aliases.bash --no-check-certificate -O ~/bin/aliases.bash` 890 | 2. `echo "source ~/bin/aliases.bash" >> ~/.bashrc` 891 | 3. To make bash more usable you probably want to install https://github.com/mrzool/bash-sensible 892 | 4. To make this work across remote machines, you also may want to install https://github.com/Russell91/sshrc 893 |
894 | --------------------------------------------------------------------------------