2015-06-05 4 views
1

Я пытаюсь запустить скрипт Perl, который читает в именах файлов из stdin и вызывает du с помощью системной команды. Когда я запускаю команду du на командной строке, она отлично работает, но когда du вызывается в perl-скрипте с помощью system(), я получаю «Нет такого файла или каталога». Имя файла имеет пробелы и апостроф, которые я избегаю, прежде чем передавать его в perl-скрипт. Сам скрипт perl ОЧЕНЬ прост:«нет такого файла или каталога» с системными вызовами perl

use strict; use warnings; 
my $line1; 
my @tmutil_args; 

while($line1 = <>){ 
    @tmutil_args = ("du", "-sh", $line1); 
    system(@tmutil_args); 
} 

Я также использую сценарий оболочки, чтобы избежать имени файла. Сценарий один строка выглядит следующим образом:

s/[\' ]/\\&/g 

образец файла до и после того, как она проходит через СЭД является:

/Volumes/Mac Mini Backup 4TB/Backups.backupdb/John's Mac Mini/2015-06-04-132645 

/Volumes/Mac\ Mini\ Backup\ 4TB/Backups.backupdb/Pete\'s\ Mac\ Mini/2015-06-04-132645 

Я попытался с и без возможности избежать пробелов и апостроф.

выход:

du: /Volumes/Mac\ Mini\ Backup\ 4TB/Backups.backupdb/Pete\'s\ Mac\ Mini/2015-06-04-132645 
: No such file or directory 

одна важная вещь, я бегу это на Mac OS X 10.95 в окне терминала. Perl v5.16.2

вы можете спросить, что я пытаюсь сделать. Я пытаюсь получить размер отдельных резервных копий Mac TimeMachine.

так может кто-нибудь сказать мне, что мне нужно?

+1

В конце каждого имени файла есть новая строка. Или, скорее, нет. –

+0

'quotemeta' - ваш друг здесь. http://perldoc.perl.org/functions/quotemeta.html – Sobrique

+0

В форме списка 'system' вам не нужно избегать имен файлов. –

ответ

3

Сообщение об ошибке сообщает вам, что вам нужно. Он пытается открыть файл, имя которого заканчивается \n. Попробуйте chomp.

Но действительно вы должны использовать find w/- exec или xargs или перемещаться в perl с помощью File::Find. Это очень хрупкий способ достижения ваших целей.

find /path/to/root/dir -type f -exec du -sh {} \; 
+2

Не 'chop' try' chomp' – Sobrique

+0

Новые линии гарантированы там, и это точно, когда 'chop' подходит. –

+0

С другой стороны, прирост производительности 'chop' над' chomp' здесь совершенно неактуальен, поэтому нет причин избегать «chomp», кроме потери удара в кодовом гольф-поле. –

1

Содержимое $line1 включает перевод строки, которые вы ввели, чтобы закончить строку. Это приведет к несоответствию, если вы пытаетесь найти файл с этим именем, поэтому удалите его с помощью chomp

Это также лучше, чтобы объявить переменные, как конце как это возможно - предпочтительно при их первом месте использования - и не в блоке в верхней части программы

use strict; 
use warnings; 

while (my $filename = <>) { 
    chomp $filename; 
    system('du', '-sh', $filename); 
} 
+0

большое спасибо, john –