2

I'm using alsa to fiddle around with the volume on a Bluetooth speaker I have connected. It's a 1-speaker setup; just something to provide some background.

I can 'get' the volume setting fm the CLI as follows:

$ amixer sget Master
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 22938 [35%] [on]
  Front Right: Playback 22938 [35%] [on]

I can 'set' the volume fm the CLI as follows:

$ amixer sset Master 50%
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 32768 [50%] [on]
  Front Right: Playback 32768 [50%] [on]

I don't need all this verbosity, so I decided to create a function, and two aliases in my ~/.bashrc file to reduce that. The function is not working as I expected:

From the CLI, this works fine:

$ amixer sget Master | awk -F"[][]" '/Right:/ { print $2 }'
35%

But when I put this into my function statement in ~/.bashrc, it works differently:

# functions & aliases for alsa mixer/volume control
function vol-get() {
   amixer sget Master | awk -F"[][]" '/Left:/ { print $2 }'
}
export -f vol-get

alias vol-up='amixer sset Master 5%+ > /dev/null && vol-get'
alias vol-dn='amixer sset Master 5%- > /dev/null && vol-get'

Re-reading ~/.bashrc & running the vol-get function yields the following:

$ . ~/.bashrc
$ vol-get
  Front Left: Playback 22938 [35%] [on]
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ?? what happened here ??
$ vol-up
  Front Left: Playback 26215 [40%] [on]
$ 

So - I'm close, but I don't understand why my | awk ... behaves differently inside the function than it does on the command line. Can someone explain and correct this?


Edits for answers to some of the Questions raised in the comments:

EDIT #1:

$ command -V vol-get
vol-get is a function
vol-get ()
{
    amixer sget Master | awk -F"[][]" '/Left:/ { print $2 }'
} 

$ awk --version
awk: not an option: --version
$ man awk
# reveals that I am actually calling `mawk`, Version 1.3.4

EDIT #2:

RE: non-printing characters; note this is a partial c&p from the output (i.e. verbatim):

$ cat -vet ~/.bashrc
...
function vol-get() {$
    amixer sget Master | awk -F'[][]' '/Left:/ { print $2 }'$
}$
...
1
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on Unix & Linux Meta, or in Unix & Linux Chat. Comments continuing discussion may be removed.
    – terdon
    Commented Oct 22, 2024 at 11:05

1 Answer 1

1

This is a half answer, because I'm not sure of the root cause:

In the function definition, substituting

awk -F"[][]"

with

awk -F'[][]'

Fixes the OP's problem, reporting just the value 50%. I've been unable to reproduce this via my own WSL box as it works with both variations.

GNU Awk 5.0.1, API: 2.0
GNU bash, version 5.0.17(1)-release
Kernel: 5.10.102.1-microsoft-standard-WSL2

$ command -V test_awk
test_awk is a function
test_awk ()
{
    echo 'Front Left: Playback 32768 [50%] [on]' | awk -F"[][]" '/Left:/ { print $2  }
}

$ test_awk
50%

Which is expected, since according to the bash manual:

Enclosing characters in double quotes (") preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !.

No mention of [] there.

5
  • 4
    But even in the face of comments claiming changing the quotes fixes it, this is a really, really, unsatisfying an answer, since it doesn't explain why that would fix it. In sh-like shells awk -F"[][]" is exactly the same as awk -F'[][]' since the square brackets aren't special in double or in single quotes. And if they had a non-sh-like shell, they'd likely know, and we'd still need an explanation on what happens.
    – ilkkachu
    Commented Oct 20, 2024 at 12:21
  • 2
    @ilkkachu - I agree. I'm also highly unsatisfied by my own answer. If a better one comes along that explains the root cause, then it should definitely be accepted. Commented Oct 20, 2024 at 12:33
  • 3
    The only way I can imagine that changing " to ' could have fixed the problem is if you have a bug elsewhere in your code, e.g. your complete code contains something like bash -c "awk -F"[][]" '...' file" which you're now changing to bash -c "awk -F'[][]' '...' file".
    – Ed Morton
    Commented Oct 21, 2024 at 12:33
  • @EdMorton: Could you explain that comment, please?
    – Seamus
    Commented Oct 23, 2024 at 3:39
  • 2
    Your awk script on it's own won't do what you say it's doing so if you're seeing the behavior you say you are then the problem has to be something in the surrounding code which we can't see such as mismatched quotes. For example, echo "*" will output *. So will bash -c 'echo "*"'. But now try bash -c "echo "*"" and it'll undesirably output the list of files in your current directory. The echo "*" didn't change but the way you're calling it did. You could "fix" it by changing the way you call echo to bash -c "echo '*'" but that may not be the best solution.
    – Ed Morton
    Commented Oct 23, 2024 at 10:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.