1

So I can run:

arecord -d 9 -f S16_LE -c 1 -r44100 -t wav /home/pi/signal_9s.wav

from terminal and it works as expected. It records for 9 seconds and saves to the signal_9s.wav file. However if I set this up to run from a cron job, I get :

arecord: main:828: audio open error: No such file or directory.

If I specify the hardware option -D hw:2,0 in my cron command, then it works, but the card that my microphone is assigned to seems to change when I run my pi connected to a monitor versus when I run my pi without a monitor, so if the pi can find the microphone without me having to specify that would solve a bunch of problems. Thanks!

2

Revised Answer:

arecord needs an environment variable called XDG_RUNTIME_DIR to locate the resources it needs. By default our cron jobs run in a different environment than (for example) the one in our interactive shell, and the cron environment won't (by default) include the variable XDG_RUNTIME_DIR.

The solution then is to add this environment variable in your crontab. Once cron has this environment variable, it should run it with no complaints. Here's how to do this:

  1. Open your crontab for editing:
$ crontab -e
  1. With your crontab open in the editor, add the following line above the line you use to start arecord:
XDG_RUNTIME_DIR=/run/user/1000 

I've used 1000 as the uid here as that is default for user pi in RPi OS. You can verify this by entering id pi a the command line.

For future reference:
The environment in cron is austere, at least in part, to reduce the risk of potential security issues. Sometimes, we need to know just exactly what the cron environment is... How do we do that? The easiest and best way I've found to do this is to ask cron to tell us! We add the printenv command in our crontab, and redirect it to a file in our home directory:

@reboot /bin/sleep; /usr/bin/printenv > /home/pi/mycronenv.txt 2>&1

This will give you a handy reference file containing your cron environment, updated each time you reboot. You can compare it against the printenv output from your interactive shell the next time your cron job misfires :)

Original Answer:

Try using /usr/bin/arecord instead of arecord in your crontab entry.

cron runs in a different environment than the one you have in your interactive shell. It doesn't know where arecord is - so you must tell it.

I don't know enough about arecord to understand the effect of specifying the "hardware option", but try this first & we'll go from there.


EDIT:

According to this Ubuntu Q&A, there is an environment variable associated with the use of arecord (XDG_RUNTIME_DIR), and it is dependent on the userid.

This answer doesn't explain things extremely well, but there is another answer that seems to do a better job of explanation..

Your difficulty here is due to the fact that cron does not have the same environment as you do from your interactive shell, and it does not have the same environment as you do in your windowing/X environment. And so, the solution must be to provide cron the environment variable that contains your hardware information.

I can't try this on my machine because: a) it is RPi Lite (no desktop/windows), and b) no microphone. Therefore, I will only suggest that you try adding the following line to your crontab file somewhere above the line you invoke arecord:

XDG_RUNTIME_DIR=/run/user/1000

Note: I assume user pi & UID = 1000

Please also note that this was adapted from the Ubuntu example, and while the approach may be good, things may be arranged differently in RPi OS - IOW, you may have to tweak this some :)

8
  • Thanks! I tried using /usr/bin/arecord in the cron entry and the same problem occurs audio open error: No such file or directory. Mar 17 '21 at 15:49
  • @ChaseRoberts: Did you specify the hardware option?
    – Seamus
    Mar 17 '21 at 18:05
  • Yeah, if I specify the hardware option it works (even with /usr/bin/arecord instead of just arecord). The problem is when I don't specify the hardware option. Mar 18 '21 at 23:36
  • @ChaseRoberts: I've not used arecord, so this will be a wag, but: Is it possible that the hardware option is set as part of your environment? You could check this by running printenv from the CLI. Also, setting hardware options sometimes requires sudo privileges - do you or did you use sudo in setting this up? FWIW, the change in environment between cron and the interactive shell (bash likely) is the most likely suspect when someone says, "It works from the command line, but not in cron". I'll wait for yr cmt & we'll try something else if this doesn't pan out.
    – Seamus
    Mar 19 '21 at 3:38
  • 1
    Perfect. I ran printenv, and sure enough XDG_RUNTIME_DIR=/run/user/1000 was there. I added that to the cron, and it works perfectly. Thank you so much for your patience and your time! Mar 20 '21 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.