Como especificar mais facilmente tarefas para lote, usando a ferramenta de prefixo de comando?

1

A ferramenta batch que vem com o daemon atd é bastante útil em princípio, executando comandos apenas quando a utilização do sistema cai abaixo de um certo nível (por padrão, 1.5). No entanto, usá-lo (e também at ) é muito ruim para os padrões modernos: você precisa alimentar um script que pode ser executado por /bin/sh ou digitar comandos interativamente em um prompt básico sem conclusão, codificação por cores, etc.

O que seria realmente bom é uma ferramenta de prefixo de comando, mais como nice , que pode ser colocada na frente de qualquer comando para adicioná-la à fila de lote (e um utilitário semelhante para at seria útil, embora esse não é o ponto principal da minha pergunta). Por exemplo, pode funcionar assim:

my-batchifying-command python some_longrunning_computational_script.py

Existe tal coisa? Se não, como poderia ser criado? Eu uso zsh para meu shell principal, mas uma resposta bash seria igualmente boa e poderia ter uma aplicabilidade mais ampla.

    
por Andrew Ferrier 17.02.2013 / 17:24

1 resposta

1

Com zsh para comandos simples:

my-batch() {print -r -- ${(qq)@} | batch}

my-batch python some_longrunning_computational_script.sh

faria isso.

Se precisar de coisas mais complexas, como loops ou redirecionamentos, você pode fazer:

my-batch eval 'for i in ...; done'

my-batch eval 'echo test > /some/file'

Mas lembre-se de usar sh , não zsh sintaxe.

Se você quiser evitar o eval , use este truque:

alias my-batch=':||'
preexec()
  if [[ $1 = my-batch\ * ]]; then
    print -r -- "${1#my-batch }" | batch
  fi

Novamente, certifique-se de usar a sintaxe sh .

Tenha em atenção que pode ser apenas um um comando (na verdade, um pipeline). Se você precisar de mais de um, use chaves:

my-batch { ls > /tmp/a; date > /tmp/b; }

A ideia acima é que o comando my-batch não faz nada, nem sequer avalia os argumentos do comando porque, por exemplo, my-batch echo $(date) expande para :|| echo $(date) e é preexec que é executado cada vez que uma linha de comando é aceito que faz o trabalho em vez disso.

Para preexec , $1 é a linha de comando completa intocada. Nós apenas verificamos se começa com "my-batch " , tira isso e enviamos o resto para batch .

Isso explica por que my-batch tem que estar no começo da linha. cmd && my-batch ... não funcionará por exemplo, e você não pode fazer coisas como my-batch foo || bar , porque ele realmente será interpretado como :|| foo || bar .

    
por 17.02.2013 / 21:55

Tags