El comando de fecha no sigue las especificaciones de Linux (Mac OS X Lion)

He estado desarrollando un script en mi linux box durante bastante tiempo, y quería ejecutarlo en mi Mac también.

Pensé que las funciones en 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 de date .

Cuando ejecuto el comando en mi máquina linux con el parámetro para dar un poco 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 script.

¡Cualquier ayuda es muy apreciada!

Esto se debe a que OSX y Linux usan dos conjuntos diferentes de 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 de date GNU que se incluye en el paquete “coreutils” de MacPorts . Se instalará en su sistema como gdate . Puede usar eso o vincular el binario de date con el nuevo binario gdate ; tu elección.

man date indica que no va más allá de un segundo. Recomendaría probar con otro idioma:

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

No gemir en OS X, gemir en BSD 😛

Existen “especificaciones de Linux” pero no regulan mucho el comportamiento del comando de date . Lo que tienes 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 ninguna definición razonable.

Hay una gran cantidad de estándares que regulan estas cosas. El que deberías mirar es POSIX que requiere

 date [-u] [+format] 

y nada más para ser respaldado por implementaciones adheridas. (Hay otros estándares como XPG y SUS que también debería considerar, pero al menos, debe exigir 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 fechas, que sin embargo es un problema práctico que muchos scripts se vuelven date . Además, para su problema concreto, no hay nada para reportar tiempos con precisión de segundo en POSIX.

De todos modos, decir que * 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 Sin embargo, la conversión de la fecha de la fecha, las soluciones tienden a ser un tanto torturadas.

En términos prácticos, puede comparar la página Man de date MacOS y la de Linux e intentar conciliar sus requisitos.

Para su requerimiento práctico, la date MacOS no admite ninguna cadena de formato con una precisión de nanosegundos, pero tampoco es probable que reciba 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))' } 

(Observe los paréntesis alrededor del argumento para print() para Python 3.) Notará que Python informa un valor con una precisión de nanosegundos (los últimos dígitos a menudo no son ceros), aunque para cuando haya ejecutado time.time() el valor obviamente ya no será correcto.

Para tener una idea de la tasa de error,

 bash@macos-high-sierra$ 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 iniciar Python e imprimir el valor probablemente agregará algunos órdenes de magnitud de sobrecarga, de manera realista, pero no he intentado cuantificar eso. (El resultado de timeit está en segundos).