2

Here's a snippet of a bash script I'm writing to log CPU loads:

#!/bin/bash
# ... irrelevant nonsense ...
cmd1="/usr/bin/mpstat -P ALL | egrep '(AM|PM)([[:space:]]+)(0)' | tr -s ' ' | cut -d' ' -f4"
ldsys="$(echo $cmd1 | /bin/sh)"
# ... irrelevant nonsense ...

$ldsys is set properly when the script is executed conventionally from the console. It's golden. Here's the issue: when executed with crontab, $ldsys is empty.

I've been trying millions of things for the last three hours to try to get this thing work... but I can't find anything. Does anyone have any ideas?


Notes:

  • /usr/bin/mpstat can be executed by cron. I tested by adding a bogus task to fire every minute: /usr/bin/mpstat -P ALL >> somefile and checking the output. It works.

  • egrep, tr, and cut all function fine under cron.

  • I'm thinking it really has to do with the eval assignment convention... but I don't know why that would be an issue considering it's a relatively-fundamental construct... After trying Adam's suggestion, I now have no idea what to think...

Edit: stripped out eval usage... still no dice.

brianreavis
  • 11,562
  • 3
  • 43
  • 50
  • See my answer at https://stackoverflow.com/questions/3639415/variables-in-crontab/71788488#71788488 regarding use of variables in crontab – brookbot Apr 07 '22 at 20:25

3 Answers3

1

Your problem is coming from mpstat. When it's run from the command prompt, it outputs the time with AM/PM. It doesn't when it's run by cron. As ennuikiller suggested, it's probably an environment problem. On my system echo $LANG gives "en_US.UTF-8" at the command prompt, but nothing when run in cron. This or some other environment variable is affecting the way mpstat outputs times so when you grep for "(AM|PM)" it doesn't find it.

By the way, why don't you just do:

ldsys=$(/usr/bin/mpstat ... )

without the assignment to "cmd1", the eval, the echo and the piping to sh?

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
0

You are encountering one of the two following issues:

This is perhaps our number one complaint with cron. When you login to Unix, startup scripts setup your environment. You can see your environment with the commands "printenv" or "env". On the other hand, cron sets up only a sparse environment 

Normally the output of any program is sent to STDOUT (standard out) and usually winds up on someone's display screen. For jobs started by cron, STDOUT will be directed to the local mail subsystem, which means any output generated by a cron job will be mailed to the user owning the job

ennuikiller
  • 46,381
  • 14
  • 112
  • 137
  • Excuse my ignorance: any ideas on how to fix it (get the output assigned to the variable)? Thanks for the insight though, I really appreciate it. By the way... I'm *doubting* it's an environment issue, considering that everything works except the `eval` assignment. – brianreavis Nov 11 '09 at 12:42
  • did you check crons mail to see if there are any errors in the output? perhaps your PATH inst whatr you think it is – ennuikiller Nov 11 '09 at 14:00
0

Have you tried eliminating the eval?

Instead of

ldsys=`eval $cmd1`

Try

ldsys=`echo "$cmd1" | /bin/sh`

or

ldsys="$(echo $cmd1 | /bin/sh)"
Adam Liss
  • 47,594
  • 12
  • 108
  • 150