我使用的是 Linux Mint 18.3 Cinnamon 64 位(版本 3.6.6),我无法从通过 cron 运行的任何程序中获取任何音频。其中包括命令行音频文件播放器、TTS 应用程序(如 espeak 或 festival)等。cron 似乎不起作用。
我使用提醒器来安排锻炼计划和当天的锻炼类型……但自从我从旧的、现在已经完全报废的 Mac Mini 换到 Linux Mint 后,这些就不再起作用了(它们可以通过普通的 xterm 命令行工作)。我从不在 crontab 中使用相对路径,所以不是这个原因。
我尝试过将标准错误导向标准输出并将该输出附加到日志文件来获取错误消息……没有任何效果。只是一个空的日志文件。
我将 crontab 文件中的命令放入脚本中,并在 crontab 中用(完全限定的)路径/文件名替换它们。然后我通过脚本打开同一个日志文件。再次打开,但没有添加任何内容,仍然没有声音。
有人见过这个问题吗?还有什么其他方法可以调试或修复它吗?
答案1
我发现这在 Linux Mint 论坛上找到与您的 Mint 版本完全相同的版本18.3
。不确定这到底是什么根本原因,但无论如何,试一试吧。
0. 查找正确的配置PavuControl
如果一切看起来都不错,那么就继续。
1. 安装最新的内核版本。重启并重试声音。
使用 UpdateManager 或此命令在终端上。
apt install linux-image-4.4.0-53-generic linux-image-extra-4.4.0-53-generic linux-headers-4.4.0-53-generic linux-headers-4.4.0-53
或者有任何疑问,请按照此操作社区教程
2. 检查音频、驱动程序和声音:
运行此命令并查看输出。注意是否有遗漏。
pactl set-sink-mute 0 0 ; pactl list sinks ; lspci -v | grep -A7 -i "audio" ; lsmod
它看起来应该是这样的:
Audio: Card-1 NVIDIA GK107 HDMI Audio Controller
driver: snd_hda_intel bus-ID: 01:00.1
Card-2 Advanced Micro Devices [AMD/ATI] SBx00 Azalia (Intel HDA)
driver: snd_hda_intel bus-ID: 00:14.2
Sound: Advanced Linux Sound Architecture v: k4.4.0-116-generic
如果您看到Advanced Linux Sound Architecture
,安装alsamixergui
可能会有帮助。
3. AlsaMixerGUI:安装 - 运行 - 重启 - 测试 - 声音
安装
alsamixer
sudo apt-get install alsamixergui
运行
alsamixer
按下F6并选择其中一个声卡,然后测试声音是否正常。
有时强制重新加载 alsa 可能会有帮助。为此,打开终端并运行:
sudo alsa force-reload
完成需要几秒钟。重新启动计算机并查看是否有声音。
4.重新安装Alsa
并PulseAudio
重启
删除所有alsa-base
和pulseaudio
包。
sudo apt-get remove --purge alsa-base pulseaudio
更新后全新安装以获取最新版本:
sudo apt-get update
sudo apt-get install alsa-base pulseaudio
强制重新加载Alsa
sudo alsa force-reload
重启。
5. 仍然没有声音 :(
好吧,至少你尝试过了。这样更好。请随意添加更多细节或任何其他对你有用的解决方案。
答案2
好吧,我不知道为什么它不起作用,但我有一个解决方案。
我发现通过 procmail 向特定电子邮件发件人发出声音公告的声音也损坏了。
所以我创建了两个非常简单的 [Tcl][1] 脚本。第一个脚本是 run,而不是 espeak 等,它只是将文本写入文件~/.alerts
。第二个脚本位于后台,是一种守护进程,等待该文件存在,当文件存在时,它会读取并读出文件中的每一行(通常只有一行),然后删除该文件。两个脚本都使用文件锁定来避免任何冲突。
检查的 Tcl 脚本~/.alerts
是从 xterm 运行的,因此它没有任何错误会干扰 cron、procmail 以及谁知道的其他程序。它只是正常工作。
这就是我的解决方案。喜欢它,爱它,恨它……它对我有用。
第一个脚本是 addalert。
这是脚本---它只是等待文件是否被锁定(最多 20 秒,然后假设它被卡住)并从 procmail 写入消息:
#!/usr/local/bin/tclsh8.5
set lockfile /home/jim/.alertlock
proc checklock {} {
global lockfile
if {![file exists $lockfile]} { return }
set counter 20
while {[file exists $lockfile]} {
incr counter -1
if {$counter <= 0} {
file delete -force $lockfile
} ;# stuck lockfile
after 333 ;
after 333 ;
after 333 ;
}
file delete -force $lockfile
}
# wait if file is locked, then lock file while adding alert
checklock
set lock [open $lockfile w] ; puts $lock "" ; close $lock
set f [open /home/jim/.alerts a]
puts $f [lindex $argv 0]
close $f
file delete -force $lockfile
我可以通过将 checklock 过程移到其自己的文件中来缩短这两个脚本,但对于像这样的小东西,这样做不值得(对我来说……我只是像上面一样使用剪切/粘贴来进行这样的快速破解)。下一个脚本称为 doalerts,它执行实际工作(它是从 xterm 或终端(如果您使用该命令行)启动的)。
#!/usr/local/bin/wish8.4
set home /home/jim
set say /home/jim/bin/speak
set alertsfile $home/.alerts
set lockfile $home/.alertlock
cd $home
proc checklock {} {
global lockfile
if {![file exists $lockfile]} { return }
set counter 20
while {[file exists $lockfile]} {
incr counter -1
if {$counter <= 0} {
file delete -force $lockfile
} ;# stuck lockfile
after 333 ;
after 333 ;
after 333 ;
}
file delete -force $lockfile
}
proc handle_alerts {} {
global say alertsfile lockfile
set lock [open $lockfile w] ; puts $lock "" ; close $lock
set f [open $alertsfile r]
set alertlist [split [read $f] \n]
close $f
foreach alert $alertlist { exec $say $alert }
file delete $alertsfile
file delete $lockfile
}
while {1} {
after 333 ;
after 333 ;
after 333 ;
if {[file exists $alertsfile] && ![file exists $lockfile]} {
handle_alerts
}
}
简而言之,它会等待(同样,最多 20 秒)锁定文件被删除,如果文件存在,则打开文件、读取文件(将其分成几行,因为每个警报都在自己的行上),关闭文件,然后使用 TTS 程序(espeak)读取警报。然后它会删除锁定文件 (~/.alertlock) 和警报文件 (~/.alerts)。
答案3
您可能需要在 crontab 临时 shell 中初始化声音才能获取声音。
因此最好将根脚本放在 crontab 中,然后在脚本中初始化音频以获取声音。