Eval a falha variável (w / Crontab)
Pergunta
Aqui está um trecho de um script bash Eu estou escrevendo para registrar cargas de CPU:
#!/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
está definido corretamente quando o script é executado convencionalmente a partir do console. É de ouro. Aqui está a questão:. quando executado com crontab, $ldsys
está vazio
Eu tenho tentado milhões de coisas para as últimas três horas para tentar obter a coisa funcionar ... mas não consigo encontrar qualquer . Alguém tem alguma idéia?
Notas:
-
/usr/bin/mpstat
pode ser executada por cron. Eu testei adicionando uma tarefa falso para disparar a cada minuto:/usr/bin/mpstat -P ALL >> somefile
e verificar a saída. Ele funciona. -
egrep
,tr
ecut
todas as funções muito bem sob cron. -
Eu estou pensando que realmente tem a ver com a convenção de atribuição eval ... mas eu não sei por que isso seria um problema considerando que é uma construção relativamente-fundamentais ...Depois tentando sugestão de Adam, agora eu não tenho nenhuma idéia o que pensar ...
Editar:. retirados uso eval
... ainda sem dados
Solução
Seu problema é proveniente de mpstat
. Quando é executado a partir do prompt de comando, ele exibe o tempo com AM / PM. Não faz quando é administrado por cron
. Como ennuikiller sugeriu, é provavelmente um problema de ambiente. No meu echo $LANG
sistema dá "en_US.UTF-8" no prompt de comando, mas nada quando executado em cron
. Esta ou alguma outra variável de ambiente está afetando vezes o caminho mpstat
saídas assim quando você grep
para "(AM | PM)". Ele não encontrá-lo
A propósito, por que você não apenas fazer:
ldsys=$(/usr/bin/mpstat ... )
sem a designação de "cmd1", o eval
, o echo
ea tubulação para sh
?
Outras dicas
Você está encontrando uma das duas questões seguintes:
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
Normalmente a saída de qualquer programa é enviado para STDOUT (saída padrão) e geralmente acaba na tela de alguém. Para os trabalhos iniciados por cron, STDOUT será direcionado para o subsistema de correio local, o que significa que qualquer saída gerada por um trabalho cron será enviado para o usuário possuir o trabalho
Você tentou eliminar a eval
?
Em vez de
ldsys=`eval $cmd1`
Tente
ldsys=`echo "$cmd1" | /bin/sh`
ou
ldsys="$(echo $cmd1 | /bin/sh)"