Quando eu chamo um script de um root
cronjob ( ) 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
root
cronjob ( ) 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 -l
diz 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 ipset
a execução conforme esperado.
Outro truque que você pode fazer é usar which
uma 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 ipset
em outro lugar no seu script, eu recomendaria - se você usar esse which
método - que você refatorasse seu script para definir ipset
uma 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, ipset
procurando em seu PATH
, que é definido pelo seu ambiente, mas cron
nã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