#+TITLE: Binaries :DRAWER: #+STARTUP: overview #+LANGUAGE: en #+EMAIL: dehaeze.thomas@gmail.com #+AUTHOR: Dehaeze Thomas #+HTML_LINK_HOME: ./index.html #+HTML_LINK_UP: ./index.html #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: :END: * Select Screen :PROPERTIES: :header-args: :tangle ~/bin/displayselect :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: Script taken from Luke Smith. #+begin_src bash twoscreen() { # If multi-monitor is selected and there are two screens. mirror=$(printf "no\\nyes" | dmenu -i -p "Mirror displays?") # Mirror displays using native resolution of external display and a scaled # version for the internal display if [ "$mirror" = "yes" ]; then external=$(echo "$screens" | dmenu -i -p "Optimize resolution for:") internal=$(echo "$screens" | grep -v "$external") res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \ tail -n 1 | awk '{print $1}') res_internal=$(xrandr --query | sed -n "/^$internal/,/\+/p" | \ tail -n 1 | awk '{print $1}') res_ext_x=$(echo $res_external | sed 's/x.*//') res_ext_y=$(echo $res_external | sed 's/.*x//') res_int_x=$(echo $res_internal | sed 's/x.*//') res_int_y=$(echo $res_internal | sed 's/.*x//') scale_x=$(echo "$res_ext_x / $res_int_x" | bc -l) scale_y=$(echo "$res_ext_y / $res_int_y" | bc -l) xrandr --output "$external" --auto --scale 1.0x1.0 \ --output "$internal" --auto --same-as "$external" \ --scale "$scale_x"x"$scale_y" else primary=$(echo "$screens" | dmenu -i -p "Select primary display:") secondary=$(echo "$screens" | grep -v "$primary") direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction"-of "$primary" --auto --scale 1.0x1.0 fi } morescreen() { # If multi-monitor is selected and there are more than two screens. primary=$(echo "$screens" | dmenu -i -p "Select primary display:") secondary=$(echo "$screens" | grep -v "$primary" | dmenu -i -p "Select secondary display:") direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") tertiary=$(echo "$screens" | grep -v "$primary" | grep -v "$secondary" | dmenu -i -p "Select third display:") xrandr --output "$primary" --auto --output "$secondary" --"$direction"-of "$primary" --auto --output "$tertiary" --"$(printf "left\\nright" | grep -v "$direction")"-of "$primary" --auto } multimon() { # Multi-monitor handler. case "$(echo "$screens" | wc -l)" in 1) xrandr $(echo "$allposs" | grep -v "$screens" | awk '{print "--output", $1, "--off"}' | tr '\n' ' ') ;; 2) twoscreen ;; ,*) morescreen ;; esac ;} # Get all possible displays allposs=$(xrandr -q | grep "connected") # Get all connected screens. screens=$(echo "$allposs" | grep " connected" | awk '{print $1}') # Get user choice including multi-monitor and manual selection: chosen=$(printf "%s\\ncancel\\nmulti-monitor\\nmanual selection" "$screens" | dmenu -i -p "Select display arangement:") && case "$chosen" in "cancel") exit ;; "manual selection") arandr ; exit ;; "multi-monitor") multimon ;; ,*) xrandr --output "$chosen" --auto --scale 1.0x1.0 $(echo "$allposs" | grep -v "$chosen" | awk '{print "--output", $1, "--off"}' | tr '\n' ' ') ;; esac $HOME/.config/polybar/scripts/launch.sh # restart polybar pgrep -x dunst >/dev/null && killall dunst && setsid dunst & # Restart dunst to ensure proper location on screen #+end_src * getbib :PROPERTIES: :header-args: :tangle ~/bin/getbib :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash [ -z "$1" ] && echo "Give either a pdf file or a DOI as an argument." && exit if [ -f "$1" ]; then # Try to get DOI from pdfinfo or pdftotext output. doi=$(pdfinfo "$1" | grep -io "doi:.*") || doi=$(pdftotext "$1" 2>/dev/null - | grep -io "doi:.*" -m 1) || exit 1 else doi="$1" fi # Check crossref.org for the bib citation. curl -s "http://api.crossref.org/works/$doi/transform/application/x-bibtex" -w "\\n" #+end_src * vpnToggle :PROPERTIES: :header-args: :tangle ~/bin/vpntoggle :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash if [[ $(nordvpn status) == *"Connected"* ]]; then nordvpn disconnect && dunstify --replace=23198 "VPN" "Disconnected"; else country=`cat ~/bin/nordvpn_countries.txt | sed 's/\s*\t\s*/ /g ; s/\s/\n/g ; s/_/ /g ; /^[a-zA-Z]/!d ; s/\(.*\)/\L\1/' | rofi -i -dmenu | sed 's/\s/_/g'`; dunstify --replace=23198 "VPN" "Connecting to $country..."; nordvpn connect $country && dunstify --replace=23198 "VPN" "Connected to $country"; fi #+end_src * bukurun :PROPERTIES: :header-args: :tangle ~/bin/bukurun :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash _rofi () { rofi -dmenu -i -no-levenshtein-sort -width 1000 "$@" } # display settings display_type=1 max_str_width=80 # keybindings switch_view="Alt+Tab" new_bookmark="Alt+n" actions="Alt+a" edit="Alt+e" delete="Alt+d" # colors help_color="#334433" # source global config if [[ -f /etc/buku_run.config ]] then source /etc/buku_run.config fi # source local config: if [[ -z $XDG_CONFIG_DIR ]] then if [[ -f $HOME/.config/buku_run/config ]] then source $HOME/.config/buku_run/config else echo "User config file \'~/.config/buku_run/config\' not found. using global config" fi else if [[ -f "${XDG_CONFIG_DIR}/buku_run/config" ]] then source "${XDG_CONFIG_DIR}/buku_run/config" else echo "User config file \'~/.config/buku_run/config\' not found. using global config" fi fi main () { HELP="Welcome to Buku. Use ${new_bookmark} to add a new Bookmark Use ${switch_view} to switch View. ${actions} for actions" if [[ $mode == "bookmarks" ]]; then content=$(parseBuku) menu=$(echo "${content}" | _rofi -p '> ' -filter "${filter}" -mesg "${HELP}" -kb-custom-1 "${new_bookmark}" -kb-custom-2 "${switch_view}" -kb-custom-3 "${actions}" -kb-custom-4 "${edit}" -kb-custom-5 "${delete}") elif [[ $mode == "tags" ]]; then menu=$(buku --np --st | awk '{$NF=""; print $0}' | cut -d ' ' -f2- | _rofi -p '> ' -mesg "${HELP}" -kb-custom-1 "${new_bookmark}" -kb-custom-2 "${switch_view}" -kb-custom-3 "${actions}" -kb-custom-4 "${edit}" -kb-custom-5 "${delete}") fi val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 12 ]]; then optionsMenu elif [[ $val -eq 10 ]]; then addMark elif [[ $val -eq 14 ]]; then deleteMenu elif [[ $val -eq 13 ]]; then editMenu elif [[ $val -eq 11 ]]; then if [[ $mode == "bookmarks" ]]; then export mode="tags" mode=tags main elif [[ $mode == "tags" ]]; then export mode="bookmarks" mode=bookmarks main fi elif [[ $val -eq 0 ]]; then if [[ $mode == "bookmarks" ]]; then id=$(getId "$content" "$menu") for bm in ${id}; do buku -o "${bm}" done elif [[ $mode == "tags" ]]; then filter="${menu}" mode="bookmarks" main fi fi } optionsMenu () { if [[ $mode == "bookmarks" ]]; then askmenu=$(echo -e "< Return\n---\n1. Edit\n2. Delete" | _rofi -p '> ' -mesg "Choose Action for bookmark") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $askmenu == "< Return" ]]; then export mode=bookmarks main elif [[ $askmenu == "1. Edit" ]]; then editMenu elif [[ $askmenu == "2. Delete" ]]; then deleteMenu fi fi elif [[ $mode == "tags" ]]; then askmenu=$(echo -e "< Return\n---\n1. Replace Tag\n2. Delete Tag" | _rofi -p '> ' -mesg "Choose Action for tag \"${menu}\"") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $askmenu == "< Return" ]]; then export mode=tags main elif [[ $askmenu == "1. Replace Tag" ]]; then newtag=$(echo | _rofi -p '> ' -mesg "Enter new tag name for tag \"${menu}\"") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $newtag == "" ]]; then mode=tags main else buku -r "${menu}" "${newtag}" mode=tags main fi fi elif [[ $askmenu == "2. Delete Tag" ]]; then delask=$(echo -e "1. Yes\n2. No" | _rofi -p '> ' -mesg "Really delete tag?") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $delask == "1. Yes" ]]; then buku -r "${menu}" mode=tags main elif [[ $delask == "2. No" ]]; then mode=tags main fi fi fi fi fi } deleteMenu () { id=$(getId "$content" "$menu") delask=$(echo -e "1. Yes\n2. No" | _rofi -p '> ' -mesg "Really delete bookmark?") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $delask == "1. Yes" ]]; then buku -d ${id} --tacit mode=bookmarks main elif [[ $delask == "2. No" ]]; then optionsMenu fi fi } editMenu () { id=$(getId "$content" "$menu") title="$(getTitleFromId $id)" bookmark="$(getUrlFromId $id)" tags="$(getTagsFromId $id)" content=$(echo -e "1. title: $title\n2. url: $bookmark\n3. tags: $tags") editmenu=$(echo -e "< Return\n---\n${content}" | _rofi -p '> ') val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $editmenu == "< Return" ]]; then main elif [[ $editmenu == "tags: NOTAG" ]]; then addTags --update elif [[ $editmenu =~ tags:* ]]; then tags="${tags}" editTags elif [[ $editmenu =~ url:* ]]; then editBookmark elif [[ $editmenu =~ title:* ]]; then editTitle fi fi } editTags () { edittagsmenu=$(echo | _rofi -filter "${tags}" -p '> ' -mesg "Edit Tags and hit Enter") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then buku -u ${id} --tag "${edittagsmenu}" fi mode=bookmarks main } editBookmark () { bmarkmenu=$(echo "" | _rofi -p "> " -filter "${bookmark}" -mesg "Edit Bookmark and hit Enter") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $bmarkmenu == "http"* ]]; then buku -u "${id}" --url "${bmarkmenu}" else echo "" | rofi -e "Not a valid URI, Make sure URLs start with http" editBookmark fi fi mode=bookmarks main } editTitle () { titlemenu=$(echo "" | _rofi -p "> " -filter "${title}" -mesg "Edit Title and hit Enter") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then buku -u "${id}" --title "${titlemenu}" fi mode=bookmarks main } addMark () { inserturl=$(echo -e "$(xclip -o)" | _rofi -p '> ' -mesg "Use URL below or type manually") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then addTags fi } addTags () { inserttags=$(buku --np --st | awk '{$NF=""; print $0}' | cut -d ' ' -f2- | _rofi -p '> ' -mesg "Add some tags. Separate tags with ', '") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 0 ]]; then if [[ $(echo "${inserttags}" | wc -l) -gt 1 ]]; then taglist=$(echo "${inserttags}" | tr '\n' ',') tags=() for tag in $taglist; do tags+=("$tag") done else tags=${inserttags} fi if [[ $1 == "--update" ]]; then buku -u "${id}" --tag ${tags} else buku -a ${inserturl} ${tags} fi fi } parseBuku () { echo "$(buku --nc -p | gawk -v max="$max_str_width" -v type="$display_type" ' BEGIN { RS="" FS="\n" } { if ($3 == "") $3 = " # NOTAG" id = gensub(/([0-9]+)\.(.*)/, "\\1", "g", $1) url = substr(gensub(/\s+> (.*)/, "\\1", "g", $2),0,max) tags = gensub(/\s+# (.*)/, "\\1", "g", $3) title = substr(gensub(/[0-9]+\.\s*(.*)/, "\\1", "g", $1),0,max) if (type == 1) print id "\t" url "\t" tags else print id "\t" title "\t" tags if (type == 3) print " \t" url "\t " print "" } ' | column -t -s $'\t')" } getId () { id=$(echo "${2%% *}") if [ -z "$id" ]; then prev="" IFS=$'\n' for line in $1; do if [ "$2" = "$line" ]; then id=$(echo "${prev%% *}") break else prev="$line" fi done fi echo $id } getTitleFromId () { echo "$(buku --nc -p $1 | gawk ' BEGIN { RS="" FS="\n" } { print gensub(/[0-9]+\.\s*(.*)/, "\\1", "g", $1) } ')" } getUrlFromId () { echo "$(buku --nc -p $1 | gawk ' BEGIN { RS="" FS="\n" } { print gensub(/\s+> (.*)/, "\\1", "g", $2) } ')" } getTagsFromId () { echo "$(buku --nc -p $1 | gawk ' BEGIN { RS="" FS="\n" } { print gensub(/\s+# (.*)/, "\\1", "g", $3) } ')" } mode=bookmarks main #+end_src * i3exit :PROPERTIES: :header-args: :tangle ~/bin/i3exit :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash # with openrc use loginctl case "$1" in lock) ~/scripts/lockscreen.sh ;; logout) loginctl terminate-session `loginctl session-status | head -n 1 | awk '{print $1}'` ;; switch_user) dm-tool switch-to-greeter ;; suspend) systemctl suspend && ~/scripts/lockscreen.sh ;; hibernate) systemctl hibernate && ~/scripts/lockscreen.sh ;; reboot) systemctl reboot ;; shutdown) systemctl poweroff ;; ,*) echo "== ! i3exit: missing or invalid argument ! ==" echo "Try again with: lock | logout | switch_user | suspend | hibernate | reboot | shutdown" exit 2 esac exit 0 #+end_src * readbib :PROPERTIES: :header-args: :tangle ~/bin/readbib :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash cd ~/Cloud/thesis/ressources/pdfs/ && ls | rofi -dmenu -lines 20 | xargs -I {} zathura {} #+end_src * readnotes :PROPERTIES: :header-args: :tangle ~/bin/readnotes :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash cd ~/Cloud/thesis/ressources/notes/pdfs/ && ls *.pdf | rofi -dmenu -lines 20 | xargs -I {} zathura {} #+end_src * askpass :PROPERTIES: :header-args: :tangle ~/bin/askpass-rofi :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: Take password prompt from STDIN, print password to STDOUT. The sed piece just removes the colon from the provided prompt: =rofi -p= already gives us a colon #+BEGIN_SRC bash rofi -dmenu \ -password \ -no-fixed-num-lines \ -p "$(printf "$1" | sed s/://)" #+END_SRC * Take Screenshot :PROPERTIES: :header-args: :tangle ~/bin/screenshot :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash status=$(echo -e "All\nGUI\nSelection\nCropped\nCopy\nShadow\nActive" | rofi -i -dmenu -p "Type") if [ -z "$status" ]; then exit; fi name=$(echo -e "screenshot-$(date +"%m-%d-%y_%H-%M-%S")" | rofi -i -dmenu -p "Filename") if [ -z "$name" ]; then exit; fi case "$status" in "All") maim ~/Pictures/$name.png ;; "GUI") flameshot gui -r > ~/Pictures/$name.png ;; "Selection") maim -s ~/Pictures/$name.png ;; "Cropped") maim -s ~/Pictures/$name.png && convert -trim ~/Pictures/$name.png ~/Pictures/$name.png;; "Copy") maim -s | xclip -selection clipboard -t image/png ;; "Shadow") maim -st 9999999 | convert - \( +clone -background black -shadow 80x3+5+5 \) +swap -background none -layers merge +repage ~/Pictures/$name.png ;; "Active") maim -i $(xdotool getactivewindow) ~/Pictures/$name.png ;; esac #+end_src * Remote Desktop Connect :PROPERTIES: :header-args: :tangle ~/bin/remote-desktop :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash computer=$(echo -e 'RNICE\nPCMEL1\nPCNASS1\nPCMEG01' | dmenu -p 'Computer:' -l 20); case $computer in PCMEL1) rdesktop -a 16 -P -z -x m -r sound:off -g "80%" -u "ESRF\OPPEL" -p $(pass esrf/PCMEL1/OPPEL | sed -n 1p) pcmel1 ;; PCMEG01) rdesktop -a 16 -P -z -x m -r sound:off -g "80%" -u "ESRF\DEHAEZE" -p $(pass ssl.esrf.fr/dehaeze | sed -n 1p) pcmeg01 ;; PCNASS1) rdesktop -a 16 -P -z -x m -r sound:off -g "80%" -u "ESRF\DEHAEZE" -p $(pass ssl.esrf.fr/dehaeze | sed -n 1p) pcnass1 ;; RNICE) echo "Not yet implemented" ;; ,*) echo "Not existing" ;; esac #+end_src * Toggle Network :PROPERTIES: :header-args: :tangle ~/bin/network-toggle :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash result=$(nmcli device | sed '1d' | dmenu -l 20); interface=$(echo $result | awk -F ' ' '{print $1}'); status=$(echo $result | awk -F ' ' '{print $3}'); if [ $status == 'disconnected' ]; then nmcli device connect $interface else nmcli device disconnect $interface fi #+end_src * Print on Rnice :PROPERTIES: :header-args: :tangle ~/bin/print-rnice :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash nbpage=$(echo -e '1\n2\n4' | dmenu -p 'Number of pages per sheet' -l 20); sides=$(echo -e 'one-sided\ntwo-sided-long-edge\ntwo-sided-short-edge' | dmenu -p 'Two Sided:' -l 20); # First copy the file to Rnice if sshpass -p "$(pass ssl.esrf.fr/dehaeze | sed -n 1p)" scp $1 dehaeze@rnice:~/Downloads/; then # Then print on Rnice sshpass -p "$(pass ssl.esrf.fr/dehaeze | sed -n 1p)" ssh dehaeze@rnice "lpr -o media=A4 -o sides=$sides -o number-up=$nbpage -P ctb110c1u ~/Downloads/$1"; # Finally, delete the file else echo "Command Failed" fi #+end_src * Mount TMP14DAYS :PROPERTIES: :header-args: :tangle ~/bin/mnt_tmp_14_days :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash sudo -A mkdir ~/tmp_14_days; sudo -A mount -o rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=160.103.232.103,mountvers=3,mountport=597,mountproto=tcp,local_lock=none,addr=160.103.232.103 rnice:/hz/tmp_14_days ~/tmp_14_days; #+end_src * Make GIF :PROPERTIES: :header-args: :tangle ~/bin/make-gif :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html #+begin_src bash palette="/tmp/palette.png" filters="fps=15,scale=320:-1:flags=lanczos" ffmpeg -v warning -i $1 -vf "$filters,palettegen" -y $palette ffmpeg -v warning -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $2 #+end_src * Download-Audio :PROPERTIES: :header-args: :tangle ~/bin/yt-audio :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash if [ $TMUX ]; then tmux split -v -l 5 "cd ~/Downloads/ && youtube-dl --add-metadata -xic -f bestaudio/best $1" && tmux select-pane -U else cd ~/Downloads/; setsid nohup youtube-dl --add-metadata -xic -f bestaudio/best $1 &> /dev/null & fi #+end_src * Download-Video :PROPERTIES: :header-args: :tangle ~/bin/yt-video :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash if [ $TMUX ]; then tmux split -v -l 5 "cd ~/Downloads/ && youtube-dl --add-metadata -ic $1" && tmux select-pane -U else cd ~/Downloads/; setsid nohup youtube-dl --add-metadata -ic $1 &> /dev/null & fi #+end_src * Pdf Shrink :PROPERTIES: :header-args: :tangle ~/bin/pdf-shrink :header-args+: :comments both :mkdirp yes :header-args+: :shebang "#!/usr/bin/env bash" :END: #+begin_src bash shrink () { gs \ -q -dNOPAUSE -dBATCH -dSAFER \ -sDEVICE=pdfwrite \ -dCompatibilityLevel=1.3 \ -dPDFSETTINGS=/screen \ -dEmbedAllFonts=true \ -dSubsetFonts=true \ -dAutoRotatePages=/None \ -dColorImageDownsampleType=/Bicubic \ -dColorImageResolution=$3 \ -dGrayImageDownsampleType=/Bicubic \ -dGrayImageResolution=$3 \ -dMonoImageDownsampleType=/Subsample \ -dMonoImageResolution=$3 \ -sOutputFile="$2" \ "$1" } check_smaller () { # If $1 and $2 are regular files, we can compare file sizes to # see if we succeeded in shrinking. If not, we copy $1 over $2: if [ ! -f "$1" -o ! -f "$2" ]; then return 0; fi ISIZE="$(echo $(wc -c "$1") | cut -f1 -d\ )" OSIZE="$(echo $(wc -c "$2") | cut -f1 -d\ )" if [ "$ISIZE" -lt "$OSIZE" ]; then echo "Input smaller than output, doing straight copy" >&2 cp "$1" "$2" fi } usage () { echo "Reduces PDF filesize by lossy recompressing with Ghostscript." echo "Not guaranteed to succeed, but usually works." echo " Usage: $1 infile [outfile] [resolution_in_dpi]" } IFILE="$1" # Need an input file: if [ -z "$IFILE" ]; then usage "$0" exit 1 fi # Output filename defaults to "-" (stdout) unless given: if [ ! -z "$2" ]; then OFILE="$2" else OFILE="-" fi # Output resolution defaults to 72 unless given: if [ ! -z "$3" ]; then res="$3" else res="90" fi shrink "$IFILE" "$OFILE" "$res" || exit $? check_smaller "$IFILE" "$OFILE" #+end_src * =setbg= - Set Background :PROPERTIES: :header-args: :tangle ~/bin/setbg :END: #+begin_src bash bgloc="${XDG_CACHE_HOME:-$HOME/.cache/}/bg" [ -f "$1" ] && ln -sf "$(readlink -f "$1")" "$bgloc" [ -d "$1" ] && ln -sf "$(find "$(readlink -f "$1")" -iregex '.*.\(jpg\|jpeg\|png\|gif\)' -type f | shuf -n 1)" "$bgloc" xwallpaper --zoom "$bgloc" #+end_src