![无法创建 udev 规则来运行用于在插头上回送麦克风的脚本](https://linux22.com/image/998501/%E6%97%A0%E6%B3%95%E5%88%9B%E5%BB%BA%20udev%20%E8%A7%84%E5%88%99%E6%9D%A5%E8%BF%90%E8%A1%8C%E7%94%A8%E4%BA%8E%E5%9C%A8%E6%8F%92%E5%A4%B4%E4%B8%8A%E5%9B%9E%E9%80%81%E9%BA%A6%E5%85%8B%E9%A3%8E%E7%9A%84%E8%84%9A%E6%9C%AC.png)
我一直在尝试设置我的 USB 麦克风,以切换到默认值并使用 udev 自动环回。
我当前的规则是:
ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/micunplug"
micplug 脚本是:
#!/bin/bash
echo "setting source mic" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono
echo "loopback mic" >> /home/wanderingconfused/test
pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo
将麦克风设置为默认源并将其环回。
micunplug 脚本是:
#!/bin/bash
echo "turn off loopback" >> /home/wanderingconfused/test
pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
echo "setting source webcam" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono
这会关闭环回并将默认源返回到我的网络摄像头。
这些脚本本身完全按照预期工作。但是,当 udev 执行它们时,所有内容都会回显到测试文件,但 pulseaudio 会忽略这些命令。
我认为这与权限有关,这就是我添加 GROUP 的原因。我尝试了几个组和所有者,并尝试了 MODE=="0660",但此时我不知所措。
编辑 3/3/2017 所以现在我的 /usr/bin/pulse_events_wrapper 是:
#!/bin/bash
# Get UID of user running pulseaudio (uses the first if more than one)
PUID=`ps -C pulseaudio -o ruid= | awk '{print $1}'`
if [ ! -z "$PUID" ]; then
# environment variables to export
export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
export HOME=`getent passwd $PUID | cut -d: -f6`
if [ -x "$HOME/.pulse_events" ]; then
# Pass single command line arg to user script
nohup sudo -u "#$PUID" -E $HOME/.pulse_events $1 >/dev/null 2>&1 &
fi
fi
home/.pulse_events 脚本是
!/bin/bash
case $1 in
micplug)
echo "setting source mic" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono >>/home/wanderingconfused/test 2>&1
echo "loopback mic" >> /home/wanderingconfused/test
pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo$
;;
micunplug)
echo "turn off loopback" >> /home/wanderingconfused/test
pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - ) >>/home/wanderingconfused/test 2>&1
echo "setting source webcam" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono >>/home/wanderingconfused/test 2>&1
;;
esac
它确实有效,但我宁愿不将所有内容转储到文件中。我尝试过删除回声并将所有内容路由为空,但随后它就停止工作了。
当我查看测试文件时,麦克风拔出似乎重复发生:
setting source mic
loopback mic
68
turn off loopback
setting source webcam
turn off loopback
turn off loopback
You have to specify a module index or name
setting source webcam
You have to specify a module index or name
setting source webcam
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
70
Failure: No such entity
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
78
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
80
turn off loopback
turn off loopback
setting source webcam
Failure: No such entity
setting source webcam
setting source mic
loopback mic
82
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
Source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono does not exist.
loopback mic
84
turn off loopback
turn off loopback
setting source webcam
You have to specify a module index or name
setting source webcam
setting source mic
loopback mic
87
turn off loopback
setting source webcam
turn off loopback
You have to specify a module index or name
setting source webcam
另一件奇怪的事情,尽管它说,“源 alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono 不存在。”但它仍然可以工作。
答案1
pulseaudio 服务器通常以普通用户身份运行(至少在我输入此内容的 16.10 上),但是 udev 以 root 身份运行脚本,没有普通用户拥有的正常环境变量。您可能可以在系统范围内运行 pulseaudio(我从未这样做过,但https://community.linuxmint.com/tutorial/view/1137意味着它可以完成,或者您需要修改脚本以以相关用户的身份运行 pacmd。
也许将您的脚本更改为包装器以运行每个用户脚本,例如:
/usr/bin/pulse_event_wrapper:
#!/bin/bash
# Get UID of user running pulseaudio (uses the first if more than one)
PUID=`ps -C pulseaudio -o ruid= | awk '{print $1}'`
if [ ! -z "$PUID" ]; then
# environment variables to export
export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
export HOME=`getent passwd $PUID | cut -d: -f6`
if [ -x "$HOME/.pulse_events" ]; then
# Pass single command line arg to user script
sudo -u "#$PUID" -E "$HOME/.pulse_events $1" >/dev/null 2>&1
fi
fi
然后将脚本放在主目录中的 .pulse_events 中(确保使其可执行,例如 chmod 755 /home/wanderingconfused/.pulse_events )
/主页/wanderingconfused/.pulse_events:
#!/bin/bash
case $1 in
micplug)
echo "setting source mic" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb Logitech_Logitech_USB_Microphone-00.analog-mono
echo "loopback mic" >> /home/wanderingconfused/test
pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo
;;
micunplug)
echo "turn off loopback" >> /home/wanderingconfused/test
pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
echo "setting source webcam" >> /home/wanderingconfused/test
pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono
;;
esac
最后,让 udev 使用您需要的事件参数调用包装器:
ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/pulse_event_wrapper micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/pulse_event_wrapper micunplug"
答案2
我最终最有效的解决方案。
Udev 规则:
ACTION=="add", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a03", GROUP=="audio" RUN+="/usr/bin/pulse_event_wrapper micplug"
ACTION=="remove", ENV{ID_MODEL}=="Logitech_USB_Microphone", RUN+="/usr/bin/pulse_event_wrapper micunplug"
/usr/bin/pulse_events_wrapper
#!/bin/bash
# Get UID of user running pulseaudio (uses the first if more than one)
PUID=`ps -C pulseaudio -o ruid= | awk '{print $1}'`
if [ ! -z "$PUID" ]; then
# environment variables to export
export PULSE_RUNTIME_PATH="/var/run/user/$PUID/pulse"
export HOME=`getent passwd $PUID | cut -d: -f6`
if [ -x "$HOME/.pulse_events" ]; then
# Pass single command line arg to user script
nohup sudo -u "#$PUID" -E $HOME/.pulse_events $1 >/dev/null 2>&1 &
fi
fi
主页/.pulse_events
#!/bin/bash
n=0
case $1 in
micplug)
while ! $(pactl list sources|grep -q 'Logitech USB Microphone Analog Mono')
do let "n += 1"
sleep 1
if [ "$n" -eq 10 ]
then break
fi
done
pacmd set-default-source alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono
pactl load-module module-loopback latency_msec=1 source=alsa_input.usb-Logitech_Logitech_USB_Microphone-00.analog-mono sink=alsa_output.pci-0000_00_14.2.analog-stereo
;;
micunplug)
pactl unload-module $(pactl list short modules | awk '$2 == "module-loopback" { print $1 }' - )
pacmd set-default-source alsa_input.usb-046d_081b_4B042590-02.analog-mono
;;
esac
我添加了一个 while 循环来检查 pulseaudio 源列表中的麦克风,一切正常,无需填满我的测试文件。删除规则仍然触发两次我曾尝试观察 udev 事件以找到仅与 1 个事件匹配的唯一集合 ID,但我尝试的那些违反了规则。虽然该事件只需要运行一次,但运行两次不会造成任何损害,我很高兴它不会运行超过这个次数。所以...现在...我完成了。