As funções de bash são exportadas pelo ambiente. O comando at
disponibiliza o ambiente, o umask e o diretório atual do processo de chamada para o script, gerando código shell que reproduz o ambiente. O script executado pelo seu trabalho é algo assim:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Em versões mais antigas do bash, as funções eram exportadas como uma variável com o nome da função e um valor começando com ()
e consistindo em código para definir a função, por exemplo,
stupid="() {
date
}"; export stupid
Isso tornou muitos cenários vulneráveis a uma falha de segurança, o bug ShellShock (encontrado por Stéphane Chazelas ), que permitia a qualquer um capaz de injetar o conteúdo de uma variável de ambiente sob qualquer nome para executar código arbitrário em um script bash. As versões do bash onde com uma correção do Shellshock usam uma maneira diferente: elas armazenam a definição da função em uma variável cujo nome contém caracteres que não são encontrados em variáveis de ambiente e que as shells não analisam como atribuições.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Devido a %
, esta não é uma sintaxe sh válida, nem mesmo no bash, portanto, a tarefa at falha, mesmo se tentar usar a função ou não. A versão Debian do , que é usada em muitas distribuições Linux, era changed na versão 3.16 para exportar apenas variáveis que possuam nomes válidos em shell scripts. Portanto, versões mais novas do at não passam funções exportadas pelo shell do Shell, enquanto as mais antigas são erradas.
Mesmo com versões do bash pré-Shellshock, a função exportada só funciona em scripts bash iniciados a partir da tarefa at, não no próprio job. No job em si, mesmo que seja executado por bash, stupid
é apenas outra variável de ambiente; O bash só importa funções quando é iniciado.
Para exportar funções para um trabalho no, independentemente do bash ou na versão, coloque-os em um arquivo e forneça esse arquivo a partir do seu trabalho ou inclua-os diretamente em seu trabalho. Para imprimir todas as funções definidas em um formato que possa ser lido, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM