123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #!/bin/bash
- ########## DEFAULT VALUES ###############################################
- # boolean variables are '1' for true or anything else for false.
- wait=10 # between outputs, in s
- bps=555 # output bytes per s - more is faster - 555 is a good value on my machine - set to 0 to disable; requires pv to be installed.
- colored=1 # 0 for no colors or if command output provides colors, 1 for randomized color for each block
- stars=0 # sprinkle canvas witgh stars after showing command output
- density=3 # how many stars do you want on screen, max., in percent. Not precise.
- erase=0 # instead of simplyclearing the screen, erase it from top to bottom
- erasetime=2 # how many seconds do you wnat the erase process to last. Not precise.
- colors=( 1 2 3 4 5 6 ) # to work with tput. exclude black and white; bold is randomized inside the script
- # each line produces a block of output (later split by newline & eval'd)
- commands='toilet -t -f smmono12 -W -- "$(date +%R)"
- toilet -t -f future -- "$(date +"%A %d %B")"
- toilet -t -f future -- "$(uptime -p)"'
- ########## USER CUSTOMISATION ################
- config="$XDG_CONFIG_HOME/termss/${0##*/}.conf"
- [ -r "$config" ] && . "$config"
- ##############################################
- grep -qw toilet <<<"$commands" && ! which toilet >/dev/null && commands='echo "Please install toilet!"
- echo "Or configure other commands in $config"'
- #~ dependencies for marquee1 script
- for i in shuf od tput; do
- which "$i" >/dev/null || exit 1
- done
- # pv is an optional dependency
- which pv >/dev/null || bps=0
- # sleep as a builtin
- for file in /usr/lib/bash/sleep /usr/lib32/bash/sleep /usr/lib64/bash/sleep; do
- [ -r "$file" ] && enable -f "$file" sleep && break
- done
- # Portable enough?
- # let's assume terminal size doesn't change during script execution
- term_cols=$(tput cols)
- term_lines=$(tput lines)
- rand_func() {
- # more random than RANDOM? networkworld.com/article/3208389/linux/unix-how-random-is-random.html
- num="$(od -vAn -N2 -tu < /dev/urandom )"
- #num=$RANDOM
- # if $1 is passed, make sure random number is >= that value. if not, minimum is 0.
- min=${1-0}
- (( num < min )) && num=$((num + min))
- echo $num
- }
- #~ if [[ "$colored" == "1" ]]; then
- #~ colmax=${#colchoice[*]}
- #~ colchoice=$(( $(rand_func $colmax) % colmax))
- #~ lastcolchoice=$colchoice
- #~ fi
- tput civis # cursor invisible
- #~ echo -en "\e]12;10\a" # make cursor green (we need this later)
- oldifs="$IFS"
- #declare -A length
- while :; do
- longest_all=0
- outputlines=0
- count=0
- colchoiceprevious=()
- # command execution, but no output - to calculate size of complete output
- IFS=$'\n'
- while read -r -- command ; do
- IFS="$oldifs"
- # one array field for each command's output
- output[count]="$(eval $command)"
- longest[count]=0
- while read -r -- line ; do
- # find longest line
- (( ${#line} > longest_all )) && longest_all=${#line}
- (( ${#line} > ${longest[count]} )) && longest[count]=${#line}
- ((outputlines++))
- done <<<"${output[count]}"
- IFS=$'\n'
- ((count++))
- done <<<"$commands"
- IFS="$oldifs"
- # put cursor on random vertical position, i.e. line
- scope=$(( term_lines - outputlines ))
- vpos=0
- (( scope > 0 )) && vpos="$(( $(rand_func $scope) % scope ))" && tput vpa "$vpos"
- # random horizontal pos. offset, used later to put cursor
- scope=$(( term_cols - longest_all ))
- (( scope > 0 )) && offset_all=$(( $(rand_func $scope) % scope )) || offset_all=0
- # define 1 color for each command
- if [[ "$colored" == "1" ]]; then
- colchoice=( $(shuf -n$count -e ${colors[@]}) ) # once to initialise
- until [[ "${colchoice[@]}" != "${colchoiceprevious[@]}" ]]; do
- colchoice=( $(shuf -n$count -e ${colors[@]}) )
- done
- colchoiceprevious=( ${colchoice[@]} )
- fi
- # write text to random position
- for (( i=0 ; i<count ; i++ )) ; do
- [[ "$colored" == "1" ]] && tput setaf $(( ${colchoice[i]} + 8 * ( $(rand_func 2)%2 ) )) # randomly makes the color bold or not, by adding 8 to the random value, or not
- offset=$(( ( longest_all - ${longest[i]} ) / 2 + offset_all )) # this centers the blocks on top of each other
- IFS='' # necessary to include leading whitespace in line
- if (( bps > 0 )); then
- while read -r -- line ; do
- tput hpa $offset # place cursor horizontally
- tput cnorm
- printf "%s" "$line"
- tput civis
- printf "\n"
- done <<<"${output[i]}" | pv -L $bps -q --
- else
- while read -r -- line ; do
- tput hpa $offset # place cursor horizontally
- echo "$line"
- done <<<"${output[i]}"
- fi
- IFS="$oldifs"
- #~ if [[ "$colored" == "1" ]]; then
- #~ until [[ "$colchoice" != "$lastcolchoice" ]]; do colchoice=$(( $(rand_func $colmax) % colmax)); done
- #~ lastcolchoice=$colchoice
- #~ fi
- done
- if [[ "$stars" == 1 ]]; then
- # convert density to absolute number of stars desired
- density="$(bc <<<"scale=10;$term_cols*$term_lines/100*$density")"
- sleep "$(bc <<<"scale=10;$wait/10")"
- tput sgr0 # reset
- chars='*∙·•·•·•∙·•·•·•+◆●☼'
- #strings -e S -s '' /dev/urandom | while read -n1 char; do
- starsleep="$(bc <<<"scale=10;($wait-($wait/10))/$density")"
- while sleep "$starsleep"; do
- # put cursor on random position
- Y=$(( $(rand_func $term_lines) % term_lines ))
- X=$(( $(rand_func $term_cols) % term_cols ))
- if ((X<offset_all || X>=offset_all+longest_all)) || \
- ((Y<vpos || Y>=vpos+outputlines)); then
- tput cup $Y $X
- #~ # put cursor on random vertical position, i.e. line
- #~ scope=$term_lines
- #~ tput vpa $(( $(rand_func $scope) % scope ))
- #~ # random horizontal pos. i.e. column
- #~ scope=$term_cols
- #~ tput hpa $(( $(rand_func $scope) % scope ))
- #tput setaf $(( ${colors[$(( $(rand_func ${#colors[@]})%${#colors[@]} ))]} ))
- printf '\e[%s;37m%s' "$((RANDOM%2))" "${chars:$((RANDOM%${#chars})):1}"
- fi
- done
- fi & pid=$!
- sleep $wait
- [[ "$stars" == 1 ]] && kill $pid >/dev/null 2>&1
- if [[ "$erase" == 1 ]] && ((erasetime>0)) && which pv >/dev/null; then
- tput -S <<!
- cup 0 0
- cnorm
- !
- # cursor visible (normal)
- #~ screenchars="$((term_lines * term_cols))"
- #~ screenchars="$((screenchars/10))" # 10 spaces, therefore screenchars/10
- #~ ((erasetime > 0)) && delay="$(bc <<<"scale=10;$erasetime/$screenchars")" || delay=0.0002
- #~ for (( i=0;i<screenchars;i++ )); do
- #~ printf ' ' # 10 spaces, therefore screenchars/10
- #~ sleep "$delay"
- #~ done
- screenchars="$((term_lines * term_cols))"
- bps_cls="$((screenchars/erasetime))"
- for (( i=0;i<screenchars;i++ )); do
- printf " "
- done | pv -L $bps_cls -q
- tput -S <<!
- civis
- cup 0 0
- !
- else
- clear
- fi
- done 2>/dev/null
|