29

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.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
milarepa
  • 1,456
  • 2
  • 16
  • 22
  • 1
    Looks like you should be able to do it by parsing `/var/lib/alsa/asound.state`. – jordanm Sep 05 '13 at 19:22
  • 1
    Note: 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
  • 3
    Instead of adding "closed" to your title, you should just answer your own question and leave it – jordanm Sep 05 '13 at 19:55

6 Answers6

28

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)
jasonwryan
  • 71,734
  • 34
  • 193
  • 226
18

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%
$ 
slm
  • 363,520
  • 117
  • 767
  • 871
13

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%
intika
  • 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
1

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

7thFox
  • 21
  • 1
  • 5
0

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 ']'.

0

Here's what works for me. YMMV.

$ amixer get Master | egrep -o '[0-9]{1,3}%'
51%
$
ychaouche
  • 945
  • 8
  • 25