You are not logged in.
I'm trying to write a panel script that pipes stuff to Lemonboy's bar. I've stripped the code to create a small sample that illustrates the issue I'm experiencing:
#! /bin/sh
trap 'trap - TERM; rm linelog; kill 0' INT TERM QUIT EXIT
wm_infos=
title_infos="[hold on a sec]"
{
bspc control --subscribe &
xtitle -s -f 'T%s' &
} |\
while read -r line ; do
case "$line" in
T*)
title_infos="${line#?}"
;;
W*)
wm_infos="${line#?}"
;;
esac
echo "$line" >> linelog
printf "\\l%s\n" "$wm_infos $title_infos"
done | bar
wait
Roughly half the time, when this panel script is started, only bspc's output is displayed in the bar, yet both xtitle's and bspc's output appear in "linelog". In this case, after focusing another window, xtitle's new output appears in the bar. The other half of the time, both bspwm's and xtitle's output appear right when the panel script is launched as expected.
Adding a small delay (sleep 0.5) between launching "bspc control" and "xtitle" causes xtitle's output to appear every time after 0.5 seconds, but I'd like to know what's actually wrong with this; bar should be displaying everything that is piped to it. I've been trying to fix this for a good part of the day, sadly enough. Any suggestions?
Offline
I've had some trouble with a somewhat similar python script piping info to bar. I don't know if it's the same issue, but it seems that bar can be picky about the font and glyphs it displays. For example, I can use the stlarch font when compiling bar and it works perfectly with the various special characters like this:
"-misc-stlarch-medium-r-normal--10-*-*-*-*-*-*-*"
However, if I change the size to 17 (which should be a valid size according to xfontsel), bar cuts off and otherwise mangles the text, seemingly around the 'special' characters in the font.
If this helps, great...if not...good luck!
Scott
Last edited by firecat53 (2014-02-09 02:54:36)
Offline
Thanks firecat53, although I think these are two different issues.
The most elegant solution I could figure out simply involves placing a "sleep 0.01" in-between the bspc and xtitle forks, as well as other programs launched. I mean, I can spare a few hundredths of a second on login for my panel to load, lol.
EDIT: I'd at least like to know if this is a bug in bar or a problem with my script, so I can report it if necessary.
Last edited by Mindstormscreator (2014-02-09 03:21:36)
Offline
You are probably reaching the while loop before the two commands have some output since you aren't waiting for them. That's what the & does...
You're just jealous because the voices only talk to me.
Offline
You are probably reaching the while loop before the two commands have some output since you aren't waiting for them. That's what the & does...
I don't think it should matter though, since the loop only runs through after receiving a line from stdin. Every time, the log file shows that the output of both commands pass through the loop and are therefore printed into bar, but bar sometimes decides to not print the second line of input received, as far as I can tell.
Offline
Offline
Lies. Show me evidences that it's bar fault and I'll provide a fix asap.
LemonMan, I love your bar, but I'm blaming it for this one. Here's a simple sh snippet which should prove it:
#! /bin/sh
{
echo "0" &
echo "1" &
} | while read -r line ; do
if [ $line == "0" ]; then
info_1=$line
elif [ $line == "1" ]; then
info_2=$line
fi
echo "$info_1 $info_2" | tee -a logfile
done | bar -bp
Roughly half the time, bar incorrectly outputs just '0' or just '1', when really it should be displaying the final state of the while loop when info_1 and info_2 contain values. For example, on a run when bar displayed just a "1", logfile contained:
1
0 1
Therefore, it seems it is just displaying the first line, despite having received the second one afterwards.
Last edited by Mindstormscreator (2014-02-10 02:20:22)
Offline
bar does stop parsing the input once the trailing null byte or a newline is met. The reason behind this decision is simply because bar is a single-line bar. You should gather all your data first then send it off to bar or, if that's not possible I could lift the newline condition.
Offline
bar does stop parsing the input once the trailing null byte or a newline is met.
As in, bar will stop parsing, print the current line, and begin parsing the next line once newline or the null byte is reached? I don't understand how this would cause bar to not print the second piped input received immediately after the first versus having received it 0.01 seconds later. Inside the while loop, both printed lines are properly terminated with a newline, so the second echoed line should be visible in bar, right?
Offline
The sample snippet does always output "0 1" with no problem at all.
Anyway you're fetching data the wrong way, that fork and read thing gives me shivers.
Alright, maybe I suck at bash scripting, but I'm confident bar is messing up. That last snippet, for me, must be ran 10-15 times in order to see the effect. This should be a much, much more clean-cut sample which shows it:
#! /bin/sh
{
echo "Info 0"
#sleep 0.01
echo "Info 1"
} | tee logfile | bar -bp
Now, every single time when the "sleep 0.01" line remains commented, bar displays "Info 0", which is wrong. The logfile in this case displays:
Info 0
Info 1
When "sleep 0.01" is uncommented, bar always displays "Info 1", and the logfile is the same.
Please try this one out, LemonMan.
Last edited by Mindstormscreator (2014-02-10 17:13:22)
Offline
poll() is incompatible with buffered streams. As soon as the data is read from the pipe into the internal stream buffer, poll() doesn't work anymore. Disable the buffer and it works again:
main (int argc, char **argv)
{
setvbuf(stdin, NULL, _IONBF, 0);
char input[1024] = {0, };
| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |
Offline