Issue
Following from my previous question here, please see below a fuller form of my question.
Code use case
The current code is a module for use in polybar, a customisable status bar. As per the first link, polybar is drawn using a configuration file and each bar that is called (by, for instance, running the polybar mybar
) reads the configuration file for any given modules. A full example can be seen here. Custom or user defined modules are loaded by calling the relevant script file. For instance:
[module/test]
type = custom/script
exec = some/script/file
tail = true
Polybar accepts, at the very least, shell scripts and python scripts (and perhaps others, though I have not tested this). For the purposes of this question, I am concerned with the appropriateness of my shell script and not its interface with polybar (which currently works as expected; though as @EdMorton explains, this may not be intended functionality, hence this question).
Current code
The following is a minimal working example of my code.
#!/bin/bash
smile=#d1dadf;
sad=#ff5833;
angry=#1a88a4;
laugh=#daf7a6;
while true; do
# get hour
time=$(date +%_H -u);
# set empty hour
timeShow=TEST;
# set empty emoji
emoji=;
if [ $time -ge 0 ] && [ $time -lt 6 ];
then
emoji=%{F$smile}😀%{F-}
elif [ $time -ge 6 ] && [ $time -lt 12 ];
then
emoji=%{F$sad}😢%{F-}
elif [ $time -ge 12 ] && [ $time -lt 18 ];
then
emoji=%{F$angry}😡%{F-}
elif [ $time -ge 18 ] && [ $time -ne 0 ];
then
emoji=%{F$laugh}😆%{F-}
fi
if [[ "$emoji" =~ [😢] ]];
then
((timeShow = time - 1))
elif [[ "$emoji" =~ [😡] ]];
then
((timeShow = time - 2))
elif [[ "$emoji" =~ [😆] ]];
then
((timeShow = time - 3))
fi
echo "$timeShow:$(date '+%M' -u) $emoji"
sleep 1
done
Explanation of inputs (and outputs)
Running the script as is requires no input (the output is calculated from within the script itself). Hence running the script is simply done via:
./script.sh
The output should (and does) return the formatted time, along with the emoji wrapped in colour format tags, as described above.
The program as it stands takes the current UTC hour from date
. This value (stored in the variable time
) is then modified and stored within timeShow
. Assuming a particular range of hours (and hence emoji
), the script then modifies timeShow
by either subtracting 1, 2, or 3. The emoji are found in the string emoji
by performing a regex operation to locate the character, which is wrapped by colour formatting.
Expected output given hardcoded input
Changing the following:
while true; do... done
To this:
for time in 8 12 22 0; do... done
In addition, the following lines should be changed to match below:
# get hour
#time=$(date +%_H -u);
# set default hour
timeShow=0
Should give the following as expected outputs, assuming the script is run on the hour.
Loop 1 (at 8 am) (offset of -1):
7:00 %{F#ff5833}😢%{F-}
Loop 2 (at 12 pm) (offset of -2):
10:00 %{F#1a88a4}😡%{F-}
Loop 3 (at 10 pm) (offset of -3):
19:00 %{F#daf7a6}😆%{F-}
Loop 4 (at 12 am) (offset of 0):
0:00 %{F#d1dadf}😀%{F-}
Desired output
The script works as intended. As mentioned above, however, this may not be accidental. The purpose of this question is to understand whether the approach used is producing the correct output, or only happens to do so. The regex at present isolates the character by using the [😀]
. For any glyph which may comprise 2 or more characters, M-bM-^XM-^A$
for instance, isolating the emoji thusly, [😀]
is potentially inaccurate as it would match the first corresponding character, leading to undesirable or unexpected behaviour. Further explanation of this problem is provided here.
Solution
Instead of matching $emoji
with a regexp, set another variable when you're setting emoji
, and use that when setting timeShow
.
#!/bin/bash
smile=#d1dadf;
sad=#ff5833;
angry=#1a88a4;
laugh=#daf7a6;
while true; do
# get hour
time=$(date +%_H -u);
# set empty hour
timeShow=TEST;
timeOffset=0
# set empty emoji
emoji=;
if [ $time -ge 0 ] && [ $time -lt 6 ];
then
emoji=%{F$smile}😀%{F-}
timeOffset=3
elif [ $time -ge 6 ] && [ $time -lt 12 ];
then
emoji=%{F$sad}😢%{F-}
timeOffset=1
elif [ $time -ge 12 ] && [ $time -lt 18 ];
then
emoji=%{F$angry}😡%{F-}
timeOffset=2
elif [ $time -ge 18 ] && [ $time -ne 0 ];
then
emoji=%{F$laugh}😆%{F-}
timeOffset=3
fi
timeshow=$((time - timeOffset)
echo "$timeShow:$(date '+%M' -u) $emoji"
sleep 1 &
wait
done
Answered By - Barmar Answer Checked By - Pedro (WPSolving Volunteer)