2015-01-08 2 views
7

Sto lavorando a una piccola applicazione per suonare campane della scuola su un programma, che può essere aggiornato da un sito web. Tutto funziona alla grande, tranne che lo script programmato come cron job non riprodurrà il suono quando viene eseguito lo script. Ho aggiunto comandi di piping di uscita ed echo allo script per verificare che cron lo stia eseguendo, ma la parte che riproduce il suono non funziona. Lo script funziona come previsto quando viene eseguito manualmente dalla CLI.Perché il mio script cron PHP non suona?

Lo script estrae un tempo e un file audio per ogni periodo della giornata in programma, quindi confronta il tempo associato al file audio con l'ora corrente - se si tratta di un match, lo farà

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

Cron è quindi programmato per eseguire questo script ogni minuto durante la giornata scolastica:

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

Anche in questo caso, se corro manualmente lo script quando c'è suono in programma, l'audio viene riprodotto attraverso gli altoparlanti collegati. Quando avrò un codice di prova che farà eco allo schermo o verrà inviato a un file inserito, cron scaricherà l'output nei file, confermando che sta eseguendo lo script come pianificato. Semplicemente non riprodurrà la parte maledettamente sana della sceneggiatura.

Ho controllato tutti i miei permessi e dato che tutto il resto funziona, sembrano accurati. Posso perfino scrivere un semplice script BASH per far sì che Cron suoni un programma in una programmazione, quindi sembra che il sistema abbia le appartenenze ai gruppi giuste per accedere sia allo script che al file audio. Ho cambiato exec() per shell_exec(), ho provato a utilizzare solo i comandi e i percorsi assoluti ai comandi e il processo cron è pianificato per essere eseguito come root. Non riesco ancora a capire perché questa piccola funzionalità che sfortunatamente è così importante per questo programma non funzionerà.

Qualsiasi consiglio è molto apprezzato.

+0

Questo sembra più simile a una domanda per un sito diverso SE. Per Ubuntu c'è una risposta qui: http://askubuntu.com/questions/530048/ubuntu-14-04-and-playing-songs-from-cron Potrebbe essere utile su altri gusti nix forse. – developerwjk

+1

Prova ad aggiungere questo all'esec: 'exec ('...>/tmp/cronlog 2> & 1')' e controlla il file di log '/ tmp/cronlog' se c'è qualche errore. Se 'aplay' ha bisogno di X devi assicurarti che la root abbia accesso alla sessione X attiva (vedi il comando' xhost'). È possibile che si desideri utilizzare un utente con sessione attiva per il processo cron. – fejese

+0

Questo potrebbe aiutare: http://stackoverflow.com/a/22744360/1163786 - Un consiglio: non eliminare gli errori durante il debug dei problemi di cronjob. Aumentare il livello di registrazione. –

risposta

0

Invece di impostare come cron, utilizzare intervallo php o javascript (asincrono - Ajax) per chiamare il file php previsto. Penso che questo risolva il tuo problema.

Il processo cron in esecuzione nel server, non genererà alcun output sul browser.

Cron Job è utile per inviare notifiche/mail, aggiornare/inserire in db in intervalli particolari.

Per le vostre esigenze, è necessario eseguire lo script tramite browser.

0

Come altri hanno menzionato nei commenti, è necessario salvare i registri e quindi esaminarli per ottenere indizi.

Da ciò che ricordo dalle mie esperienze l'utilizzo di uno script dedicato eseguito da PHP può essere utile. Si dovrebbe alimentare allo script bash il nome del file audio come parametro. Per esempio:

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

Nello script è possibile impostare la directory di lavoro, le variabili di ambiente, ecc

Naturalmente, si deve sfuggire variabili se si vuole evitare gli studenti che ottengono idee malizioso.

Una tecnica su cui sono sempre tornato quando il gioco si fa duro è avere uno script in esecuzione in cron controllato da un file memorizzato in say/tmp/che è possibile scrivere tramite il server Web e PHP .

Quindi, solo ottenere PHP per scrivere i dati di controllo in un file in/tmp (o qualsiasi altra directory scrivibile) e ottenere il vostro script utente bash testato per monitorare regolarmente tramite cron. Potrebbe essere semplice come avere una linea che punta al file audio nel tuo caso.

che è sempre lavorato per me senza sorprese.

1

Probabilmente autorizzazioni per /dev/snd/pcmC0D0p sono il problema. (Questo è il dispositivo per ALSA scheda 0: dispositivo 0:. Riproduzione) Se c'è una sessione di desktop in esecuzione sul server, può avere un demone pulseaudio tenendo il dispositivo aperto.

Impostare le cose per consentire a più utenti di essere in grado di riprodurre il suono allo stesso tempo è un disastro e richiede la configurazione di pulseaudio in una modalità a basse prestazioni che non è a zero copia, quindi non farlo. Assicurati solo che il server possa aprire esclusivamente il dispositivo audio quando necessario.

Per verificare se un dispositivo ALSA suono è aperto o non (indipendentemente dallo stato di pausa o w/e):

$ 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 

Così la prima PCM riproduzione sulla mia prima scheda audio è aperto, ma il 2 ° PCM (l'uscita S/PDIF dell'audio della mia scheda madre) è chiusa. Ulteriori aperture del dispositivo audio funzionano solo perché l'impostazione ALSA predefinita rende il dispositivo "predefinito" un wrapper pulseaudio. hw:0 non riuscirebbe, perché è occupato, e questa scheda audio non ha un mixer hardware.

(fatto divertente: alcune vecchie schede audio, ad esempio alcune schede PCI Soundblaster, supportavano più aperture del dispositivo hardware. Più flussi di dati PCM potevano essere inviati alla scheda, dove sarebbero stati mixati dal suo DSP. m totalmente sbagliato e il driver del kernel stava mixando. < Ma comunque, non avevi bisogno di pulseaudio se ne avevi uno.)

0

Come ho capito, cron | crontab viene eseguito nel proprio ambiente; ad esempio, si veda risposta accettata in:

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

Così, anche se aplay riprodurrà un suono (WAV) file quando viene richiamato come utente normale o come root (su | sudo), non giocare quella file quando viene chiamato da cron - ad esempio, l'esecuzione di uno script bash (.sh) che contiene la sua dichiarazione aplay).

Questo funziona, sul mio sistema Arch Linux.

Ecco il mio cron_notification.sh script:

#!/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 

E, qui è la quota di competenza del mio file /etc/crontab:

# /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 

ho lasciato dei commenti in atto, per i riferimenti e chiarezza.

alert.jpg

notification

È possibile scaricare il file audio PHASER.WAV dal mio sito web, qui:

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