Timeout-Befehl unter Mac OS X?


Antworten:


138

Sie können verwenden

brew install coreutils

Und wenn Sie eine Zeitüberschreitung benötigen, verwenden Sie

gtimeout

..stattdessen. Um zu erklären, warum hier ein Ausschnitt aus dem Abschnitt Homebrew Caveats:

Vorsichtsmaßnahmen

Alle Befehle wurden mit dem Präfix 'g' installiert.

Wenn Sie diese Befehle wirklich mit ihren normalen Namen verwenden müssen, können Sie Ihrem PATH aus Ihrem bashrc ein "gnubin" -Verzeichnis hinzufügen, wie:

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

Darüber hinaus können Sie auf ihre Manpages mit normalen Namen zugreifen, wenn Sie das Verzeichnis "gnuman" auch von Ihrem bashrc zu Ihrem MANPATH hinzufügen:

MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"

22
Dann: Alias ​​Timeout = Gtimeout
Nkadwa

1
Oder ln -s /usr/local/bin/gtimeout /usr/local/bin/timeoutum nur den einen Befehl zu aktivieren (die Alias-Lösung funktioniert für die interaktive CLI-Verwendung, jedoch nicht, wenn sie aus Bash-Skripten aufgerufen wird).
John Y

1
Auf meiner Seite habe ich nach der Installation von coerutils eine Zeitüberschreitung als Zeitüberschreitung erhalten: ln -s / usr / local / bin / gtimeout / usr / lokal / bin / timeout ln: / usr / local / bin /
timeout

Update: Ich habe gerade coreutils mit installiert brew install coreutilsund der timeoutBefehl war ohne Präfix verfügbar.
Tdensmore

25

Ein anderer einfacher Ansatz, der ziemlich plattformübergreifend funktioniert (weil er Perl verwendet, das fast überall ist), ist folgender:

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

Von hier aus gefangen: https://gist.github.com/jaytaylor/6527607

Anstatt es in eine Funktion einzufügen, können Sie einfach die folgende Zeile in ein Skript einfügen, und es funktioniert auch:

timeout.sh

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

oder eine Version, die Hilfe / Beispiele eingebaut hat:

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' "$@";

Wie sieht es aus, es direkt zu verwenden, ohne es in eine Funktion zu verpacken?
mwfearnley

Es ist so ziemlich einfach, die Funktion zu entfernen und die Perl-Zeile zu verlassen ... Ich habe oben mehr Details eingefügt!
Brad Parks

Wie sieht es als Einweg-Einzeiler aus? So etwas wie perl -e 'alarm shift; exec "ping google.com"?
mwfearnley

Leider erzeugt dies eine Alarm clockNachricht, wenn der Timer abläuft, und das Beseitigen wird unübersichtlich .
RichVel

1
Es wäre gut, die ualarm-Version hinzuzufügen, wenn Sie mehr Präzision benötigen: function timeout() { perl -e 'use Time::HiRes "ualarm"; ualarm shift; exec @ARGV' "$@"; } (Beachten Sie, dass Perl> = 5.8 gemäß perldoc.perl.org/functions/alarm.html erforderlich ist )
gib

6

Mit diesem Befehl können Sie die Ausführungszeit jedes Programms begrenzen:

ping -t 10 google.com & sleep 5; kill $!

9
Dies ist wahrscheinlich nicht das, was Sie wollen. Das Ergebnis ist, dass der Befehl genau 5 Sekunden ausgeführt wird. Das heißt, wenn Sie möchten, dass es eine maximale Zeit ist, aber nicht auch die
minimale, dann

2

Das Timeout-Paket von Ubuntu / Debian kann auf einem Mac kompiliert werden und funktioniert. Das Paket ist unter http://packages.ubuntu.com/lucid/timeout verfügbar


2
Eine einfachere Möglichkeit ist die Verwendung von Homebrew: brew install coreutils- Verwenden gtimeoutoder setzen Sie dann Ihren Pfad, um den timeoutNamen zu verwenden.
RichVel

1

Du kannst tun ping -t 10 google.com >nul

das> nul wird die Ausgabe los. Anstatt also 64 BYTES VON 123.45.67.8 BLAH BLAH BLAH anzuzeigen, wird nur eine leere neue Zeile angezeigt, bis das Zeitlimit überschritten wird. Das Flag -t kann in eine beliebige Zahl geändert werden.


2
Ping war wirklich eine Probe. Ich möchte ein Programm ausführen, um einige Metriken zu sammeln
sheki
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.