Comando de tempo limite no Mac OS X?

95

Existe uma alternativa para o comando timeout no Mac OSx. O requisito básico é que eu seja capaz de executar um comando por um determinado período de tempo.

por exemplo:

timeout 10 ping google.com

Este programa executa ping por 10s no Linux.

Sheki
fonte
Veja também unix.stackexchange.com/questions/43340/…
Joshua Goldberg

Respostas:

139

Você pode usar

brew install coreutils

E sempre que precisar de tempo limite, use

gtimeout

..em vez de. Para explicar por que aqui está um snippet da seção de advertências do Homebrew:

Ressalvas

Todos os comandos foram instalados com o prefixo 'g'.

Se você realmente precisa usar esses comandos com seus nomes normais, pode adicionar um diretório "gnubin" ao seu PATH a partir do bashrc como:

PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"

Além disso, você pode acessar suas páginas de manual com nomes normais se adicionar o diretório "gnuman" ao seu MANPATH do bashrc também:

MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
kvz
fonte
22
Então: alias timeout = gtimeout
nkadwa
1
Ou ln -s /usr/local/bin/gtimeout /usr/local/bin/timeoutapenas para habilitar um comando (a solução de alias funciona para uso CLI interativo, mas não quando chamada de scripts bash).
John Y
1
Do meu lado, depois de instalar coerutils, obtive o tempo limite disponível como tempo limite: ln -s / usr / local / bin / gtimeout / usr / local / bin / timeout ln: / usr / local / bin / timeout: Arquivo existe
talsibony
1
Atualização: Acabei de instalar o coreutils usando brew install coreutils, e o timeoutcomando estava disponível sem o prefixo.
tdensmore
25

Outra abordagem simples que funciona praticamente em várias plataformas (porque usa perl que está quase em todos os lugares) é esta:

function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; }

Roubado aqui: https://gist.github.com/jaytaylor/6527607

Em vez de colocá-lo em uma função, você pode simplesmente colocar a seguinte linha em um script, e ele também funcionará:

timeout.sh

perl -e 'alarm shift; exec @ARGV' "$@";

ou uma versão com ajuda / exemplos integrados:

timeout.sh

#!/usr/bin/env bash

function show_help()
{
  IT=$(cat <<EOF

Runs a command, and times out if it doesnt complete in time

Example usage:
 
   # Will fail after 1 second, and shows non zero exit code result
   $ timeout 1 "sleep 2" 2> /dev/null ; echo \$?
   142

   # Will succeed, and return exit code of 0.
   $ timeout 1 sleep 0.5; echo \$?
   0

   $ timeout 1 bash -c 'echo "hi" && sleep 2 && echo "bye"' 2> /dev/null; echo \$?
   hi
   142

   $ timeout 3 bash -c 'echo "hi" && sleep 2 && echo "bye"' 2> /dev/null; echo \$?
   hi
   bye
   0
EOF
)
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

#
# Mac OS-X does not come with the delightfully useful `timeout` program.  Thankfully a rough BASH equivalent can be achieved with only 2 perl statements.
#
# Originally found on SO: http://stackoverflow.com/questions/601543/command-line-command-to-auto-kill-a-command-after-a-certain-amount-of-time
# 
perl -e 'alarm shift; exec @ARGV' "$@";
Brad Parks
fonte
Qual é a aparência de usá-lo diretamente, sem envolvê-lo em uma função?
mwfearnley
é basicamente apenas remover a função e sair da linha perl ... Coloquei mais detalhes acima!
Brad Parks
Como é uma linha de uso único? Algo assim perl -e 'alarm shift; exec "ping google.com"?
mwfearnley
Infelizmente, isso gera uma Alarm clockmensagem quando o cronômetro expira e pode ser complicado eliminar isso .
RichVel de
1
Seria bom adicionar a versão ualarm para quando você precisar de mais precisão: function timeout() { perl -e 'use Time::HiRes "ualarm"; ualarm shift; exec @ARGV' "$@"; } (Observe que requer Perl> = 5,8 de acordo com perldoc.perl.org/functions/alarm.html )
gib
7

Você pode limitar o tempo de execução de qualquer programa usando este comando:

ping -t 10 google.com & sleep 5; kill $!
deadmoto
fonte
9
Provavelmente não é isso que você deseja. O resultado é que o comando será executado exatamente 5 segundos. Ou seja, se você quiser que seja um tempo máximo, mas não também o mínimo, não é isso que você está procurando
gesell
2

O Timeout Package do Ubuntu / Debian pode ser compilado no Mac e funciona. O pacote está disponível em http://packages.ubuntu.com/lucid/timeout

Sheki
fonte
2
Uma maneira mais fácil é usar o Homebrew: brew install coreutils- então use gtimeoutou defina seu PATH para usar o timeoutnome.
RichVel de
1

Você pode fazer ping -t 10 google.com >nul

o> nul se livra da saída. Então, em vez de mostrar 64 BYTES DE 123.45.67.8 BLAH BLAH BLAH, ele apenas mostrará uma nova linha em branco até o tempo esgotar. -t sinalizador pode ser alterado para qualquer número.

redCube
fonte
2
Ping foi realmente uma amostra. Quero executar um programa para coletar algumas métricas
sheki