2

Is it possible to add those effects in normal terminal? Modified terminal? Code something from 'scratch' for fun? Play sound every 3 seconds and lower the intensity of cursor highlight smoothly over 3 seconds time.

1 Answer 1

3

This is a fun idea. I'd use that.

Unfortunately, terminals don't support fading text or fading reverse video. So you get to select some ANSI colors to cycle through and rewrite the screen yourself. This puts you squarely in the "code something from 'scratch' for fun" territory.

This task can be completed in Bash, Python, C or any one of hundreds of other languages capable of execing shell commands. Pick a language you want to learn, or are already familiar with.

Assuming you are working in bash or another shell, you can play audio with the play command (from the sox package). There are many other command line media players to choose from, depending on the audio format.

It will be a bit difficult to parse the output of watch -d in order to identify changes. Most command pipelines like to work with a complete file. Detecting the screen refresh from an unending file, like stdout from watch -d, and splitting it into chunks is the crux. You might find it easier to stash the output of your watched command in a variable or temp file that you can diff against in the next run.

Here is an example of how you might get the ball rolling in bash:

#!/bin/bash
# depends on wdiff, play and cmp
# sudo apt install wdiff sox diffutils
#
# Takes the command to watch as arguments. Example:
# ./submarine-watch.sh date

CMD="$@"
CLEAR="\e[H\e[J"

show_change() {
    for bg in {251..232}; do
        fg=$((256-(bg>244)*(bg-245)*4))
        DISPLAY=$(
            wdiff -1y"\e[48;5;${bg};38;5;${fg}m" -z"\e[0m" \
                <(echo "$OUT") <(echo "$NEWOUT")
            )
        echo -e "${CLEAR}$DISPLAY"
        sleep 0.15
    done
    echo -e "${CLEAR}$NEWOUT"
}

OUT=$($CMD)
echo -e "${CLEAR}$OUT"
while true; do
    sleep 5  # update interval in seconds, like watch -n
    NEWOUT=$($CMD)
    if ! cmp -s <(echo "$OUT") <(echo "$NEWOUT"); then
        play ~/Music/submarine.wav &>/dev/null &
        show_change &
    fi
    NEWOUT="$OUT"
done

Which we can run like this: ./submarine-watch.sh date Check out the output animation: asciicast

This example has a hard-coded refresh rate of 5 seconds. You can add argument parsing or just change the hard-coded delay to suit your needs. This example does zero input validation before running whatever command is provided. Your security spidey-sense should be tingling in a big way. Do not use this example with any sort of elevated privileges on a shared system.

3
  • wow this behaves exactly as i imagined very cool :) fun stuff together with 'sensors' Thank you!
    – new User
    Commented Oct 27, 2020 at 14:19
  • 1
    added > /dev/null 2>&1 to 'play' so it doesnt show in terminal output
    – new User
    Commented Oct 27, 2020 at 16:00
  • 1
    Good call on redirecting play to /dev/null. I had that commented out during my testing so didn't think of it.
    – Kenny
    Commented Oct 28, 2020 at 6:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .