¿Comando de tiempo de espera en Mac OS X?

90

¿Existe una alternativa para el comando de tiempo de espera en Mac OSx? El requisito básico es que puedo ejecutar un comando durante un período de tiempo específico.

p.ej:

timeout 10 ping google.com

Este programa ejecuta ping durante 10 segundos en Linux.

sheki
fuente
Ver también unix.stackexchange.com/questions/43340/…
Joshua Goldberg

Respuestas:

134

Puedes usar

brew install coreutils

Y luego, cuando necesite tiempo de espera, use

gtimeout

..en lugar. Para explicar por qué, aquí hay un fragmento de la sección Advertencias de Homebrew:

Advertencias

Todos los comandos se han instalado con el prefijo 'g'.

Si realmente necesita usar estos comandos con sus nombres normales, puede agregar un directorio "gnubin" a su PATH desde su bashrc como:

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

Además, puede acceder a sus páginas de manual con nombres normales si agrega el directorio "gnuman" a su MANPATH desde su bashrc también:

MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
kvz
fuente
21
Entonces: alias timeout = gtimeout
nkadwa
1
O ln -s /usr/local/bin/gtimeout /usr/local/bin/timeoutsimplemente para habilitar un comando (la solución de alias funciona para el uso de CLI interactivo, pero no cuando se llama desde scripts bash).
John Y
1
Por mi parte, después de instalar coerutils, obtuve un tiempo de espera disponible como tiempo de espera: ln -s / usr / local / bin / gtimeout / usr / local / bin / timeout ln: / usr / local / bin / timeout: el archivo existe
talsibony
Actualización: acabo de instalar coreutils usando brew install coreutilsy el timeoutcomando estaba disponible sin el prefijo.
tdensmore
24

Otro enfoque simple que funciona prácticamente en varias plataformas (porque usa Perl, que está en casi todas partes) es este:

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

Enganchado desde aquí: https://gist.github.com/jaytaylor/6527607

En lugar de ponerlo en una función, puede simplemente poner la siguiente línea en un script y también funcionará:

timeout.sh

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

o una versión que ha incorporado ayuda / ejemplos:

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
fuente
¿Cómo se ve usarlo directamente, sin envolverlo en una función?
mwfearnley
es prácticamente eliminar la función y dejar la línea de perl ... ¡Puse más detalles arriba!
Brad Parks
¿Cómo se ve como un delineador de un solo uso? Algo como perl -e 'alarm shift; exec "ping google.com"?
mwfearnley
Desafortunadamente, esto genera un Alarm clockmensaje cuando el temporizador expira y eliminarlo se vuelve complicado .
RichVel
1
Sería bueno agregar la versión ualarm para cuando necesite más precisión: function timeout() { perl -e 'use Time::HiRes "ualarm"; ualarm shift; exec @ARGV' "$@"; } (Tenga en cuenta que requiere Perl> = 5.8 de acuerdo con perldoc.perl.org/functions/alarm.html )
gib
6

Puede limitar el tiempo de ejecución de cualquier programa usando este comando:

ping -t 10 google.com & sleep 5; kill $!
deadmoto
fuente
9
Probablemente esto no sea lo que quieres. El resultado es que el comando se ejecutará exactamente 5 segundos. Es decir, si usted quiere que sea un tiempo máximo pero no también el min Esto no es lo que busca
Gesell
2

El paquete Timeout de Ubuntu / Debian se puede compilar en Mac y funciona. El paquete está disponible en http://packages.ubuntu.com/lucid/timeout

sheki
fuente
2
Una forma más fácil es usar Homebrew: brew install coreutils- luego use gtimeouto configure su PATH para usar el timeoutnombre.
RichVel
1

Tu puedes hacer ping -t 10 google.com >nul

el> nul se deshace de la salida. Entonces, en lugar de mostrar 64 BYTES DE 123.45.67.8 BLAH BLAH BLAH, solo mostrará una nueva línea en blanco hasta que se agote el tiempo. -t bandera se puede cambiar a cualquier número.

redCube
fuente
2
Ping fue realmente una muestra. Quiero ejecutar un programa para recopilar algunas métricas
sheki