Amixer Возвращая неправильное Значение звука

У меня есть решение, написанное для совместимости с оболочкой POSIX, но я тестировал его только в bash, {{1} } поэтому я не знаю наверняка, переносится ли он. И я не знаю zsh, поэтому я не пытался сделать его дружественным к zsh. Вы передаете в него свою команду; передача команды в качестве аргумента (ов) другой команде - это плохой дизайн * .

Конечно, любое решение этой проблемы должно знать , сколько строк и столбцов имеет терминал. В приведенном ниже коде я предположил, что вы можете полагаться на переменные среды LINES и COLUMNS (которые на меньше ] смотрит на). Более надежные методы:

  • используйте rows = "$ {LINES: = $ (tput lines)}" и cols = "$ {COLUMNS : = $ (tput cols)} ", как предложено AP или
  • посмотрите на вывод из stty size . Обратите внимание, что эта команда должна иметь терминал в качестве стандартного ввода, поэтому, если он находится в сценарии, и вы подключаетесь к сценарию, вам придется скажем, stty size (в bash) или stty size dev / tty . Захват вывода еще сложнее.

Секретный ингредиент: команда fold разбивает длинные строки так, как это делает экран, поэтому сценарий может правильно обрабатывать длинные строки.

#!/bin/sh
buffer=$(mktemp)
rows="$LINES"
cols="$COLUMNS"
while true
do
      IFS= read -r some_data
      e=$?        # 1 if EOF, 0 if normal, successful read.
      printf "%s" "$some_data" >> "$buffer"
      if [ "$e" = 0 ]
      then
            printf "\n" >> "$buffer"
      fi
      if [ $(fold -w"$cols" "$buffer" | wc -l) -lt "$rows" ]
      then
            if [ "$e" != 0 ]
            then
                  cat "$buffer"
            else
                  continue
            fi
      else
            if [ "$e" != 0 ]
            then
                  "${PAGER:="less"}" < "$buffer"
                  # The above is equivalent to
                  # cat "$buffer"   | "${PAGER:="less"}"
                  # … but that’s a UUOC.
            else
                  cat "$buffer" - | "${PAGER:="less"}"
            fi
      fi
      break
done
rm "$buffer"

Чтобы использовать это:

  • Поместите вышеуказанное в файл; предположим, вы назвали его mypager .
  • (Необязательно) поместите его в каталог, который является вашим путем поиска; например, $ HOME / bin .
  • Сделайте его исполняемым, набрав chmod + x mypager .
  • Используйте его в таких командах, как ps ax | mypager или ls -la | mypager .
    Если вы пропустили второй шаг (размещение сценария в каталоге, который является вашим путем поиска), вам придется выполнить ps ax | path_to_mypager / mypager , где path_to_mypager может быть относительным путем, например «. ».

* Почему передача команды в качестве аргумента (ов) другой команде является плохим дизайном?

I. Эстетика / Соответствие традициям / Философия Unix

У Unix есть философия Делай одно дело и делай это хорошо . Например, если программа собирается отображать данные определенным образом (как это делают пейджеры), , тогда она также не должна вызывать механизм, который производит данные . Вот для чего нужны трубы.

Не многие программы Unix выполняют заданные пользователем команды или программы. Давайте посмотрим на некоторые из них:

  • Оболочка, как в sh -c " command "
    Ну, выполнение заданных пользователем команд - это оболочки. ] job ; это One Thing , которое делает оболочка. (Конечно, я не говорю, что оболочка - это простая программа.)
  • env , nice , nohup , setsid , su и sudo . У этих программ есть что-то общее - все они существуют для запуска программы с измененной средой выполнения 1 . Они должны работать так, как они делают, потому что Unix обычно не позволяет вам изменять среду выполнения другого процесса; вы должны изменить ваш собственный процесс, а затем fork и / или exec .
    _______
    1 Я использую фразу среда выполнения в широком смысле, имея в виду не только переменные среды, {{1 }} но также и атрибуты процесса, такие как значение « nice », UID и GID, группа процессов, идентификатор сеанса, управляющий терминал, открытые файлы, рабочий каталог , значение umask , ulimit s, расположение сигналов, таймер тревоги и т. д.
  • Программы, позволяющие «избежать оболочки». Единственный пример, который приходит на ум, - vi / vim , хотя я почти уверен, что есть и другие. Это исторические артефакты. Они предшествуют оконным системам и даже системам управления заданиями; если вы редактируете файл и хотите сделать что-то еще (например, посмотрите список каталогов), у вас будет пришлось сохранить файл и выйти из редактора, чтобы вернуться в оболочку. Теперь вы можете переключиться в другое окно,или используйте Ctrl + Z (или введите : suspend ) , чтобы вернуться в оболочку, сохранив при этом редактор, {{1} } так что экранирование оболочки, возможно, устарело.

Я не считаю программы, которые выполняют другие (жестко запрограммированные) программы , чтобы использовать их возможности, а не дублировать их. Например, некоторые программы могут выполнять diff или sort . (Например, есть рассказы о том, что ранние версии заклинания использовали sort-u , чтобы получить список слов, используемых в документе , и затем diff - или, возможно, comm - чтобы сравнить этот список со списком слов словаря и определить, какие слова из документа {{1 }} не было в словаре.)

II. Проблемы с синхронизацией

В соответствии с вашим сценарием, строка RET = "$ ($ @)" не завершается , пока не завершится вызванная команда. Следовательно, ваш сценарий не может начать отображение данных до тех пор, пока команда, которая их генерирует, не будет завершена. Вероятно, самый простой способ исправить это - отделить команду генерации данных от программы отображения данных (хотя есть и другие способы).

III. История команд

  1. Предположим, вы запускаете некоторую команду с выводом, обработанным фильтром отображения, и вы просматриваете вывод и решаете, что хотите сохранить этот вывод в файл. Если вы набрали (в качестве гипотетического примера)

     ps ax | mypager 
     

    , затем введите

     !: 1> myfile 
     

    или нажмите и отредактируйте строку соответствующим образом. Теперь, если вы набрали

     mypager "ps ax" 
     

    , вы все равно можете вернуться и отредактировать эту команду в ps ax> myfile , {{ 1}}, но это не так просто.

  2. Или предположим, что вы решили запустить ps uax следующим. Если вы набрали ps ax | mypager , вы могли бы сделать

     !: 0 u!: * 
     

    Опять же, с mypager "ps ax" , это все еще выполнимо, но, возможно, сложнее .

  3. Также посмотрите на две команды: ps ax | mypager и mypager «ps ax» . Предположим, вы запускаете историю , перечисляя список через час. ISTM, что вам придется взглянуть на mypager "ps ax" немного сложнее , чтобы увидеть, какая команда выполняется.

IV. Сложные команды / цитирование

  1. echo {1..10000} , очевидно, всего лишь пример команды; ps ax не намного лучше. Что, если вы хотите сделать что-то немного немного более реалистичным, например ps ax | grep oracle ? Если вы наберете

     mypager ps ax | grep oracle 
     

    он запустит mypager ps ax и направит вывод через grep oracle . Итак, если результат ps ax составляет 30 строк, mypager вызовет less , {{1} } даже если вывод ps ax | grep oracle - всего 3 строки. Вероятно, есть примеры, которые терпят неудачу в более драматической форме.

    Итак, вы должны сделать то, что я показывал ранее:

     mypager "ps ax | grep oracle" 
     

    Но RET = "$ ($ @)" может с этим не справлюсь. Конечно, есть способы справиться с подобными вещами, но они не приветствуются.

  2. Что делать, если командная строка, вывод которой вы хотите захватить , еще более сложна; например,

     команда  1   " arg  1 " |  команда  2   ' arg  2 ' $ ' arg  3 ' 

    где аргументы содержат беспорядочные комбинации пробелов, вкладка, $ , | , \ , , > , * , ; , и , [, ] , (, ) , `, и, возможно, даже ' и " . Такая команда может быть достаточно сложной для ввода прямо в оболочку. Теперь представьте себе кошмар , связанный с необходимостью процитировать его, чтобы передать его в качестве аргумента mypager .

1
11.07.2018, 03:52
1 ответ

Pulseaudio имеет собственный набор регуляторов громкости, а устройство pulseпредставляет собой преобразователь, который позволяет только приложениям ALSA -использовать Pulseaudio.

Я очень сомневаюсь, что настройка какого-либо микшера на устройстве pulseделает что-то разумное. И я не уверен, какое значение считывания элементов управления микшером вернут, возможно, настройку громкости стока по умолчанию (, но мне нужно прочитать исходный код, чтобы узнать ).

Если вы хотите управлять громкостью приложений Pulseaudio из командной строки (независимо от того, используют ли они Pulseaudio через ALSA или напрямую ), взгляните на pacmd.

0
28.01.2020, 00:32

Теги

Похожие вопросы