[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: writing to /dev/stdout fails in cron script



On 22/08/14 22:53, Karl E. Jorgensen wrote:
> Hi
> 
> On Fri, Aug 22, 2014 at 11:23:37AM +0200, Tony van der Hoff wrote:
>> Hi,
>>
>> Running up-to-date Wheezy.
>>
>> I have a script, simplified like this:
>>
>> -----------------------------
>> #!/bin/bash
>> DEBUG=1
>>
>> OUT=/dev/null
>>
>> if [ $DEBUG -ne 0 ]; then
>> 	OUT=/dev/stdout
>> fi
>>
>> echo hello > $OUT
>> -----------------------------
>>
>> This works fine when invoked from the command line, but when called as a
>> cron task, same user, it fails with
>> /home/tony/scripts/test: line 10: /dev/stdout: Permission denied
>>
>> Any suggestions on how to fix this, please?
> 
> Short version: Don't do it. At least not this way.
> 
> I suspect that the crontab entry is your own - or alternatively an
> /etc/cron.d/* file which specifies a non-root user - is that correct?
> 
Absolutely correct -- My user's crontab.

> If so, the error message makes sense - you have to take into account
> how cron works: cron will create an empty temporary file to capture
> the stdout/stderr or whatever it runs (because it will be emailed to
> you).  And stderr/stdout will be redirected to this file *before* it
> drops its privileges.  So this temporary file will be owned by root.
> And the permissions on the file ensure it is only writeable by root
> (and probably only readable by root, as somebody might expect the
> output to be private).
> 
> So when your script starts, its stdout has already been opened for
> it.  Remember that file permissions are only checked at the time the
> file is opened - not subsequently.
> 
OK, understood

<snip experiments>

> In your case, he solution for switching debugging on/off is probably
> changing the way you do things: Instead of writing to /dev/null when
> debugging is off, simply do not perform debugging if it is off!
> (writing to /dev/null is a waste of resources anyway)
> 
> A little shell function like this will do the trick:
> 
> debug()
> {
>   if [ $DEBUG -ne 0 ]; then
>     echo "$@"
>   fi
> }
> 
> so you script can use "debug" the same way it uses echo.
> 
> Hope this helps.
> 
Well, it certainly helps in that I now understand the problem.

Your suggestion is useful in the current context, but unfortunately
isn't the whole answer. I started out saying that my sample script was
simplified; actually it was just sufficient to demonstrate the problem
as it then was.

This whole thing started off by my wanting to suppress the (very
intrusive) output from pushd/popd, for which selective /dev/null would
be suitable. I don't really want my scripts to generate any output,
other than for errors, or debugging. So I tried defining $OUT as above,
and got myself into deep water, and it's time to step back.

I'll use your debug() function and define my own pushd/popd functions
along the same lines.

Thanks for your help, and very lucid explanation.

-- 
Tony van der Hoff  | mailto:tony@vanderhoff.org
Ariège, France     |


Reply to: