Это не имеет значения потому что оба 4>&1
и 4<&1
сделайте то же самое: dup2(1, 4)
который является системным вызовом для дублирования fd на другого. Дублированный fd автоматически наследовал направление ввода-вывода исходного fd. (то же для 4>&-
по сравнению с 4<&-
который обе твердости к close(4)
, и 4>&1-
который является dup2(1, 4)
сопровождаемый close(1)
).
Однако 4<&1
синтаксис сбивает с толку, если по некоторым причинам fd 1 не был явно открыт для чтения (который будет еще более сбивать с толку), таким образом, в моем уме должен будет избежаться.
Дублированный fd
совместно использует то же открытое описание файла, что означает, что они совместно используют то же смещение в файле (для тех типов файлов, где это имеет смысл), и те же связанные флаги (режим перенаправления/открытия ввода-вывода, O_APPEND и так далее).
На Linux существует другой способ копировать a fd
(который не является действительно дублированием), и создайте новое открытое описание файла для того же ресурса, но с возможно различными флагами.
exec 3> /dev/fd/4
В то время как на Солярисе и вероятно большинстве других Нельдов, который более или менее эквивалентен dup2(4, 3)
, на Linux, который открывает тот же ресурс как, на который указывает fd 4 с нуля.
Это - важное различие, потому что, например, для регулярного файла, смещение fd 3 будет 0 (начало файла), и файл будет усеченным (который является, почему, например, на Linux необходимо записать tee -a /dev/stderr
вместо tee /dev/stderr
).
И режим I/O может отличаться.
Интересно, если fd 4 указал на конец чтения канала, то fd 3 теперь указывает на конец записи (/dev/fd/3
ведет себя как именованный канал):
$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b
$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b
У меня есть два предсказания нефти, которые могут помочь. Однако не чувствует, что, возможно, что-то лучше придут.
Во-первых, используйте SED, чтобы добавить цитаты всему, поэтому вы покончите только в том случае, если есть только какие-то котировки в имени файла, такое как
ls -t | head -500 | sed -e 's/\(.*\)/"\1"/' | xargs file | grep -v 'image'
, другой - использовать LS, чтобы найти 501-е место Чтобы получить более новые вещи, как
find -newer $(ls -t | head -501 | tail -1) -type f -exec file {} \; | grep -v image
Для общих советов относительно обработки имен файлов, потенциально содержащих пробелы, см. Почему мой скрипт Shell заслонка пробела или других специальных символов?
Трудность с тем, что вы пытаетесь Для этого нет хорошего способа перечислить самые последние файлы со стандартными инструментами.
Самый простой способ сделать то, что вы делаете здесь, - это использовать ZSH как ваша оболочка. Он имеет квалификаторы для сортировки файлов по дате. Для запуска файл
в 500 последних файлах:
file *(om[1,500])
с файлом Linux
Утилита, пропустите -I
или - Тип MIME
Опция, чтобы получить вывод, который легче разбираться. Файлы изображения идентифицируются по линиям, заканчивающимся с изображением / что-то
.
file --mime-type *(om[1,500]) | sed -n 's~: *image/[^ ]*$~~p'
Если вам нужно справиться с абсолютно всеми именами файлов, в том числе с новой строкой в их имени, используйте опцию -0
для вывода NULL-DELIMITED. Последние версии GNU SED могут использовать NULL BYTES в качестве разделителя записи вместо новых линий.
file --mime-type -- *(om[1,500]) | sed -zn 's~: *image/[^ ]*$~~p'
Если у вас нет ZSH, вы можете использовать LS
и справиться с именами файлов, которые содержат пробелы, но не в номинальные или конечные пробелы, передавая опцию -L1
, чтобы Файл
. Это вызвало файл
в одном файле одновременно, поэтому он немного медленнее.
ls -t | head -n 500 | xargs -L1 file --mime-type -- | sed -n 's~: *image/[^ ]*$~~p'
Использование Xargs
, это можно сделать таким образом:
find . -type f -print0 | xargs -0 file | grep -v 'image'
Но вчера
настолько вчера. Крутые дети используют Parallel
сегодня. Используя параллельно, это было бы:
find . -type f | parallel file | grep -v 'image'
см. Без использования -Print0 и -0. Параллель
действительно умно сам.
Обновление
Для листинга только последних 500 файлов ваша команда будет:
ls -1t | head -500 | parallel file {} | grep -v image
важно
в случае, если ваш параллель старый и выше синтаксис не работает, то установите новую версию параллельно как Знаменил здесь: http://www.gnu.org/software/parallel/parallel_tutorial.html
Используйте "find" с опцией "-print0", а вывод - "xargs" с опцией "-0".
Несмотря на то, что я знаю (и использую) эту технику, я вижу, что пользователь @Jens ответил на похожий вопрос, где вы можете найти более подробную информацию :
https://stackoverflow.com/questions/16758525/use-xargs-with-filenames-containing-whitespaces
Можно попробовать
printf "%s\0" $(ls -t | head -500) | xargs -0 file | grep -v image
Это заставляет xargs свести к нулю аргументы имени файла.