linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* A couple of convenience scripts
@ 2022-01-21 22:35 Jens Bauer
  0 siblings, 0 replies; only message in thread
From: Jens Bauer @ 2022-01-21 22:35 UTC (permalink / raw)
  To: linux-btrfs

Hi all.

As I'm not a fan of typing long command-lines once a month, I made myself a couple of convenient scripts for scrubbing.
I don't know if there are already scripts like these, but I'm posting them in case someone find them useful.

There might be bugs, if so, they're likely just minor, as I've been using/modifying the scripts all day on 3 different machines. If you find anything you think is incorrect, feel free to let me know.


Show scrub status on selected or all BTRFS volumes:
--8<-----8<---{ ~/bin/Scrub-status }--8<---
#!/bin/bash

# Usage:
#   Scrub-status [volume] ...
# ... or watch all while updating every 5 seconds ...
# Cls; while [ 1 ]; do Home; Scrub-status; sleep 5; done

[ "$EUID" == "0" ] || { sudo -E $0 $@ && exit 0; exit 1; }

# Hint: Cls, Home, CMsg and BTRFS-df can be handy to have in ~/.bash_functions
Cls(){ echo -en "\033c"; }
Home(){ echo -en "\033[H"; }
CMsg(){ echo -en "\033[1;$1m${*:2}\033[m${2:+\n}"; }

BTRFS-df(){ df -h --type=btrfs --output=used,target | tail -n +2 | sort -h; }
BTRFS-status(){ btrfs scrub status "$1"; }
GETVAL(){ local val=$(egrep "^$2:" <<< "$1"); val="${val#$2:}"; echo "${val##* }"; }
BTRFS-state(){ GETVAL "$1" "Status"; }
BTRFS-timeLeft(){ GETVAL "$1" "Time left"; }

volumes=("$@");
[ -z "$*" ] && volumes=($(BTRFS-df | grep -oP '\S+$'))

h=0; for vol in "${volumes[@]}"; do [ ${#vol} -gt $h ] && h=${#vol}; done

for vol in "${volumes[@]}"; do
  volume="$vol                    "
  status=$(BTRFS-status "$vol")
  state=$(BTRFS-state "$status")
  time=$(BTRFS-timeLeft "$status")
  color=30
  case "$state" in finished) color=32 ;; running) color=34 ;; *) state="?" ;; esac
  echo -n "${volume:0:$h}: "; CMsg $color "$state${time:+  (time left: $time)}\033[K"
done
--->8----->8----->8--


Scrubbing selected or all BTRFS-volumes:
--8<-----8<---{ ~/bin/scrub }--8<---
#!/bin/bash

# Usage:
# scrub [vol] ...
#  -If not supplying any arguments, all BTRFS-volumes will be scrubbed.
# otherwise, supply the volumes you want scrubbed ...
# scrub /home /usr /mnt/files
# Scrub all in the background ...
# sudo true; scrub &
# ... quietly ...
# sudo true; scrub >/dev/null 2>&1 &

[ "$EUID" == "0" ] || { sudo -E $0 $@ && exit 0; exit 1; }

BTRFS-df(){ df -h --type=btrfs --output=used,target | tail -n +2 | sort -h; }
BTRFS-status(){ btrfs scrub status "$1"; }
GETVAL(){ local val=$(egrep "^$2:" <<< "$1"); val="${val#$2:}"; echo "${val##* }"; }
BTRFS-state(){ GETVAL "$1" "Status"; }
BTRFS-timeLeft(){ GETVAL "$1" "Time left"; }

scrubTimeLeft(){
  local status state t h m s=1

  while [ -z "$state" ]; do
    status=$(BTRFS-status "$1")
    state=$(BTRFS-state "$status")
    t=$(BTRFS-timeLeft "$status")
  done

  case "$state" in finished) s=0 ;;
  running) [ -n "$t" ] && {
    s=${t##*:}; t=${t%%:$s}; s=${s##*0}
    m=${t##*:}; t=${t%%:$m}; m=${m##*0}
    h=${t##*:}; t=${t%%:$h}; h=${h##*0}
    s=$((${h:-0}*3600+${m:-0}*60+${s:-0}))
  } ;; esac
  echo ${s:-0}
}

waitFor(){
  local seconds=1
  while [ $seconds -ne 0 ]; do
    sleep $seconds
    seconds=$(scrubTimeLeft "$1")
  done
}

volumes=("$@")
[ -z "$*" ] && volumes=($(BTRFS-df | grep -oP '\S+$'))

echo "Will scrub: ${volumes[@]}" >&2

for vol in "${volumes[@]}"; do
  [ -d "$vol" ] && {
    btrfs scrub start "$vol"
    waitFor "$vol"
    echo "Scrubbing finished on $vol" >&2
    sleep 2
  }
done
--->8----->8----->8--

My BTRFS-df function lists the BTRFS volumes sorted by usage.
This is useful for quickly getting the smallest volumes scrubbed first.

If you choose to have a ~/.bash_functions script like I do, just add the following line in your ~/.bashrc right after your ~/.bash_aliases line:

[ -x ~/.bash_functions ] && . ~/.bash_functions

(I have both at the absolute top of my ~/.bashrc ... you may choose to use -f instead of -x if you wish)
Since most commands are lowercase, I've started most of the functions with capital letters to avoid conflicts.

Enjoy.


Love
Jens

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-21 22:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-21 22:35 A couple of convenience scripts Jens Bauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).