Como posso chamar vários comandos como argumentos para uma função?

1

Eu quero escrever uma função "para sempre" que eu possa executar vários comandos até que eu a mate manualmente com Ctrl-C. Basicamente, a partir da linha de comando do zsh, sei que posso fazer isso, e isso funciona bem:

$ while {} { ls ; sleep 1 }

que repetirá as chamadas ls e sleep 1 , para sempre.

Eu não consigo descobrir uma sintaxe para transformar algo assim em uma função. Algo como:

forever() { while {} { "${@}" } }

que eu quero então chamar com algo como:

$ forever ( ls ; sleep 1 )

Provavelmente parece bobo quando while {} {<commands>} e forever {<commands>} não são muito diferentes. Mas o que eu realmente quero como objetivo final é uma função de "dormir para sempre", onde eu possa dizer algo como

$ forever-sleep 5 ls -l
$ forever-sleep 5 ( ls -l a ; ls -l b )

e ele vai dormir $1 segundos depois de executar o (s) comando (s) que eu dou para sempre (até que eu o mate manualmente com Ctrl-C).

(Eu experimentei muitas combinações e aninhamentos de () , (()) , {} , [] , [[]] , "" , '' e outros, e eu simplesmente consigo) t descobrir como obter a função e a linha de comando para não ter erros de sintaxe, analisar erros, etc.)

Então,

  • Existe algo parecido com essa idéia de "para sempre"?
  • Isso é possível em uma função? (Eu preferiria uma função que eu possa colocar no meu .zshrc em vez de ter um shell script executável separado).
por snapshoe 15.07.2013 / 06:14

1 resposta

1

Você estava quase lá:

forever-sleep() {
   if [[ ! $1 -gt 0 ]]; then
     print "Usage $0 [time in sec] command -parameter"
     return 2
   fi
   local time=$1
   shift 1
   while true; do
      eval "$@"
      print -- "### finished: $(date) ###############################################"
      sleep $time
   done
}

A sintaxe é então forever-sleep [time in sec] command -parameters , como

$ forever-sleep 2 date +%s
1373873888
1373873890
1373873892
1373873894
...

Algumas observações:

  • $1 -gt 0 implementa uma verificação rudimentar, se o primeiro parâmetro for numericamente, avaliando $1 > 0 . Um tempo de espera negativo não parece sensato.
  • usei while true; do ... done , mas sua sintaxe while {} {...} também funciona.
  • shift 1 é usado para descartar o primeiro argumento para a função (que é salvo em $time , para que posteriormente a variável "$@" possa ser usada por conveniência.
  • eval "$@" , em contraste com um mero "$@" , torna possível fazer algumas coisas mais avançadas, como

    forever-sleep 2 'foo=$(date); echo $foo'
    

    Por favor, observe as aspas simples no último comando!

  • A chamada de impressão fornece um separador visual - goste ou não ;)
por 15.07.2013 / 09:43

Tags