Domanda

Ho avuto un giro di ricerca, e dal mio punto di vista utilizzando apici inversi è l'unico modo in cui posso risolvere questo problema. Sto cercando di chiamare il comando mdls da Perl per ogni file in una directory per trovare della scorsa volta accede. Il problema che sto avendo è che nei nomi dei file che ho da find Ho spazi escape che bash, ovviamente, non piace. C'è un modo semplice per sfuggire tutto lo spazio bianco nei miei nomi di file prima di passarli a mdls. Ti prego perdonami se questa è una domanda ovvia. Sono abbastanza nuovo per Perl.

my $top_dir = '/Volumes/hydrogen/FLAC';

sub wanted { # Learn about sub routines 
    if ($File::Find::name) { 
         my $curr_file_path = $File::Find::name. "\n";
        `mdls $curr_file_path`;
         print $_;
    }
}

find(\&wanted, $top_dir);
È stato utile?

Soluzione

Se sei sicuro i nomi dei file non contengono a capo (o CR o LF), quindi praticamente tutte le shell Unix accettare backslash citando, e Perl ha la quotemeta funzione per applicarlo.

my $curr_file_path = quotemeta($File::Find::name);
my $time = `mdls $curr_file_path`;

Purtroppo, questo non funziona per i nomi dei file con a capo, perché le maniglie di shell un backslash seguito da un ritorno a capo eliminando sia caratteri invece che solo la barra rovesciata. Quindi, per essere davvero sicuro, l'uso String :: shellquote :

use String::ShellQuote;
...
my $curr_file_path = shell_quote($File::Find::name);
my $time = `mdls $curr_file_path`;

che dovrebbe funzionare su nomi di file che contengono nulla, tranne un carattere NUL, che davvero non dovrebbe usare nei nomi dei file.

Entrambe queste soluzioni sono solo gusci in stile Unix. Se siete su Windows, corretta guscio citando è molto più complicato.

Altri suggerimenti

Se si vogliono semplicemente "tempo di accesso ultima" in termini di dell'OS ora dell'ultimo accesso, mdls è lo strumento sbagliato. Utilizzare stat di perl. Se si desidera ora dell'ultimo accesso in termini di Mac applicazione registrata (ad esempio, una canzone di Quicktime o iTunes) allora mdls è potenzialmente lo strumento giusto. (Si potrebbe anche usare osascript per interrogare l'applicazione Mac direttamente ...)

I backtick sono per catturare il ritorno del testo. Dal momento che si sta utilizzando mdls, assumo l'acquisizione e l'analisi del testo è ancora a venire.

Quindi ci sono diversi metodi:

  1. Utilizza il modulo elenco di sistema e la citazione non è necessario ( se tu non si preoccupano il testo di ritorno);

  2. String :: shellquote per sfuggire il nome del file prima di inviarlo a sh;

  3. Crea la stringa e racchiudono tra virgolette singole prima di inviare a inviare alla shell. Questo è più difficile di quanto sembri perché i file con i nomi di singoli apici sconfigge le vostre citazioni! Ad esempio, sam's song.mp4 è un nome di file legale, ma se vi circondano con virgolette singole si ottiene 'sam's song.mp4' che non è quello che volevi dire ...

  4. Usa open per aprire un tubo per l'uscita del processo figlio in questo modo: open my $fh, '-|', "mdls", "$curr_file" or die "$!";

Esempio di stringa :: shellquote:

use strict; use warnings;
use String::ShellQuote;
use File::Find;

my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';

sub wanted { 
    if ($File::Find::name) { 
         my $curr_file = "$File::Find::name";
         my $rtr;
         return if -d;
         my $exec="mdls ".shell_quote($curr_file);
         $rtr=`$exec`;  
         print "$rtr\n\n";
    }
}

find(\&wanted, $top_dir);

Esempio di tubo:

use strict; use warnings;
use String::ShellQuote;
use File::Find;

my $top_dir = '/Users/andrew/music/iTunes/iTunes Music/Music';

sub wanted { 
    if ($File::Find::name) { 
         my $curr_file = "$File::Find::name";
         my $rtr;
         return if -d;
         open my $fh, '-|', "mdls", "$curr_file" or die "$!";
         { local $/; $rtr=<$fh>; }  
         close $fh or die "$!";
         print "$rtr\n\n";
    }
}

find(\&wanted, $top_dir);

Se si desidera solo per trovare l'ultimo tempo di accesso, c'è qualche strano motivo Mac non si utilizza stat? Quando sarebbe peggio di kMDItemLastUsedDate?

 my $last_access = ( stat($file) )[8];

Sembra kMDItemLastUsedDate Non è sempre aggiornato per l'ultima volta di accesso. Se si lavora con un file attraverso il terminale (ad esempio cat, more), kMDItemLastUsedDate non cambia, ma il valore che ritorna dal stat è giusto. touch sembra fare la cosa giusta in entrambi i casi.

Sembra che tu abbia bisogno stat per la vera risposta, ma mdls se siete alla ricerca per l'accesso attraverso le applicazioni.

È possibile ignorare il guscio esprimendo il comando come un elenco, in combinazione con capture() da IPC :: System :: Simple :

use IPC::System::Simple qw(capture);

my $output = capture('mdls', $curr_file_path);

Quota il nome della variabile all'interno delle backticks:

`mdls "$curr_file_path"`;
`mdls '$curr_file_path'`;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top