Кажется, что причина для моей проблемы была nfs-kernel-server
экспортировал каталог. nfs-kernel-server
вероятно, идет позади нормальных открытых файлов и таким образом не перечислен lsof
и fuser
.
Когда я остановился nfs-kernel-server
Я мог umount
каталог.
Я сделал страницу с примерами всех решений до сих пор здесь: http://oletange.blogspot.com/2012/04/umount-device-is-busy-why.html
Различие находится, в каких данных целевая программа принимает.
Если Вы просто используете канал, он получает данные по STDIN (стандартный входной поток) как необработанная груда данных, что он может отсортировать одну строку за один раз. Однако некоторые программы не принимают свои команды по стандарту в, они ожидают, что это будет разъяснено в аргументах команде. Например, touch
берет имя файла в качестве параметра на командной строке как так: touch file1.txt
.
Если у Вас есть программа, которой выходные имена файлов по стандарту и хотят использовать их в качестве аргументов touch
, необходимо использовать xargs
который считывает потоковые данные STDIN и преобразовывает каждую строку, в космос разделил аргументы команде.
Эти две вещи эквивалентны:
# touch file1.txt
# echo file1.txt | xargs touch
Не использовать xargs
если Вы не знаете точно, что это делает и почему это необходимо. Довольно часто имеет место, что существует лучший способ сделать задание, чем использование xargs
вызвать преобразование. Процесс преобразования также чреват потенциальными ловушками как выход и расширение слова и т.д.
Уже подробно остановиться на ответах если, xargs
может сделать одну прохладную вещь, которая становится все больше важной в сегодняшней среде многоядерных и распределенных вычислений: это может быть параллельным заданиям процесса.
Например:
$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8
закодирует *.wav => *.flac, с помощью трех процессов сразу (-P 3
).
xargs особенно полезен, когда Вы имеете список filepaths на stdin и хотите сделать что-то с ними. Например:
$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
Давайте исследуем это шаг за шагом:
$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....
Другими словами, наш вход является списком путей, к которым мы хотим сделать что-то.
Для обнаружения, что xargs делает с этими путями должен добавить хороший прием echo
перед Вашей командой, как так:
$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....
-n 1
аргумент заставит xargs превратить каждую строку в собственную команду. sed -i "s/color/colour/g"
команда заменит все случаи color
с colour
для указанного файла.
Обратите внимание, что это только работает, если у Вас нет пробелов в Ваших путях. Если Вы делаете, необходимо использовать завершенные пути пустого указателя, как введено для xargs путем передачи -0
флаг. Использование в качестве примера было бы:
$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"
Который делает то же как, что мы описали выше, но также и работы, если один из путей имеет пространство в нем.
Это работает с любой командой, которая производит имена файлов, как произведено такой как find
или locate
. Если Вы, действительно оказывается, используете его в репозитории мерзавца с большим количеством файлов, хотя, могло бы быть более эффективно использовать его с git grep -l
вместо git ls-files
, как так:
$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"
git grep -l "color" "*.tex"
команда даст список "*.tex" файлов, содержащих фразу "цвет".
Ваш первый аргумент иллюстрирует различие вполне хорошо.
\ls | grep Cases | less
позволяет Вам просмотреть список имен файлов, произведенных ls
и grep
. Не имеет значения, что они, оказывается, имена файлов, они - просто некоторый текст.
\ls | grep Cases | xargs less
позволяет Вам просмотреть файлы, имена которых производятся первой частью команды. xargs
берет список имен файлов, как введено и команды на ее командной строке, и выполняет команду с именами файлов на ее командной строке.
При рассматривании использование xargs
, имейте в виду, что это ожидает вход, отформатированный странным способом: разграниченный пробелом, с \
, '
и "
используемый для заключения в кавычки (необычным способом, потому что \
не специальные внутренние кавычки). Только используйте xargs
если Вы Ваши имена файлов не содержите пробел или \'"
.
xargs
имеет -0, --null
опция обойти проблему пробелов (очень вероятно, что я узнал, что от Вас :), таким образом, я предполагаю, что Вы обращаетесь к без опций xarg
звоните, но я озадачен Вашей ссылкой на кавычки. У Вас есть ссылка или пример относительно этого?.. (PS. | xargs less
удобный "прием" +1..спасибо..
– Peter.O
01.12.2011, 22:59
В Вашем примере Вы не должны использовать xargs
вообще с тех пор find
сделает точно и безопасно что Вы хотите сделать.
Точно, что Вы хотите использовать find
:
find -maxdepth 1 -name '*Cases*' -exec touch {} +
В этом примере -maxdepth 1
средства только ищут в текущем каталоге, не убывайте ни в какие подкаталоги; по умолчанию находка посмотрит во всех подкаталогах (который часто является, что Вы хотите), если Вы ограничение это с maxdepth. {}
название файла, которым заменят в его месте и +
один из двух маркеров конца команды, другого существа ;
. Различие между ними - это ;
должностное лицо средств команда на каждом файле по одному, тогда как +
должностное лицо средств команда на всех файлах сразу. Обратите внимание, однако, что Ваша оболочка, вероятно, попытается интерпретировать ;
с самостоятельно, таким образом, необходимо будет выйти из него также \;
или ';'
. Да, find
имеет много небольших раздражений как это, но его питание больше, чем восполняет его.
Оба find
и xargs
хитры для изучения сначала. Помочь Вам учиться xargs
попытайтесь использовать -p
или --interactive
опция, которая покажет Вам команду, она собирается выполнить и предложить Вам, действительно ли Вы хотите выполнить ее.
Так же с find
можно использовать -ok
вместо -exec
предлагать Вам, хотите ли Вы выполнить команду.
Существуют времена, тем не менее, когда find
не сможет сделать все, что Вы хотите, и это то, где xargs
входит. -exec
команда только примет один экземпляр {}
появление, поэтому если Вы получили бы ошибку с find -type f -exec cp {} {}.bak \;
таким образом, Вы могли вместо этого сделать это как так: find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
Можно узнать больше о Командах выполнения в руководстве Findutils GNU.
Кроме того, я упомянул это find
безопасно делает то, что Вы хотите, потому что, когда Вы имеете дело с файлами, Вы собираетесь встретиться с пробелами и другими символами, которые вызовут проблемы с xargs
если Вы не используете -0
или --null
опция наряду с чем-то, что генерирует входные параметры, завершенные нулевым символом вместо пробела.
'
или "
может быть проблематичным, тогда как find
обработает те случаи без проблемы.
– aculich
04.12.2016, 20:33
xargs
(наряду с find
, sort
, du
, uniq
, perl
и немногие другие), принимает, что переключатель командной строки говорит, что "STDIN имеет список файлов, разделенных NUL (0x00) байт". Это помогает обработать имена файлов с пробелами и другими забавными символами в них. Имена файлов не содержат NULs.
xargs
и$(...)
), xargs намного более безопасен, чем замена команды. И я не могу вспомнить никогда случайную встречу с законным именем файла с новой строкой в нем. Разве выход и проблемы ловушек расширения слова с заменой команды не, не xargs? – camh 20.11.2011, 00:31xargs -0
), который полезен в сочетании сfind -print0
. интересный – Ken Bloom 20.11.2011, 03:22xargs
назовите программу через оболочку с пространством разделенным args, или делает это, на самом деле создают список аргументов внутренне (например, для использования сexecv
/execp
)? – detly 20.11.2011, 11:55-d \n
, хотя BSD xargs (OSX и др.), кажется, не поддерживает эту опцию. – fluffy 21.11.2011, 02:20