Grep строка из одного и того же файла в нескольких файлах .tar.gz [дубликат]

Я могу воспроизвести приведенные выше сообщения следующим образом:

mkdir test; cd test
mkdir repos; cd repos

mkdir g; cd g
git init
touch a
git add a
git commit -m test
cd ..

git clone g h
cd ..

mkdir copy
cp -ua repos copy
cp -uav repos copy

Запуск команды cp -ua под strace покажет, что она действительно удаляет (unlink) файлы, которые он говорит.

Случилось так, что объекты в repo/h/.git/objects являются жесткими ссылками на объекты в repo/g/.git/objects. (В моем исходном случае я копировал репозиторий, содержащий вложенные репозитории, которые изначально были созданы как клоны основного репо).

cp -a означает cp --preserve, что задокументировано как

--preserve[=ATTR_LIST]

сохранить указанные атрибуты (по умолчанию: режим, владение, временные метки ), по возможности дополнительные атрибуты: контекст, ссылки, xattr, все

Развязка происходит как часть сохранения жестких ссылок:

linkat(AT_FDCWD, "копировать/repos/g/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", AT_FDCWD, "копия/репозитории/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", 0) = -1 EEXIST (Файл существует)

unlink("copy/repos/h/.git/объекты/2b/bf350cea1fb4fd036235d7e6c36eb600e68885") = 0

linkat(AT_FDCWD, "копировать/repos/g/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", AT_FDCWD, "копия/репозитории/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", 0) = 0

А почему именно он генерирует сообщения, которые меня так смутили?

Похоже, -u (--update) не совсем реализовано в этом коде. В основном это оптимизация производительности, позволяющая избежать ненужного повторного копирования данных. Создание жестких ссылок не требует копирования каких-либо данных.

В документации мы можем увидеть другие сценарии, в которых cp также должен удалять файлы:

  -f, --force

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

В случае с -f я понимаю, что он может захотеть показать определенные файлы, которые он должен «форсировать».

Я полагаю, было бы также полезно показать удаление, если cp прерывается. В противном случае пользователи вряд ли поймут, что файл мог быть удален из места назначения (в качестве промежуточного шага).

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

0
15.09.2016, 10:05
2 ответа

Команда zgrep работает с файлами .tar.gz без извлечения содержимого.

1
28.01.2020, 02:14

Предположим, что под «без извлечения» вы подразумеваете «без сохранения извлеченных файлов на диск» :

for file in *.tar.gz ; do
    tar xzOf $file b | grep --label=$file/b -H foo
done

параметры tar:

x извлекать
z gunzip перед извлечением
O дампа в стандартный вывод вместо создания файла (заглавная буква ой, а не цифра ноль)
f из указанного файла tar

Параметры grep (предложены JJoao)

- label = ... использовать указанную метку в качестве имени файла
-H печатать имя файла для каждого совпадение

6
28.01.2020, 02:14

Теги

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