I have a text status bar on a tiling window manager and I am using tcl to feed information to it. At the moment I need a command line that output the volume level 0% to 100%. I am using Arch Linux.
- 807,993
- 194
- 1,674
- 2,175
- 1,456
- 2
- 16
- 22
-
1Looks like you should be able to do it by parsing `/var/lib/alsa/asound.state`. – jordanm Sep 05 '13 at 19:22
-
1Note: in the future, saying you're using Arch isn't really relevant. What actually matters is what sound subsystem you're using, e.g. ALSA, OSS or PulseAudio. – strugee Sep 05 '13 at 19:55
-
3Instead of adding "closed" to your title, you should just answer your own question and leave it – jordanm Sep 05 '13 at 19:55
6 Answers
A one-liner to parse amixer's output for volume in a status bar:
awk -F"[][]" '/dB/ { print $2 }' <(amixer sget Master)
Edit: As of November 2020, the updated amixer for Arch Linux is 1.2.4 which has no 'dB' in the output. So, the command should replaced by:
awk -F"[][]" '/Left:/ { print $2 }' <(amixer sget Master)- 3
- 2
- 71,734
- 34
- 193
- 226
-
1
-
4@approximatenumber It sets the field separator as either `]` or `[`. – jasonwryan May 24 '16 at 18:38
-
1
-
1
-
2@mike23 `vol=$(awk '/%/ {gsub(/[\[\]]/,""); print $4}' <(amixer sget Master))` – jasonwryan Jan 16 '18 at 21:20
-
`amixer: Unable to find simple control 'Master',0`. apparently I have to add `-c 1` to the amixer command, but how can an agnostic one-liner know this? – Michael May 03 '19 at 19:37
-
also, it would be better to parse the "absolute" (non-percent) volume, as setting by percent seems to have an off by one error for one values (perhaps due to rounding?) so if you save and then restore volume from this command you will make the volume louder. – Michael May 03 '19 at 20:16
You can use amixer to do this.
Examples
$ amixer get Master
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined penum
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 65536 [100%] [off]
Front Right: Playback 65536 [100%] [off]
You can also change it and mute it like so:
set volume 75%
$ amixer set Master 75%
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined penum
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 49152 [75%] [on]
Front Right: Playback 49152 [75%] [on]
mute/unmute
$ amixer set Master toggle
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined penum
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 65536 [100%] [on]
Front Right: Playback 65536 [100%] [on]
You can quiet the output if you don't want to see any of it with the --quiet switch.
$ amixer --quiet set Master 75%
$
- 363,520
- 117
- 767
- 871
Right
amixer sget Master | grep 'Right:' | awk -F'[][]' '{ print $2 }'
85%
Left
amixer sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }'
85%
Sound server
If you are not using pulseaudio as default you can specify to amixer what server to use with -D pulse
amixer -D pulse sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }'
85%
- 13,920
- 7
- 41
- 79
-
This doesn't work for me... Master for some reason doesn't have "Left" and "Right" despite other channels such as "Speaker" having it. – Michael May 03 '19 at 20:17
Based off some of the answers already here, but managed to get avoided using both awk and grep in the same command (because that would be bloat).
amixer -D pulse get Master | awk -F 'Left:|[][]' 'BEGIN {RS=""}{ print $3 }'
Explanation:
amixer -D pulse get Master ...
Pretty self-explanatory; just lists stuff about our Master control (-D pulse because I'm using pulse). For me, it prints:
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 52428 [80%] [on]
Front Right: Playback 52428 [80%] [on]
... awk -F 'Left:|[][]' ...
Uses regex to define field separator, which can be Left: or either ][.
... { print $3 }'
Now we print out the 3rd column. Works out that since we separate on Left: as well, that the value of $3 for the right speaker will be blank
... 'BEGIN {RS=""}...
Now we're printing only 80% plus a bunch of newlines. For the script I was writing, I didn't want these, so I removed most of them with {RS=""}, and then got rid of a final one at the start by adding in the BEGIN
- 21
- 1
- 5
One Solution i have is with using echo(could not find it anywhere so i would love to know if this is not the best way to do),
echo "${$(echo "${$(amixer get Master | grep Left:)#*\[}")%%\]*}"
i just let Echo delete both the beginning till the first '[' and from the end till the last ']'.
Here's what works for me. YMMV.
$ amixer get Master | egrep -o '[0-9]{1,3}%'
51%
$
- 945
- 8
- 25