Supondo que você esteja usando o at
de Thomas Koenig em um sistema glibc (Linux) (agora mantido por Jose Calhariz ), é possível, mas não documentado claramente, de at(1)
:
If the file /var/run/utmp is not available or corrupted, or if the user is not logged on at the time at is invoked, the mail is sent to the userid found in the environment variable LOGNAME. If that is undefined or empty, the current userid is assumed.
A maneira como at
funciona é construir um arquivo de trabalho que atd
usa, cujas três primeiras linhas são:
#!/bin/sh
# atrun uid=100 gid=100
# mail youruser 1
em que uid=100
, gid=100
e youruser
são determinados programaticamente quando o trabalho está sendo criado. A lógica para determinar o nome de usuário é:
- ligue para
getlogin()
- se essa for a chamada NULL
getenv("LOGNAME")
- verifique se o nome existe chamando
getpwnam()
- se essa for a chamada NULL
getpwuid(real_uid)
- se NULL jogar todos os brinquedos fora do carrinho
Então, como podemos convencer getlogin()
a retornar NULL para usar a variável LOGNAME? Uma maneira é arranjar stdin para não ser um terminal (é por isso que eu considero glibc, getlogin()
se comporta de maneira diferente nos sistemas).
Para fazer isso em bash
:
LOGNAME=backup at 19:52 -m <<< uptime
echo uptime | LOGNAME=backup at 19:52 -m
O ponto é usar o redirecionamento para apresentar o (s) comando (s) no stdin para que at
seja executado. ( at
também executa uma reabertura de stdin se você usar sua opção -f
, embora seja tarde demais para ser útil aqui.) Em vez disso, você pode salvar seu comando em um arquivo ou com bash to salvar a criação de um arquivo:
LOGNAME=backup at 19:52 -m -f <( echo uptime ) 0<&-
( 0<&-
fecha stdin, < /dev/null
também funciona)
Se o seu terminal (ou screen
ou tmux
) desconsiderar utmp
(por configuração ou com permissões ou problemas de ajuda), você pode definir apenas LOGNAME
e usar at
como normal, pois getlogin()
falhará. Você pode dizer se este é o caso encontrando seu terminal usando tty
e então verificando w
para ver se você está logado corretamente no tty, ou tente perl -E 'say getlogin()||"not-in-utmp";'
.
(Apenas para esclarecer, LOGNAME só pode ser um nome de usuário local, se você precisar de um email para ir a outro lugar, precisará usar aliases
/ .forward
/ procmail
etc.)