Прямо сейчас я использую команду ниже, чтобы получить имена томов подключенных дисков в OSX:
$exec = "df -lH | grep \"/Volumes/*\" | tr -s \" \" | sed 's/ /;/g'";
И анализируя вывод, используя этот код:
$lines = explode("\n", $output);
$i = 0;
foreach ($lines as $line) {
$driveinfo = explode(";", $line);
$driveinfo[7] = trim($driveinfo[0]);
if (!empty($driveinfo[0]))
$allremovabledrives[$driveinfo[0]] = $driveinfo;
$i++;
}
Это прекрасно работает, если в метке тома нет пробелов:
[/dev/disk1s1] => Array
(
[0] => /dev/disk1s1
[1] => 32G
[2] => 31G
[3] => 674M
[4] => 98%
[5] => 0
[6] => 0
[7] => /dev/disk1s1
[8] => /Volumes/LUMIX
)
Но если я смонтирую диск с именем тома, в котором есть пробелы, добавляются аварийные сигналы и дополнительные значения массива:
[/dev/disk4] => Array
(
[0] => /dev/disk4
[1] => 4.0T
[2] => 1.2T
[3] => 2.8T
[4] => 29%
[5] => 140741078
[6] => 347553584
[7] => /dev/disk4
[8] => /Volumes/My
[9] => Passport
[10] => Pro
)
Кто-нибудь может помочь мне решить эту проблему? Я не очень разбираюсь в утилитах sed и командной строки …
ОК, имя тома всегда является последним полем, и вы знаете, сколько их полей (9), поэтому я бы просто разделил пробел и запросил столько полей. И не заморачивайся sed
/awk
/grep
/tr
вещи, так как вы уже находитесь в полноценной системе программирования, которая может делать то, что эти команды делают более эффективно в своем собственном пространстве процессов.
Во-первых, вы можете передать список томов, информацию о которых вы хотите получить. df
в качестве аргументов, что означает, что вам не нужно grep
:
$df = shell_exec('df -lH /Volumes/*');
Теперь разделите на новую строку и избавьтесь от заголовков:
$rows = explode("\n", $df);
array_shift($rows);
Начните строить свой результат:
$result = array();
Здесь нам не нужно использовать утилиты оболочки, чтобы сделать возможным explode
что мы уже можем сделать с preg_split
, Регулярное выражение /\s+/
соответствует 1 или более пробельным символам в строке, поэтому мы не получаем дополнительные поля. Предел (9) означает, что он разбивается только на 9 полей независимо от того, сколько еще пробелов — таким образом, пробелы в последнем поле (имя тома) остаются одни.
foreach ($rows as $row) {
$cols = preg_split('/\s+/', $row, 9);
$result[$cols[0]] = $cols;
}
После всего этого, $result
должен выглядеть так, как вы хотите.
Других решений пока нет …