2015-01-08 15 views
7

Ich arbeite an einer kleinen Anwendung, um Schulglocken nach einem Zeitplan zu läuten, der von einer Website aktualisiert werden kann. Alles funktioniert gut, außer dass das Skript, das als Cron-Job geplant ist, den Sound nicht wiedergeben wird, wenn das Skript ausgeführt wird. Ich habe dem Skript Output-Piping- und Echo-Befehle hinzugefügt, um zu überprüfen, ob Cron es ausführt, aber der Teil, der den Sound spielt, funktioniert nicht. Das Skript funktioniert wie erwartet, wenn es manuell über CLI ausgeführt wird.Warum spielt mein PHP-Cron-Skript keinen Ton?

Das Skript eine Zeit extrahiert und eine Sounddatei für jede Periode des Tages auf dem Programm, vergleicht dann die an die Sounddatei zugeordnet Zeit mit der aktuellen Zeit - wenn es ein Spiel, es wird

exec("/usr/bin/aplay /var/www/site/".$soundfile); 

Cron wird dann geplant dieses Skript jede Minute während des Schultages laufen:

* 8-16 * 1-6,9-12 1-5 root /usr/bin/php -f /var/www/site/scripts/playsound.php > /dev/null 

Noch einmal, wenn ich manuell das Skript ausführen, wenn es Ton geplant ist, wird der Ton spielt durch die angeschlossenen Lautsprecher. Wenn ich Testcode habe, der auf dem Bildschirm erscheint oder in eine Datei ausgegeben wird, wird Cron die Ausgabe in die Dateien ausgeben und bestätigen, dass das Skript wie geplant ausgeführt wird. Es wird einfach nicht den Sound-Teil des Skripts wiedergeben.

Ich habe alle meine Berechtigungen überprüft und da alles andere funktioniert, scheinen sie genau zu sein. Ich kann sogar ein einfaches BASH-Skript schreiben, um Cron dazu zu bringen, einen Sound nach einem Zeitplan abzuspielen. Daher scheint das System die richtigen Gruppenmitgliedschaften zu haben, um sowohl auf das Skript als auch auf die Sounddatei zugreifen zu können. Ich habe exec() für shell_exec() ausgewechselt, habe versucht, nur die Befehle sowie die absoluten Pfade zu den Befehlen zu verwenden, und der Cron-Auftrag soll als root ausgeführt werden. Ich kann immer noch nicht herausfinden, warum dieses kleine Feature, das leider so kritisch für dieses Programm ist, nicht funktioniert.

Jeder Rat wird sehr geschätzt.

+0

Dies scheint eher wie eine Frage für eine andere SE-Website. Für Ubuntu gibt es hier eine Antwort: http://askubuntu.com/questions/530048/ubuntu-14-04-and-play-songs-from-cron Könnte auf anderen Nix-Aromen vielleicht hilfreich sein. – developerwjk

+1

Versuchen Sie, dies zur exec hinzuzufügen: 'exec ('...>/tmp/cronlog 2> & 1')' und überprüfen Sie die '/ tmp/cronlog' Log-Datei, wenn es einen Fehler gibt. Wenn 'aplay' X benötigt, müssen Sie sicherstellen, dass root Zugriff auf die aktive X-Sitzung hat (siehe' xhost' Befehl). Möglicherweise möchten Sie einen Benutzer mit einer aktiven Sitzung für den Cron-Job verwenden. – fejese

+0

Das könnte helfen: http://StackOverflow.com/a/22744360/1163786 - Ein Tipp: Unterdrücken Sie keine Fehler beim Debuggen von Cronjob-Problemen. Protokollierungsstufe erhöhen –

Antwort

0

stattdessen als cron Setzung verwenden php Intervall oder JavaScript (asynchronous - Ajax) die beabsichtigte php Datei aufrufen. Ich denke, das wird Ihr Problem lösen.

Der Cron-Job, der im Server ausgeführt wird, wird keine Ausgabe an Ihren Browser werfen.

Cron Job ist gut, um Benachrichtigungen/E-Mails senden, update/einfügen in db in bestimmten Abständen.

Für Ihre Anforderungen müssen Sie das Skript über den Browser ausführen.

0

Wie andere in den Kommentaren erwähnt haben, müssen Sie die Protokolle wirklich speichern und dann nach Hinweisen untersuchen.

Von dem, was ich aus meinen Erfahrungen mit einem dedizierten Skript erinnern, die von PHP ausgeführt wird, kann von Vorteil sein. Sie würden dem Bash-Skript den Namen der Sounddatei als Parameter übergeben. Zum Beispiel:

exec("/path/to/script.sh $SOUNDFILEPATH"); 

Im Skript können Sie Setup Arbeitsverzeichnis, Umgebungsvariablen usw.

Natürlich müssen Sie Variablen entkommen, wenn Sie die Studenten immer schelmisch Ideen vermeiden wollen.

Eine Technik, auf die ich immer zurückgegriffen habe, wenn es schwierig wird, ist ein unter cron laufendes Skript, das von einer in say/tmp/gespeicherten Datei gesteuert wird, auf die man über den Webserver und PHP schreiben kann .

So einfach PHP zu schreiben Steuerdaten in eine Datei in/tmp (oder einem anderen beschreibbaren Verzeichnis) und erhalten Sie Ihre getestete Benutzer Bash-Skript, um es regelmäßig über Cron zu überwachen. Es könnte so einfach sein wie eine Zeile, die in Ihrem Fall auf die Sounddatei zeigt.

Das hat immer für mich ohne Überraschungen funktioniert.

1

Wahrscheinlich sind die Berechtigungen auf /dev/snd/pcmC0D0p das Problem. (Das ist das Gerät für ALSA Card 0: Gerät 0: Wiedergabe.) Wenn auf dem Server eine Desktop-Sitzung ausgeführt wird, verfügt es möglicherweise über einen pulseaudio-Daemon, der das Gerät geöffnet hält.

Die Einrichtung von mehreren Benutzern, um gleichzeitig Sound abspielen zu können, ist ein Chaos und erfordert die Konfiguration von Pulseaudio in einem Low-Performance-Modus, der nicht zero-copy ist, also tu das nicht. Stellen Sie nur sicher, dass der Server das Audiogerät bei Bedarf exklusiv öffnen kann.

Um ein ALSA-Sound-Gerät ist offen oder nicht (unabhängig von Pausenzustand oder w/e) ob:

$ cat /proc/asound/card0/pcm0p/sub0/hw_params 
access: MMAP_INTERLEAVED 
format: S16_LE 
subformat: STD 
channels: 2 
rate: 44100 (44100/1) 
period_size: 8192 
buffer_size: 16384 

$ cat /proc/asound/card0/pcm1p/sub0/hw_params 
closed 

So ist die erste PCM-Wiedergabe auf meiner ersten Soundkarte ist offen, aber die zweite PCM (Der S/PDIF-Ausgang meines Motherboard-Audio) ist geschlossen. Weitere öffnungen des Sound-Gerätes funktionieren nur, weil das ALSA-Standard-Setup das "Standard" -Gerät zu einem Pulseaudio-Wrapper macht. hw:0 würde fehlschlagen, weil es beschäftigt ist, und diese Soundkarte hat keinen Hardware-Mixer.

(Fun Tatsache: einige alte Soundkarten, zB einige PCI Soundblaster Karten, unterstützt mehrere öffnet der Hardware-Gerät. Mehrere Ströme von PCM-Daten könnten DMAed auf die Karte, wo sie durch seine DSP gemischt werden würde. m total falsch und der Kernel-Treiber mischte>. < Aber wie auch immer, Sie brauchten Pulseaudio nicht, wenn Sie einen hatten.)

0

Wie ich es verstehe, cron | crontab läuft in seiner eigenen Umgebung; siehe zB akzeptierte Antwort:

https://serverfault.com/questions/337631/crontab-execution-doesnt-have-the-same-environment-variables-as-executing-user

So, obwohl aplay einen Ton spielen (WAV-Datei), wenn sie als normaler Benutzer oder als root aufgerufen (su | sudo), wird es nicht spielen, dass Datei, wenn es von cron aufgerufen wird - z. B. Ausführen eines Bash (.sh) -Skripts, das Ihre aplay-Anweisung enthält.

Dies funktioniert, auf meinem Arch Linux-System.

Hier ist mein cron_notification.sh Skript:

#!/usr/bin/bash 

# /mnt/Vancouver/Programming/scripts/cron_notification.sh 

# For use with crontab [ sudo gedit /etc/crontab ] 
# cron (Arch Linux: cronie) requires full paths: 
# /usr/bin/aplay 
# /usr/bin/notify-send 

for i in 1 2 3 4 5 
    do 
    #aplay alarm.mp3 ## << aplay cannot play MP3 files; use WAV 
    # ---------------------------------------- 
    # NEEDED TO RUN 'aplay' FROM crontab: 
    # https://unix.stackexchange.com/questions/231941/cant-run-aplay-as-root 
    # https://www.reddit.com/r/linuxquestions/comments/37vcbo/playing_audio_from_a_cronjob/ 
    # PulseAudio needs XDG_RUNTIME_DIR, so: 

    XDG_RUNTIME_DIR=/run/user/`id -u` /usr/bin/aplay /mnt/Vancouver/Programming/scripts/PHASER.WAV 
    # ---------------------------------------- 
    sleep 0.25 
done 

# ---------------------------------------------------------------------------- 
# "Critical" alerts persist until clicked (i.e., do not appear, then fade after ~20"): 
# notify-send -u critical 'Hello Victoria!' 'Countdown has ended!' --icon=dialog-information 

/usr/bin/notify-send -u critical 'Hello Victoria!' "It's 3 pm!" -i /mnt/Vancouver/Programming/scripts/alert.jpg 

Und hier ist der relevante Teil meiner /etc/crontab Datei:

# /etc/crontab 

# system-wide crontab 
# edit: sudo {your favorite text editor: gedit; geany; ...} /etc/crontab 
# https://crontab.guru  ## online crontab values checker, planner 

# ===================================================================== 
# SHELL 
# ===================================================================== 

# cron (crontab) requires full paths: 
SHELL=/usr/bin/sh 
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 

# ===================================================================== 
# ARCH LINUX-RELATED [Arch Linux x86_64] 
# ===================================================================== 

# cron | https://wiki.archlinux.org/index.php/Cron 
# Will install, use "cronie" cron (crontab): 
# Install cronie: sudo pacman -Syu cronie 
# Enable cron: sudo systemctl enable --now cronie.service 
#  Start cron: sudo systemctl start cronie.service 
# Restart cron: sudo systemctl restart cronie.service 

# ===================================================================== 
# APLAY NOTIFICATION (3:00pm M-F) 
# ===================================================================== 

# Two issues when running 
# /mnt/Vancouver/Programming/scripts/cron_notification.sh 
# from cron: 

# ---------------------------------------- 
# 1. "notify-send": 

# https://bbs.archlinux.org/viewtopic.php?id=216912 
# notify-send also needs access to your DBUS_SESSION_BUS_ADDRESS. Assuming that your UID is 1000: 

DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" 

# More here: https://wiki.archlinux.org/index.php/Desktop_notifications#Usage_in_programming 

# ---------------------------------------- 
# 2. "aplay": 

# TO RUN 'aplay' FROM crontab: 
# https://www.reddit.com/r/linuxquestions/comments/37vcbo/playing_audio_from_a_cronjob/ 
# PulseAudio needs XDG_RUNTIME_DIR, so: 

# XDG_RUNTIME_DIR=/run/user/`id -u` /usr/bin/aplay /mnt/Vancouver/Programming/scripts/PHASER.WAV 

# Line above added to "/mnt/Vancouver/Programming/scripts/cron_notification.sh" script. 

# ---------------------------------------- 

# m h dom mon dow user nice command 

# "At 15:00 on every day-of-week from Monday through Friday” 
# [https://crontab.guru/#0_15_*_*_1-5]: 
0 15 * * 1-5 victoria nice -n 19 /usr/bin/bash /mnt/Vancouver/Programming/scripts/cron_notification.sh 

# NOTE -- running as user ("victoria"), not "root". 

# Test - every minute: 
#* * * * 1-5 victoria nice -n 19 /usr/bin/bash /mnt/Vancouver/Programming/scripts/cron_notification.sh 

ich die Kommentare an seinem Platz belassen, nach Referenzen und Klarheit.

alert.jpg

notification

können Sie die PHASER.WAV Tondatei von meiner Website herunterladen, hier:

http://persagen.com/files/PHASER.WAV

Verwandte Themen