2012-03-21 7 views
39

Ho sviluppato uno script sulla mia macchina Linux per parecchio tempo e volevo eseguirlo anche sul mio Mac.Il comando data non segue le specifiche Linux (Mac OS X Lion)

Ho pensato che le funzioni del Mac fossero le stesse di Linux, ma oggi ho capito che era sbagliato. Sapevo che sul Mac esistevano meno funzioni, ma pensavo che le funzioni esistenti, avessero la stessa implementazione.

Questo problema riguarda specificamente il comando date.

Quando eseguo il comando sulla mia macchina Linux con il parametro per fornire un po 'di tempo in nanosecondi, ottengo il risultato corretto, ma quando lo eseguo sul mio Mac, non ha questa opzione.

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

Come faccio a ottenere l'ora corrente in nanosecondi come comando bash su Mac?

Nella peggiore delle ipotesi, creo un piccolo pezzo di codice che chiama una funzione di sistema in C o qualcosa del genere e quindi lo chiamiamo all'interno del mio script.

Qualsiasi aiuto è molto apprezzato!

+0

Il peggiore è sed ;-) – callumacrae

+2

Non mi fiderei di Linux per quanto riguarda la conformità ad alcuni standard Unix. Mac OS X segue Single Unix Specification V3, non Linux. Inoltre una data con una precisione di nanosecondi ottenuta da un comando bash è molto precisa ma non molto accurata. Qual è il tuo bisogno? – mouviciel

+0

Grazie per il vostro contributo ragazzi. Imparerò a conoscere GNU vs. BSD e verificherò le differenze tra sed. @mouviciel, volevo creare un comando personalizzato 'time'. –

risposta

53

Questo perché OSX e Linux utilizzano due diversi set di strumenti. Linux usa la versione GNU del comando date (quindi GNU/Linux). Ricorda che Linux è Linux e OS X è Unix. Sono diversi.

È possibile installare il comando GNU date incluso nel pacchetto "coreutils" da MacPorts. Verrà installato sul sistema come gdate. È possibile utilizzarlo o collegare il binario date con il nuovo binario gdate; la tua scelta.

+0

Grazie per l'informazione Joe! –

+20

Vale la pena notare che coreutils è anche in [Homebrew] (http://mxcl.github.io/homebrew/) che rende l'installazione un gioco da ragazzi.Basta installare Homebrew e poi "brew install coreutils" e hai gdate. – Nick

+2

So che questo è più vecchio di 2 anni, ma grazie! Ho avuto uno snippet di formattazione delle date molto complesso in uno script utilizzato in un progetto di database su larga scala che utilizzava l'eccellente '-d' flag di date. Sono contento di poterlo usare ancora su Mac. – Jangari

7

man date indica che non va oltre un secondo. Vorrei consigliamo di provare un'altra lingua:

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

Non gemere a OS X, gemere a BSD :-P

+17

Interpreto sempre un interprete Python quando ho bisogno di sapere che nanosecondo è giusto adesso. ;-) –

+1

haha, punto giusto - ma riesci a trovare soluzioni migliori? – callumacrae

+0

Grazie per la risposta @Callum Macrae, ma penso che dovrò andare con l'altra risposta perché mi darà risultati più accurati. –

0

Esistono "specifiche Linux" ma non regolano molto il comportamento del comando date. Quello che hai è esattamente l'opposto: Linux (o più specificamente gli strumenti GNU user-space) ha un gran numero di estensioni che non sono compatibili con Unix con qualsiasi definizione ragionevole.

C'è un gran numero di standard che do regolano queste cose. Quello che dovrebbe essere guardando è POSIX che richiede

date [-u] [+format] 

e niente di più da sostenere aderendo implementazioni. (Ci sono altri standard come XPG e SUS che potreste voler considerare, ma per lo meno, dovreste richiedere e aspettarvi POSIX in questi giorni ... finalmente.)

Il documento POSIX contiene un numero di esempi ma non c'è nulla per la conversione che è comunque un problema pratico che molti script si rivolgono a date per. Inoltre, per il tuo problema concreto, non c'è nulla per riportare i tempi con accuratezza inferiore al secondo in POSIX.

In ogni caso, il fatto che * BSD non sia Linux non è molto utile qui; devi solo capire quali sono le differenze e codificare in modo difensivo. Se le tue esigenze sono complesse o insolite, potresti rivolgerti a un linguaggio di scripting come Perl o Python che eseguono questi tipi di operazioni di formattazione della data più o meno fuori dalla scatola in un'installazione standard (sebbene né Perl né Python abbiano un modo rapido ed elegante per fare la conversione fuori dalla scatola, entrambe le soluzioni tendono ad essere un po 'torturate).

In termini pratici, è possibile confrontare lo MacOS date man page e lo Linux one e provare a riconciliare i requisiti.

Per le vostre esigenze pratiche, MacOS date non supporta alcuna stringa di formato con accuratezza al nanosecondo, ma non è possibile ricevere risultati utili su tale scala quando l'esecuzione del comando richiederà un numero significativo di nanosecondi. Mi accontenterei di un'accuratezza di un millisecondo (e anche di quella che verrà scartata dal tempo di esecuzione nelle cifre finali) e moltiplicherò per ottenere il numero in scala di nanosecondi.

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

(Notare le parentesi che racchiudono l'argomento per print() per Python 3.) Si noterà che Python fa segnalare un valore a precisione nanosecondo (le ultime cifre spesso non sono zeri), anche se per il momento si aver eseguito time.time() il valore ovviamente non sarà più corretto.

Per avere un'idea del tasso di errore,

[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 

Il sovraccarico di partire Python e la stampa il valore è destinata probabilmente ad aggiungere un paio di ordini di grandezza di spese generali, realisticamente, ma mi rifugio' t ho tentato di quantificarlo. (L'output da timeit è in secondi.)