Seu script não está vendo suas variáveis ​​de ambiente quando executado como um cron job.

Seu script não está vendo suas variáveis ​​de ambiente quando executado como um cron job.

Quando eu chamo um script de um rootcronjob ( ) ele falha com a mensagem 'ipset não encontrado'. Aqui está a linha de script problemática:

for i in $(cat /etc/cn.zone); do ipset -A china $i; done

Algumas linhas antes no script este comando é chamado:

ipset -N china hash:net

Então o ipset em questão foi realmente criado.

Se eu executar este script a partir do diretório inicial do root, ele funcionará perfeitamente.

Alguma ideia do que pode causar o erro?

Responder1

Seu script não está vendo suas variáveis ​​de ambiente quando executado como um cron job.

Eu chamo um script de um rootcronjob ( ) e ele falha com a mensagem 'ipset não encontrado'…

Você está executando este script como um script Bash; qual é o que a maioria dos scripts de shell são hoje em dia?

Nesse caso, altere a primeira linha do seu script de

#!/bin/bash

Para isso:

#!/bin/bash -l

Adicionar -ldiz ao Bash para executar como se tivesse sido invocado como um shell de login. E se o script Bash for executado por meio do shell de login nesse cron job, todas as variáveis ​​de ambiente - e outros itens - que normalmente são definidos por meio do shell de login estarão disponíveis para esse script Bash, permitindo assim ipseta execução conforme esperado.


Outro truque que você pode fazer é usar whichuma variável Bash como esta; você claramente está usando isso para $(cat /etc/cn.zone)que o mecanismo seja semelhante:

$(which ipset)

E no seu script mude sua linha para esta:

for i in $(cat /etc/cn.zone); do $(which ipset) -A china $i; done

O que isso fará é - usando which- fornecer ao seu script o caminho completo para ipset(algo como /sbin/ipset) em qualquer sistema em que você esteja executando. E então a configuração dela como uma variável analisada $()permitirá que o próprio script a execute.

Mas como você usa ipsetem outro lugar no seu script, eu recomendaria - se você usar esse whichmétodo - que você refatorasse seu script para definir ipsetuma variável como esta perto do topo do seu script:

ipset_bin=$(which ipset);

E então chame seus comandos assim:

$ipset_bin -N china hash:net

E isto:

for i in $(cat /etc/cn.zone); do $ipset_bin -A china $i; done

Responder2

Seu shell sabe onde encontrar executáveis, ipsetprocurando em seu PATH, que é definido pelo seu ambiente, mas cronnão compartilha o mesmo ambiente.

Adicionar isso no topo do crontab(ou do seu script) deve informar onde encontrar os comandos exatamente como você espera:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

informação relacionada