上下文:我正在创建自己的i3-Bar脚本来读取在后台运行的其他(异步)脚本的输出,将它们连接起来,然后将它们echo
连接到i3-Bar本身。 / em>的
我传递输出的方式是普通文件,我猜(逻辑上)问题是文件有时会同时读写。重现此行为的最佳方法是暂停计算机,然后将其唤醒 - 我不知道确切的原因,我只能继续我从调试中看到的内容日志文件。
主要代码: 为了清晰起见添加了评论
#!/usr/bin/env bash
cd "${0%/*}";
trap "kill -- -$$" EXIT; #The bg. scripts are on a while [ 1 ] loop, have to kill them.
rm -r ../input/*;
mkdir ../input/; #Just in case.
for tFile in ./*; do
#Run all of the available scripts in the current directory in the background.
if [ $(basename $tFile) != "main.sh" ]; then ("$tFile" &); fi;
done;
echo -e '{ "version": 1 }\n['; #I3-Bar can use infinite array of JSON input.
while [ 1 ]; do
input=../input/*; #All of the scripts put their output in this folder as separate text files
input=$(sort -nr <(printf "%s\n" $input));
output="";
for tFile in $input; do
#Read and add all of the files to one output string.
if [ $tFile == "../input/*" ]; then break; fi;
output+="$(cat $tFile),";
done;
if [ "$output" == "" ]; then
echo -e "[{\"full_text\":\"ERR: No input files found\",\"color\":\"#ff0000\"}],\n";
else
echo -e "[${output::-1}],\n";
fi;
sleep 0.2s;
done;
示例输入脚本:
#!/usr/bin/env bash
cd "${0%/*}";
while [ 1 ]; do
echo -e "{" \
"\"name\":\"clock\"," \
"\"separator_block_width\":12," \
"\"full_text\":\"$(date +"%H:%M:%S")\"}" > ../input/0_clock;
sleep 1;
done;
问题不在于脚本本身,但事实是,i3-Bar收到格式错误的JSON输入( - &gt;解析错误),并终止 - 我稍后会显示此类日志。
另一个问题是,后台脚本应该异步运行,因为有些需要每隔1分钟更新一次nad,等等。所以使用FIFO并不是一个真正的选择,除非我创建一些丑陋低效的hacky东西。
我知道这里需要IPC,但我不知道如何有效地这样做。
随机崩溃的脚本输出 - 唤醒错误看起来相同
[{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"192.168.1.104 "},{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"100%"}],
[{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"192.168.1.104 "},,],
(错误由第二行创建) 如您所见,主脚本尝试读取文件,没有任何输出,但逗号仍然存在 - &gt;格式错误的JSON。
答案 0 :(得分:1)
立即错误很容易修复:如果相应的文件为空,请不要在output
附加条目:
for tFile in $input; do
[[ $tFile != "../input/*" ]] &&
[[ -s $tFile ]] &&
output+="$(<$tFile),"
done
但是这里存在潜在的竞争条件。仅仅因为特定的输入文件存在并不意味着数据已完全写入其中。我会将您的输入脚本更改为类似
#!/usr/bin/env bash
cd "${0%/*}";
while true; do
o=$(mktemp)
printf '{"name": "clock", "separator_block_width": 12, "full_text": %(%H:%M:%S)T}\n' > "$o"
mv "$o" ../input/0_clock
sleep 1
done
此外,${output%,}
是在必要时修剪尾随逗号的更安全的方法。