Почему ‘pipe-to-awk’ ведет себя иначе внутри функции?

Вопрос или проблема

Я использую alsa, чтобы поиграться с громкостью на подключенной Bluetooth-колонке. Это односpeakerная система; просто что-то для фона.

Я могу ‘получить’ настройки громкости из CLI следующим образом:

$ amixer sget Master
Простой контроль микшера 'Master',0
  Возможности: pvolume pswitch pswitch-joined
  Каналы воспроизведения: Левый фронт - Правый фронт
  Ограничения: Воспроизведение 0 - 65536
  Моно:
  Левый фронт: Воспроизведение 22938 [35%] [включено]
  Правый фронт: Воспроизведение 22938 [35%] [включено]

Я могу ‘установить’ громкость из CLI следующим образом:

$ amixer sset Master 50%
Простой контроль микшера 'Master',0
  Возможности: pvolume pswitch pswitch-joined
  Каналы воспроизведения: Левый фронт - Правый фронт
  Ограничения: Воспроизведение 0 - 65536
  Моно:
  Левый фронт: Воспроизведение 32768 [50%] [включено]
  Правый фронт: Воспроизведение 32768 [50%] [включено]

Мне не нужна вся эта болтовня, поэтому я решил создать функцию и два псевдонима в своем ~/.bashrc файле, чтобы сократить это. Функция работает не так, как я ожидал:

Из CLI это работает хорошо:

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

Но когда я помещаю это в свою функцию в ~/.bashrc, это работает иначе:

# функции и псевдонимы для управления микшером/громкостью alsa
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'

Перечитывая ~/.bashrc и запуская функцию vol-get, я получаю следующее:

$ . ~/.bashrc
$ vol-get
  Левый фронт: Воспроизведение 22938 [35%] [включено]
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ?? что здесь произошло ??
$ vol-up
  Левый фронт: Воспроизведение 26215 [40%] [включено]
$ 

Так что – я близок, но не понимаю, почему мой | awk ... ведет себя иначе внутри функции, чем на командной строке. Может кто-нибудь объяснить и исправить это?

ИЗМЕНЕНИЕ:

$ 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
# показывает, что я на самом деле вызываю `mawk`, версия 1.3.4

Ответ или решение

Почему команда ‘pipe-to-awk’ ведет себя иначе внутри функции?

Когда вы работаете с командной оболочкой, такой как Bash, важно понимать, что контекст выполнения команд может влиять на их поведение. В данном случае, при использовании amixer и awk внутри функции vol-get, результат отличается от ожидаемого. Давайте подробнее разберем, почему это происходит.

1. Структура вашей функции

Вот ваша функция vol-get:

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

Когда вы вызываете эту функцию, поиск ‘Left:’ выполняется на выводе команды amixer sget Master, и вы хотите, чтобы awk извлекал процент звука. Однако вместо того чтобы вернуть ожидаемые данные, функция отображает полную информацию о выводе amixer.

2. Проблемы с форматом вывода

Когда вы выполняете команду в CLI напрямую, она корректно находит нужные строки с текстом, однако внутри функции может иметь место несколько факторов, которые изменяют поведение:

  • Вывод команды: Убедитесь, что внутренняя структура текста выводимой команды amixer неизменная. Вы можете асинхронно проверить разницу в наличии строк, используя другие режимы ввода (например, сохраняйте вывод в файл и просматривайте его).

3. Ошибка в условиях поиска

Вы используете /Left:/ как паттерн для awk. Могло бы быть, что в вашем выводе amixer действительно нет строки "Left:". Проверьте, как выглядят выведенные строки, и измените условие на подходящее. Например, если вы хотите отобразить правый канал, возможно, нужно изменить условие на /Right:/ или проверить комбинацию.

4. Различия в окружении выполнения

Когда вы вызываете функцию, Bash использует несколько другие контексты, например, переменные среды. Возможно, что ваше окружение или установленный awk могут влиять на поведение.

Как вы указали, версия вашего awk — это mawk, и важно помнить, что разные реализации awk могут иметь разные синтаксисы или особенности обработки. Несмотря на то, что это не должно повлиять на базовую функциональность, лучше всего уточнить, что ваша реализация правильно обрабатывает ввод.

5. Несоответствие и отладка

При возникновении такой проблемы важно делать отладочную печать вывода перед передачей через awk:

function vol-get() {
   amixer sget Master | tee /tmp/amixer_output | awk -F"[][]" '/Left:/ { print $2 }'
   cat /tmp/amixer_output  # Посмотреть на вывод
}

Эта команда покажет вам, что именно передается в awk. Если вы увидите, что вывод не содержит искомую строку, необходимо пересмотреть логику или параметры поиска.

Заключение

Чтобы функция vol-get работала правильно, стоит проверить структуру вывода от amixer, задать правильные условия поиска в awk и убедиться, что все команды выполняются в ожидаемом формате и синтаксисе. Это позволит избежать проблем в будущем и обеспечит корректную работу ваших функций для управления громкостью.

Оцените материал
Добавить комментарий

Капча загружается...