Странный “Никакой такой файл” ошибка с “xargs” и “файлом”

В этом сценарии я обычно использую lsof в сочетании с PS для обнаружения, кто держит занятое устройство.

Давайте возьмем пример с палкой usb, которая была смонтирована как/media/disk-1

$> sudo umount /media/disk-1 
[sudo] password for cj: 
umount: /media/disk-1: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))

Таким образом, я затем пытаюсь узнать, кто держит устройство с lsof.

$> lsof | grep disk-1
bash       7822         cj  cwd       DIR       8,33      16384          1 /media/disk-1

И так как столбец 2 является содержанием pid, мы можем получить название того процесса с PS.

$> ps -A | grep 7822
7822 pts/1    00:00:00 bash

Теперь, когда удар прибывает из терминала, который был открыт в dir на устройстве, таким образом, в этой точке я мог или закрыть или уничтожить тот терминал, таким образом, устройство будет свободно снова.


Обновление я не думаю, что ответил на вопрос, но возможно это могло быть полезно для кого-то еще так, что я оставляю его так или иначе.

6
13.11.2013, 06:38
3 ответа

Замена команды $(file --mime-type -b FILE) выполняется оболочкой прежде чем быть переданным xargs, который является, почему Вы не видите то, в чем Вы нуждаетесь. Кавычка $(file --mime-type -b FILE) и передайте его bash -c через xargs

find . -type f | xargs -n 1 -I FILE bash -c  'echo $(file --mime-type -b FILE)'
5
27.01.2020, 20:23
  • 1
    ... настолько делающий названный файл'FILE'продемонстрирует это приятно. –  jthill 13.11.2013, 16:58

Нет никакой потребности использовать xargs здесь. Просто используйте find -exec переключатель.

$ find . -type f -exec file --mime-type -- {} +

Примеры

значение по умолчанию file вывод

$ find 8* -type f -exec file --mime-type -- {} + | tail -5
89999/sample10.txt:               text/plain
89999/sample2.txt:                text/plain
89999/sample4.txt:                text/plain
89999/sample6.txt:                text/plain
89999/sample9.txt:                text/plain

file -b вывод

$ find 8* -type f -exec file --mime-type -b -- {} + | head -5
application/x-empty
text/x-perl
text/plain
text/plain
text/plain

Альтернативы

Это просто к вашему сведению, но существует другая названная команда mimetype который можно также использовать, чтобы сделать то же самое как file --mimetype. Эта команда является частью этого пакета на Fedora, perl-File-MimeInfo, и работы так же:

$ find 8* -type f -exec mimetype -- {} + | tail -5
89999/sample10.txt:               text/plain
89999/sample2.txt:                text/plain
89999/sample4.txt:                text/plain
89999/sample6.txt:                text/plain
89999/sample9.txt:                text/plain

Более тщательно продуманное должностное лицо

Учитывая Вас справился "о выполнении больше, чем просто эхо.." и так как Вы пытаетесь использовать xargs Я собираюсь прийти к заключению, что Вы думаете, что необходимо будет сделать больше тщательно продуманности с xargs.

Но если Вы используете find, это обычно - не лучший способ пойти. Можно вместо этого использовать find, и затем в find -exec переключитесь называют оболочку и делают более сложные вещи в здесь, вместо того, чтобы попытаться подключить коаксиальным кабелем xargs в выполнение этого более сложным способом.

$ find . -type f -exec sh -c '
   cmd1;
   cmd2;
   file --mime-type -b "$@";
   cmd3;
   cmd4;
 ' sh {} \;

Примечание: То, что я переключился от использования + разделитель, который передает несколько аргументов file --mime-type ... кому: \; который передает по одному.

Пример

$ find 8* -type f -exec sh -c '
   echo -n "mime-type: "; 
   file --mime-type -b "$@"
  ' sh {} \; |& tail -10
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/x-shellscript
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
mime-type: text/plain
4
27.01.2020, 20:23
  • 1
    Если Вы не перенесете его, то это подвергнется оболочке globbing. Является ли это тем, что Вы хотите, или не субъективно - я думаю, что Вы на самом деле хотите, find . -name '8*', но трудно сказать. –  Chris Down 13.11.2013, 07:07
  • 2
    @ChrisDown - да в моем демонстрационном каталоге данных я на самом деле хотел 8* 8-). Но это просто b/c моей установки. –  slm♦ 13.11.2013, 07:09

Ваша проблема о расширении оболочки. $ () расширен, прежде чем он будет передан как аргумент. Если Вы хотите рассматривать его как есть, одинарная кавычка он и назвать оболочку для него.

Кроме того, если Вы обрабатываете имена файлов, привыкаете использовать print0 и 0, поскольку пропуск их произведет проблемы для Вас с именами файлов, содержащими пробел.

Пример:

find . -type f -print0 | xargs -0 -n 1 -I FILE bash -c 'echo $(file --mime-type -b FILE)'

В Вашем случае это может быть упрощено до:

find . -type f -print0 | xargs -0 -n 1 file --mime-type -b

Дополнительный комментарий: Вызов программы для всех найденных файлов (быть этим 'xargs-n 1' или find+exec) может быть реальным узким местом производительности. Если у Вас будет каталог с тысячами файлов, то Вы породите тысячи процессов.

3
27.01.2020, 20:23
  • 1
    Существует-P опция установить макс. процессы в xargs. –  manish_s 01.11.2014, 20:16

Теги

Похожие вопросы