bash equivalente deste uso do comando tcsh “sched”?

2

No tcsh, o comando sched interno faz com que um comando seja executado pelo shell atual em um horário especificado.

Eu tenho o seguinte arquivo $HOME/.sched (esta é uma versão simplificada dele):

setenv today 'date +%F'
sched +00:01 sched 00:00 source $HOME/.sched

Eu então source $HOME/.sched no meu $HOME/.cshrc .

Isso define a variável de ambiente $today como, por exemplo, "2012-06-25" e atualiza automaticamente para a data atual todas as noites à meia-noite. O trabalho automaticamente reprograma-se sempre que é executado.

Observe que o comando date é chamado apenas uma vez por dia e somente quando é necessário.

Existe uma maneira de fazer isso no bash? Observe que o comando at não funcionará; ele invoca um comando externamente e não pode afetar o ambiente atual do shell.

(Eu sei que posso digitar $(date +%F) em vez de $today , mas como eu uso isso interativamente, a digitação extra é um fardo significativo.)

O tcsh também possui vários aliases especiais que são executados automaticamente em determinadas circunstâncias:

The beepcmd, cwdcmd, periodic, precmd, postcmd, and jobcmd Special aliases can be set, respectively, to execute commands when the shell wants to ring the bell, when the working directory changes, every tperiod minutes, before each prompt, before each command gets executed, after each command gets executed, and when a job is started or is brought into the foreground.

O bash tem algo assim?

    
por Keith Thompson 25.06.2012 / 23:45

6 respostas

4

Você já tentou $PROMPT_COMMAND ? É comumente usado para definir o título do xterm para mostrar o CWD, por exemplo. É executado quando o prompt é mostrado. Pode ser possível definir sua variável com isso. A primeira desvantagem seria que seu comando será executado toda vez que você pressionar enter no shell. O segundo seria que, se não estiver ativo em seu terminal por muito tempo e o dia passar, ele não será configurado automaticamente. Ele será definido após a próxima entrada no terminal.

# export PROMPT_COMMAND="export today=\'date\'"
# echo $today
Tue Jun 26 01:07:19 EEST 2012
# echo $today
Tue Jun 26 01:07:21 EEST 2012
# echo $today
Tue Jun 26 01:07:22 EEST 2012
    
por 25.06.2012 / 23:53
3

Se você estiver disposto a negociar duas backquotes por um dólar:

alias today='date +%F'
echo 'today'

Se você quiser a data em uma variável, então atualizando em PROMPT_COMMAND é a única maneira que eu posso pensar. Você pode evitar bifurcar um processo em cada prompt usando a variável incorporada SECONDS .

update_today () {
  if ((SECONDS/86400 > __last_today_update)); then
    ((__last_today_update = SECONDS/86400))
    today=$(date +%F)
  fi
}
PROMPT_COMMAND="update_today; $PROMPT_COMMAND"

Outra abordagem é inserir seu texto por meio de uma ligação de chave.

rl_insert () {
  READLINE_LINE=${READLINE_LINE:0:$READLINE_POINT}$1${READLINE_LINE:$READLINE_POINT}
  ((READLINE_POINT+=${#1}))
}
bind -x '"\C-xt":rl_insert "$(date +%F)"'
    
por 26.06.2012 / 02:47
0

Parece que você está procurando at :

~$ at now + 1 minute
warning: commands will be executed using /bin/sh
at> echo "test" | wall
at> 
job 2 at Mon Jun 25 17:51:00 2012

Broadcast Message from user@host                                              
        (somewhere) at 17:51 ...                                               

test                                                                           

Apesar de tudo, reli a sua pergunta e você está procurando por algo que se auto-programar. Isso seria muito fácil de fazer com at chamando um script de shell que faz o que ele precisa fazer e, em seguida, configura um novo trabalho at . No entanto, at é executado em sua própria sub-rotina; não como o shell de onde você invoca.

    
por 26.06.2012 / 02:52
0

Não parece que o bash tenha um recurso equivalente, pelo menos não com todas as qualidades que você descreve. Se você está procurando um "melhor dos dois mundos", zsh tem sched de recursos.

Eu sei que isso pode ser tão inútil quanto as outras respostas.

    
por 26.06.2012 / 07:50
0

Isso pode dar uma ideia para uma solução:

$ trap 'today=$(date)' 10
$ echo $today
$ sleep 8
$ kill -10 $$
$ echo $today

Agora você pode usar em para enviar a si mesmo ($$) um sinal na virada do dia.

    
por 28.06.2012 / 09:46
0

Eu criei uma solução que funciona sem disparar um processo extra em cada prompt. Assim como a resposta 0xAF , ele usa $PROMPT_COMMAND . É um pouco confuso, mas parece funcionar.

Existem três etapas:

Primeiro, criei um script chamado update-dot-today . Eu coloquei em $HOME/bin .

Aqui está o script:

#!/bin/bash

dir=$HOME/.today
mkdir -p $dir
file_count=$(ls $dir | wc -l)
today=$(date +%F)

if [ $file_count -eq 1 ] ; then
    if [ ! -e $dir/$today ] ; then
        mv $dir/* $dir/$today
    fi
else
    mv $dir $dir-$$
    mkdir -p $dir
    touch $dir/$today
    rm -rf $dir-$$
fi

Quando isso é executado, garante que o arquivo $HOME/.today/YYYY-MM-DD exista e que nada mais exista em $HOME/.today . Depois que o arquivo é criado, o script renomeia o arquivo existente conforme necessário, evitando quaisquer condições de corrida.

Em segundo lugar, adicionei duas entradas ao meu crontab:

@reboot         $HOME/bin/update-dot-today
0 0 * * *       $HOME/bin/update-dot-today

Isso garante que o arquivo seja criado na inicialização e atualizado todas as noites à meia-noite, horário local.

Em terceiro lugar, adicionei o seguinte ao meu $HOME/.bashrc :

today=$(date +%F)
if [ -d $HOME/.today ] ; then
    PROMPT_COMMAND='if [ ! -f "$HOME/.today/$today" ] ; then today=$(ls $HOME/.today) ; fi'
fi

Isso verifica o arquivo $HOME/.today/YYYY-MM-DD apropriado - mas se ele já existir e seu nome corresponder ao valor atual de $today , o único custo será uma verificação de existência de arquivo.

Se preferir, o arquivo YYYY-MM-DD pode ser colocado em algum lugar diferente de /tmp/today , talvez sob seu diretório pessoal. (Na verdade, isso pode ser mais seguro, no caso de algo limpar /tmp entre as reinicializações, ou no caso de outro usuário no sistema usar a mesma abordagem).

O único inconveniente (além do fato de ser bastante complicado) é que o valor de $today é definido somente depois que um prompt de shell é impresso. Mas isso é apenas uma questão de lembrar de digitar um extra Enter pelo menos uma vez depois da meia-noite.

    
por 11.06.2014 / 02:13