Execute o seguinte script toda quarta-feira:
[ -f /path/to/timestamp ] && \
[ 'date +%s' -lt $(($(cat /path/to/timestamp)+20*86400)) ] || \
{ date +%s > /path/to/timestamp; your_command; }
onde /path/to/timestamp
é um nome de caminho arbitrário (que não existe inicialmente), normalmente em algum lugar no diretório pessoal do usuário (para evitar ataques de links simbólicos, não use um diretório onde outros usuários possam gravar). Este script funciona da seguinte maneira:
- Se esse nome de caminho ainda não existe, então o criamos com a data atual como seu conteúdo e nós executamos o comando. A data é representada pelo número de segundos desde que alguma origem chamou a época.
- Se esse nome de caminho existir (nesse caso, é assumido que ele foi criado por esse script), ele especifica a data em que o comando foi executado pela última vez. Adicionamos 20 dias (20 * 86400 segundos) a essa data e comparamos o resultado com a data atual. Se pelo menos 20 dias se passaram, atualizamos o conteúdo do nome do caminho com a data atual e executamos o comando.
Como este script é executado toda quarta-feira (às 8:00) via cron, o comando será executado a cada 3 semanas (como após 1 ou 2 semanas, 20 dias ainda não passaram).
Observe que essa solução funciona mesmo se a máquina for desligada antes da terceira quarta-feira. Se, por algum motivo, a máquina for desligada na terceira quarta-feira, o comando será executado na próxima quarta-feira em que a máquina estiver ligada (a pergunta é necessária para executar o comando apenas na quarta-feira às 8h).