2012-03-21 16 views
39

He estado desarrollando un script en mi linux box desde hace bastante tiempo, y quería ejecutarlo en mi Mac también.El comando de fecha no sigue las especificaciones de Linux (Mac OS X Lion)

Pensé que las funciones en la Mac eran las mismas que las funciones en Linux, pero hoy me di cuenta de que estaba mal. Sabía que existían menos funciones en la Mac, pero pensé que las funciones que sí existían tenían la misma implementación.

Este problema es específicamente con respecto al comando date.

Cuando ejecuto el comando en mi máquina linux con el parámetro para proporcionar algo de tiempo en nanosegundos, obtengo el resultado correcto, pero cuando lo ejecuto en mi mac, no tiene esa opción.

Linux-Machine> date +%N 
55555555555 #Current time in nanoseconds 
Mac-Machine> date +%N 
N 

¿Cómo hago para obtener la hora actual en nanosegundos como un comando bash en la Mac?

El peor caso es que creo un pequeño fragmento de código que llama a una función del sistema en C o algo así y luego lo llamo dentro de mi secuencia de comandos.

¡Cualquier ayuda es muy apreciada!

+0

La peor es sed ;-) – callumacrae

+2

No confiaría en Linux con respecto al cumplimiento de algún estándar de Unix. Mac OS X sigue Single Unix Specification V3, no Linux. Además, una fecha con una precisión de nanosegundos obtenida de un comando bash es muy precisa, pero no tan precisa. ¿Cuál es tu necesidad? – mouviciel

+0

Gracias por su entrada chicos. Aprenderé sobre GNU vs. BSD, y veré las diferencias entre sed. @mouviciel, quería crear un comando 'time' personalizado. –

Respuesta

53

Esto se debe a OSX y Linux utilizan dos conjuntos diferentes de las herramientas. Linux usa la versión GNU del comando date (por lo tanto, GNU/Linux). Recuerde que Linux es Linux y OS X es Unix. Ellos son diferentes.

Puede instalar el comando GNU date que se incluye en el paquete "coreutils" del MacPorts. Se instalará en su sistema como gdate. Puede usar eso o vincular el binario date con el nuevo binario gdate; tu elección.

+0

Gracias por la información Joe! –

+20

Vale la pena señalar que coreutils está en [Homebrew] (http://mxcl.github.io/homebrew/), lo que hace que la instalación sea muy fácil.Simplemente instale Homebrew y luego 'brew install coreutils' y obtendrá gdate. – Nick

+2

Sé que esto tiene más de 2 años, pero ¡gracias! Tenía un fragmento de formato de fecha muy complejo en un script utilizado en un proyecto de base de datos a gran escala que utilizaba el excelente indicador '-d' de' date'. Me alegro de poder seguir usándolo en Mac. – Jangari

7

man date indica que no va más allá de un segundo. Recomiendo probar otro idioma:

$ python -c'import time; print repr(time.time())' 
1332334298.898616 

No gemir en OS X, gimen en BSD :-P

+17

Siempre hago girar un intérprete de Python cuando necesito saber qué nanosegundo es _hora_ ahora. ;-) –

+1

jaja, punto justo, pero ¿se te ocurre alguna solución mejor? – callumacrae

+0

Gracias por la respuesta @Callum Macrae, pero creo que tendré que ir con la otra respuesta porque me dará resultados más precisos. –

0

Existen "especificaciones de Linux" pero no regulan el comportamiento del comando date mucho. Lo que tiene es realmente lo opuesto: Linux (o más específicamente las herramientas de espacio de usuario de GNU) tiene una gran cantidad de extensiones que no son compatibles con Unix por cualquier definición razonable.

Hay una gran cantidad de estándares que hacen regulan estas cosas. El que usted debe mirar es POSIX cuales requiere

date [-u] [+format] 

y nada más para estar soportado mediante la adhesión implementaciones. (Hay otros estándares como XPG y SUS que también debería considerar, pero al menos, debería requerir y esperar POSIX en estos días ... finalmente.)

El documento POSIX contiene una serie de ejemplos, pero no hay nada para la conversión de fecha que es, sin embargo, un problema práctico que muchas secuencias de comandos pasan a date para. Además, para su problema concreto, no hay nada para reportar tiempos con precisión de segundo en POSIX.

De todos modos, pintar eso * BSD no es Linux no es realmente útil aquí; solo tienes que entender cuáles son las diferencias y codificar a la defensiva. Si sus requisitos son complejos o inusuales, tal vez recurra a un lenguaje de scripting como Perl o Python que realizan estos tipos de operaciones de formateo de fechas más o menos de fábrica en una instalación estándar (aunque ni Perl ni Python tienen una manera rápida y elegante de fecha conversión ya fuera, las soluciones tienden a ser un tanto torturadas).

En términos prácticos, puede comparar el MacOS date man page y el Linux one y tratar de conciliar sus requisitos.

Para su necesidad práctica, MacOS date no admite ninguna cadena de formato con precisión de nanosegundos, pero tampoco es probable que obtenga resultados útiles en esa escala cuando la ejecución del comando demorará un número significativo de nanosegundos. Me conformaría con la precisión del nivel de milisegundos (e incluso eso será descartado por el tiempo de ejecución en los dígitos finales) y multiplicar para obtener el número en escala de nanosegundos.

nanoseconds() { 
     python -c 'import time; print(int(time.time()*1000*1000*1000))' 
} 

(Note los paréntesis alrededor del argumento para print() para Python 3.) Usted se dará cuenta de que Python hace reportar un valor con una precisión de nanosegundos (las últimas cifras no son a menudo ceros), aunque por el momento ha ejecutado time.time() el valor obviamente ya no será correcto.

Para tener una idea de la tasa de error,

[email protected]$ python3 
Python 3.5.1 (default, Dec 26 2015, 18:08:53) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import time 
>>> import timeit 
>>> def nanoseconds(): 
... return int(time.time()*1000*1000*1000) 
... 
>>> timeit.timeit(nanoseconds, number=10000) 
0.0066173350023746025 
>>> timeit.timeit('int(time.time()*1000*1000*1000)', number=10000) 
0.00557799199668807 

La sobrecarga de partir Python e imprimir el valor es probablemente va a añadir unas órdenes de magnitud de los gastos generales, de manera realista, pero no he T intentó cuantificar eso. (La salida de timeit está en segundos.)