有没有更好的方法将 MacOS Volume 获取为整数值? (Bash)
Is there a better way to get MacOS Volume as an integer value? (Bash)
我正在尝试获取用于 Übersicht 小部件的 MacOS 输出音量的整数值,并且我有一个有效(但混乱)的解决方案。问题是该值存储为百分比,四舍五入到最接近的整数。我考虑过使用线性回归来获得一个 return 值 1-64 的函数,但是小数是……不是 bash 中的东西。我还需要在一行中执行此操作,这会导致代码整体混乱。无论如何,这是我当前的代码:
vol=$(osascript -e 'get volume settings' | cut -f2 -d':' | cut -f1 -d','); [ \"$vol\" = \"2\" ] &&let vol=1; [ \"$vol\" = \"3\" ] &&let vol=2; [ \"$vol\" = \"5\" ] &&let vol=3; [ \"$vol\" = \"6\" ] &&let vol=4; [ \"$vol\" = \"8\" ] &&let vol=5; [ \"$vol\" = \"9\" ] &&let vol=6; [ \"$vol\" = \"11\" ] &&let vol=7; [ \"$vol\" = \"13\" ] &&let vol=8; [ \"$vol\" = \"14\" ] &&let vol=9; [ \"$vol\" = \"16\" ] &&let vol=10; [ \"$vol\" = \"17\" ] &&let vol=11; [ \"$vol\" = \"19\" ] &&let vol=12; [ \"$vol\" = \"20\" ] &&let vol=13; [ \"$vol\" = \"22\" ] &&let vol=14; [ \"$vol\" = \"23\" ] &&let vol=15; [ \"$vol\" = \"25\" ] &&let vol=16; [ \"$vol\" = \"26\" ] &&let vol=17; [ \"$vol\" = \"28\" ] &&let vol=18; [ \"$vol\" = \"30\" ] &&let vol=19; [ \"$vol\" = \"31\" ] &&let vol=20; [ \"$vol\" = \"33\" ] &&let vol=21; [ \"$vol\" = \"34\" ] &&let vol=22; [ \"$vol\" = \"36\" ] &&let vol=23; [ \"$vol\" = \"38\" ] &&let vol=24; [ \"$vol\" = \"39\" ] &&let vol=25; [ \"$vol\" = \"41\" ] &&let vol=26; [ \"$vol\" = \"42\" ] &&let vol=27; [ \"$vol\" = \"44\" ] &&let vol=28; [ \"$vol\" = \"45\" ] &&let vol=29; [ \"$vol\" = \"47\" ] &&let vol=30; [ \"$vol\" = \"48\" ] &&let vol=31; [ \"$vol\" = \"50\" ] &&let vol=32; [ \"$vol\" = \"51\" ] &&let vol=33; [ \"$vol\" = \"54\" ] &&let vol=34; [ \"$vol\" = \"55\" ] &&let vol=35; [ \"$vol\" = \"56\" ] &&let vol=36; [ \"$vol\" = \"58\" ] &&let vol=37; [ \"$vol\" = \"60\" ] &&let vol=38; [ \"$vol\" = \"61\" ] &&let vol=39; [ \"$vol\" = \"62\" ] &&let vol=40; [ \"$vol\" = \"65\" ] &&let vol=41; [ \"$vol\" = \"66\" ] &&let vol=42; [ \"$vol\" = \"67\" ] &&let vol=43; [ \"$vol\" = \"68\" ] &&let vol=44; [ \"$vol\" = \"70\" ] &&let vol=45; [ \"$vol\" = \"72\" ] &&let vol=46; [ \"$vol\" = \"74\" ] &&let vol=47; [ \"$vol\" = \"75\" ] &&let vol=48; [ \"$vol\" = \"76\" ] &&let vol=49; [ \"$vol\" = \"78\" ] &&let vol=50; [ \"$vol\" = \"79\" ] &&let vol=51; [ \"$vol\" = \"81\" ] &&let vol=52; [ \"$vol\" = \"83\" ] &&let vol=53; [ \"$vol\" = \"85\" ] &&let vol=54; [ \"$vol\" = \"86\" ] &&let vol=55; [ \"$vol\" = \"88\" ] &&let vol=56; [ \"$vol\" = \"89\" ] &&let vol=57; [ \"$vol\" = \"91\" ] &&let vol=58; [ \"$vol\" = \"92\" ] &&let vol=59; [ \"$vol\" = \"94\" ] &&let vol=60; [ \"$vol\" = \"95\" ] &&let vol=61; [ \"$vol\" = \"97\" ] &&let vol=62; [ \"$vol\" = \"98\" ] &&let vol=63; [ \"$vol\" = \"100\" ] &&let vol=64; mute=$(osascript -e 'get volume settings' | cut -f2 -d'd' | cut -f2 -d':'); [ \"$mute\" = \"true\" ] &&let vol=0; echo $vol
基本上我只是获取值,将其转换为数字 1-64,如果系统静音,则将该值设置为零,然后 returning 该值。想法?我是 bash 的新手,所以请原谅我明显缺乏基础知识!
TL;DR: awk
为王,直接用awk
:
osascript -e 'get volume settings' | awk '-F:|,' '/true/ { print 0; exit; } { print int( / (100 / 64)) }'
这是我在 CharlesDuffy 展示他的力量水平之前尝试过的一些旧东西:
小数可以是bash中的东西,你只需要一个工具。正如评论所建议的那样,awk
非常擅长这种事情:
osascript -e 'get volume settings' | awk '-F:|,' '{print int( / (100 / 64))}'
最后,您可以只检查 true
或 false
是否在字符串中,并根据此重新设置音量:
# if we see "true" in the string, we're muted and should set volume to 0
osascript -e 'get volume settings' | grep "true" &>/dev/null && vol=0;
将所有这些放在一起,我们得到
osascript -e 'get volume settings' | awk '-F:|,' '{print int( / (100 / 64))}';
osascript -e 'get volume settings' | grep "true" &>/dev/null && vol=0;
echo "$vol"
如果有必要,您可以随时将它们放在一起。
您可以以牺牲可读性为代价使其更短,或者更长并保存对 osascript
的调用,这样您只调用一次。
如果如您所说,您只需要输出量,那么您就不需要awk
。如果您在将非整数小数四舍五入为整数时不需要数学准确性,您可以使用:
osascript <<< "(output volume of (get volume settings) * 0.64) as integer"
值得注意的是,这需要 0.5 到 0 和 2.5 到 2,但大多数其他一半表现正常(这与内部浮点错误有关)。
如果你想保持准确性,那么你可以使用这个:
osascript <<< "round ((output volume of (get volume settings)) * 0.64) rounding as taught in school"
这将按照人们在数学考试中会(或应该)的方式进行四舍五入。
用 vol=$( ... )
围绕所有变量赋值,将三个点替换为上面两个表达式之一。
Muted/Not 静音
用上面两个中的第二个来演示,在音量静音的情况下,给bash
变量vol
赋值0
的方法是这样的:
vol=$(( $(osascript <<< "tell (get volume settings) to ¬
if not output muted then tell (output volume * 0.64) ¬
to continue round it rounding as taught in school") ))
为了便于阅读,我将 AppleScript 分成几行,您可以保持原样,或者删除连续字符 (¬
) 并将其放在一行中(如果您需要的话)。
这使用了bash
的算术扩展符号,$(( ... ))
,其中是对osascript
的调用,现在有条件地return当且仅当系统音量未静音时output volume
的值。
如果系统音量被静音,那么脚本return什么都没有——也就是一个空表达式——其中,一个bash
算术表达式恰好评估为 0
.
只要你感兴趣……
还有一些其他方法可以使用 bash
算术表达式来达到类似的效果:
您可以选择将整个赋值移动到算术展开式中:
(( vol=$(osascript <<< "tell (get volume settings) to ¬
if not output muted then tell (output volume * 0.64) ¬
to continue round it rounding as taught in school")+0 ))
在这种情况下,我们必须在表达式中添加 0
:这是因为 AppleScript 的一个可能结果是 return 什么都没有,这将导致非感性的数学表达式,即(( vol= ))
。然而,(( vol=+0 ))
绝对没问题,当 AppleScript return 是一个数字时,它不会改变结果的值。
这种语法形式很有用,因为系统音量是否静音将反映在这行bash
代码的return状态中,即如果系统音量被静音, return 状态不为零。
计算算术表达式的另一种方法是bash
,即使用let
。由于变量赋值是作为算术表达式本身的一部分进行的,因此还需要添加 0
以确保在所有情况下都能进行完整有效的计算:
let vol=$(osascript <<< "tell (get volume settings) to ¬
if not output muted then tell (output volume * 0.64) ¬
to continue round it rounding as taught in school")+0
并且,如果系统音量静音,return 状态将再次为非零(请注意,这并不意味着 vol
的值将非零;它实际上,必然为零)。
如果 return 状态不是您要使用的东西,那么所有这三种形式在本质上是相同的,其中 none 与另外两个(除非有人发现一种特定的语法在视觉上更刺耳)。
我故意不使用 bc
来计算这些算术表达式。 bc
是 bash
中最常用的主要数学程序,尤其是在进行浮点运算时。然而,我的解决方案的首要主题是保持解决方案尽可能简单,而不是在不必要的情况下依赖到外部程序的管道链——而且效率也低于利用 bash
能够原生地做。
我正在尝试获取用于 Übersicht 小部件的 MacOS 输出音量的整数值,并且我有一个有效(但混乱)的解决方案。问题是该值存储为百分比,四舍五入到最接近的整数。我考虑过使用线性回归来获得一个 return 值 1-64 的函数,但是小数是……不是 bash 中的东西。我还需要在一行中执行此操作,这会导致代码整体混乱。无论如何,这是我当前的代码:
vol=$(osascript -e 'get volume settings' | cut -f2 -d':' | cut -f1 -d','); [ \"$vol\" = \"2\" ] &&let vol=1; [ \"$vol\" = \"3\" ] &&let vol=2; [ \"$vol\" = \"5\" ] &&let vol=3; [ \"$vol\" = \"6\" ] &&let vol=4; [ \"$vol\" = \"8\" ] &&let vol=5; [ \"$vol\" = \"9\" ] &&let vol=6; [ \"$vol\" = \"11\" ] &&let vol=7; [ \"$vol\" = \"13\" ] &&let vol=8; [ \"$vol\" = \"14\" ] &&let vol=9; [ \"$vol\" = \"16\" ] &&let vol=10; [ \"$vol\" = \"17\" ] &&let vol=11; [ \"$vol\" = \"19\" ] &&let vol=12; [ \"$vol\" = \"20\" ] &&let vol=13; [ \"$vol\" = \"22\" ] &&let vol=14; [ \"$vol\" = \"23\" ] &&let vol=15; [ \"$vol\" = \"25\" ] &&let vol=16; [ \"$vol\" = \"26\" ] &&let vol=17; [ \"$vol\" = \"28\" ] &&let vol=18; [ \"$vol\" = \"30\" ] &&let vol=19; [ \"$vol\" = \"31\" ] &&let vol=20; [ \"$vol\" = \"33\" ] &&let vol=21; [ \"$vol\" = \"34\" ] &&let vol=22; [ \"$vol\" = \"36\" ] &&let vol=23; [ \"$vol\" = \"38\" ] &&let vol=24; [ \"$vol\" = \"39\" ] &&let vol=25; [ \"$vol\" = \"41\" ] &&let vol=26; [ \"$vol\" = \"42\" ] &&let vol=27; [ \"$vol\" = \"44\" ] &&let vol=28; [ \"$vol\" = \"45\" ] &&let vol=29; [ \"$vol\" = \"47\" ] &&let vol=30; [ \"$vol\" = \"48\" ] &&let vol=31; [ \"$vol\" = \"50\" ] &&let vol=32; [ \"$vol\" = \"51\" ] &&let vol=33; [ \"$vol\" = \"54\" ] &&let vol=34; [ \"$vol\" = \"55\" ] &&let vol=35; [ \"$vol\" = \"56\" ] &&let vol=36; [ \"$vol\" = \"58\" ] &&let vol=37; [ \"$vol\" = \"60\" ] &&let vol=38; [ \"$vol\" = \"61\" ] &&let vol=39; [ \"$vol\" = \"62\" ] &&let vol=40; [ \"$vol\" = \"65\" ] &&let vol=41; [ \"$vol\" = \"66\" ] &&let vol=42; [ \"$vol\" = \"67\" ] &&let vol=43; [ \"$vol\" = \"68\" ] &&let vol=44; [ \"$vol\" = \"70\" ] &&let vol=45; [ \"$vol\" = \"72\" ] &&let vol=46; [ \"$vol\" = \"74\" ] &&let vol=47; [ \"$vol\" = \"75\" ] &&let vol=48; [ \"$vol\" = \"76\" ] &&let vol=49; [ \"$vol\" = \"78\" ] &&let vol=50; [ \"$vol\" = \"79\" ] &&let vol=51; [ \"$vol\" = \"81\" ] &&let vol=52; [ \"$vol\" = \"83\" ] &&let vol=53; [ \"$vol\" = \"85\" ] &&let vol=54; [ \"$vol\" = \"86\" ] &&let vol=55; [ \"$vol\" = \"88\" ] &&let vol=56; [ \"$vol\" = \"89\" ] &&let vol=57; [ \"$vol\" = \"91\" ] &&let vol=58; [ \"$vol\" = \"92\" ] &&let vol=59; [ \"$vol\" = \"94\" ] &&let vol=60; [ \"$vol\" = \"95\" ] &&let vol=61; [ \"$vol\" = \"97\" ] &&let vol=62; [ \"$vol\" = \"98\" ] &&let vol=63; [ \"$vol\" = \"100\" ] &&let vol=64; mute=$(osascript -e 'get volume settings' | cut -f2 -d'd' | cut -f2 -d':'); [ \"$mute\" = \"true\" ] &&let vol=0; echo $vol
基本上我只是获取值,将其转换为数字 1-64,如果系统静音,则将该值设置为零,然后 returning 该值。想法?我是 bash 的新手,所以请原谅我明显缺乏基础知识!
TL;DR: awk
为王,直接用awk
:
osascript -e 'get volume settings' | awk '-F:|,' '/true/ { print 0; exit; } { print int( / (100 / 64)) }'
这是我在 CharlesDuffy 展示他的力量水平之前尝试过的一些旧东西:
小数可以是bash中的东西,你只需要一个工具。正如评论所建议的那样,awk
非常擅长这种事情:
osascript -e 'get volume settings' | awk '-F:|,' '{print int( / (100 / 64))}'
最后,您可以只检查 true
或 false
是否在字符串中,并根据此重新设置音量:
# if we see "true" in the string, we're muted and should set volume to 0
osascript -e 'get volume settings' | grep "true" &>/dev/null && vol=0;
将所有这些放在一起,我们得到
osascript -e 'get volume settings' | awk '-F:|,' '{print int( / (100 / 64))}';
osascript -e 'get volume settings' | grep "true" &>/dev/null && vol=0;
echo "$vol"
如果有必要,您可以随时将它们放在一起。
您可以以牺牲可读性为代价使其更短,或者更长并保存对 osascript
的调用,这样您只调用一次。
如果如您所说,您只需要输出量,那么您就不需要awk
。如果您在将非整数小数四舍五入为整数时不需要数学准确性,您可以使用:
osascript <<< "(output volume of (get volume settings) * 0.64) as integer"
值得注意的是,这需要 0.5 到 0 和 2.5 到 2,但大多数其他一半表现正常(这与内部浮点错误有关)。
如果你想保持准确性,那么你可以使用这个:
osascript <<< "round ((output volume of (get volume settings)) * 0.64) rounding as taught in school"
这将按照人们在数学考试中会(或应该)的方式进行四舍五入。
用 vol=$( ... )
围绕所有变量赋值,将三个点替换为上面两个表达式之一。
Muted/Not 静音
用上面两个中的第二个来演示,在音量静音的情况下,给bash
变量vol
赋值0
的方法是这样的:
vol=$(( $(osascript <<< "tell (get volume settings) to ¬
if not output muted then tell (output volume * 0.64) ¬
to continue round it rounding as taught in school") ))
为了便于阅读,我将 AppleScript 分成几行,您可以保持原样,或者删除连续字符 (¬
) 并将其放在一行中(如果您需要的话)。
这使用了bash
的算术扩展符号,$(( ... ))
,其中是对osascript
的调用,现在有条件地return当且仅当系统音量未静音时output volume
的值。
如果系统音量被静音,那么脚本return什么都没有——也就是一个空表达式——其中,一个bash
算术表达式恰好评估为 0
.
只要你感兴趣……
还有一些其他方法可以使用 bash
算术表达式来达到类似的效果:
您可以选择将整个赋值移动到算术展开式中:
(( vol=$(osascript <<< "tell (get volume settings) to ¬ if not output muted then tell (output volume * 0.64) ¬ to continue round it rounding as taught in school")+0 ))
在这种情况下,我们必须在表达式中添加
0
:这是因为 AppleScript 的一个可能结果是 return 什么都没有,这将导致非感性的数学表达式,即(( vol= ))
。然而,(( vol=+0 ))
绝对没问题,当 AppleScript return 是一个数字时,它不会改变结果的值。这种语法形式很有用,因为系统音量是否静音将反映在这行
bash
代码的return状态中,即如果系统音量被静音, return 状态不为零。计算算术表达式的另一种方法是
bash
,即使用let
。由于变量赋值是作为算术表达式本身的一部分进行的,因此还需要添加0
以确保在所有情况下都能进行完整有效的计算:let vol=$(osascript <<< "tell (get volume settings) to ¬ if not output muted then tell (output volume * 0.64) ¬ to continue round it rounding as taught in school")+0
并且,如果系统音量静音,return 状态将再次为非零(请注意,这并不意味着
vol
的值将非零;它实际上,必然为零)。
如果 return 状态不是您要使用的东西,那么所有这三种形式在本质上是相同的,其中 none 与另外两个(除非有人发现一种特定的语法在视觉上更刺耳)。
我故意不使用 bc
来计算这些算术表达式。 bc
是 bash
中最常用的主要数学程序,尤其是在进行浮点运算时。然而,我的解决方案的首要主题是保持解决方案尽可能简单,而不是在不必要的情况下依赖到外部程序的管道链——而且效率也低于利用 bash
能够原生地做。