Кроссплатформенный способ удаления dir из tarball - PullRequest
0 голосов
/ 18 декабря 2018

Я нашел это: https://www.cyberciti.biz/faq/unix-linux-appleosx-bsd-tar-remove-directory/

tar --delete -f file.tar 'path1/dir1'

, но это не работает на MacOS.Я получаю:

tar: Option --delete is not supported

Я ищу что-то, что работает на всех * nix вкусах.Кто-нибудь знает хороший способ сделать это?Может быть, мне действительно нужно сначала распаковать и проигнорировать папку, а затем повторно архивировать ее?

1 Ответ

0 голосов
/ 20 декабря 2018

Краткий ответ

Да, если вам нужно решение, которое работает на многих * nix разновидностях , тогда вам придется;сначала распакуйте, игнорируйте папку, а затем повторно запустите ее.


Решение:

Я бы сделал что-то вроде следующего:

# Path to source .tar
src_tar=/the/path/to/your/tarfile.tar

# Path to dir in .tar that you want to delete.
rm_tar_dir=path1/dir1

# Create a temporary dir for extracting the .tar contents into.
tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'tar-tmpdir')

# Extract all contents from the source .tar to a temporary dir
tar zxf "$src_tar" -C "$tmp_dir"

# Delete the unwanted dir from temporary dir.
rm -rf "${tmp_dir:?}/${rm_tar_dir}"

# Create new .tar archive, overwriting the original source .tar
tar czf "$src_tar" -C "$tmp_dir" .

# Clean up
rm -rf "$tmp_dir"

Почему я рекомендую решение, показанное выше:

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

Iпришли к выводу о предложенном выше решении на основе следующих результатов / исследований.Варианты * nix , описанные в таблицах поддержки / совместимости ниже, далеко не исчерпывающие.Я выбрал их из перечисленных вкусов здесь .

Большинство выбранных вкусов - это те, которые разработаны группами добровольцев, которые делают их доступными бесплатно(Открыть BSD, Free BSD и т. Д.).К счастью, документация, справочные страницы и т. Д. Для этих * nix flavors публикуются онлайн, и они оказали основное влияние на мое принятие решений.IBM AIX и Sun Solaris являются исключениями, поскольку они являются проприетарными, однако для них были доступны некоторые документы, справочные страницы и т. Д.


Таблицы поддержки / совместимости

  • Опция tar --delete

    Начнем с рассмотрения поддержки опции tar commands --delete.Как видно из таблицы ниже, это далеко не так широко поддерживается :( Следовательно, поэтому кажется необходимым принять более подробное решение - к сожалению, мы не можем использовать oneliner, когда требуется кроссплатформенность.

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │ --delete    │  x  │  x   │  x   │  √  │       x      │   √   │    x    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    
  • Другие tar опции

    В представленном выше решении используется несколько опций tar, а именно;-z, -x, -f, -c и -C.Как вы можете видеть в таблице ниже, они широко поддерживаются.Однако, в частности, опция -z (которая используется для фильтрации архива через gzip) не поддерживается в IBM AIX, которая, на мой взгляд, используется на мэйнфреймах - (так что я предполагаю, что это, вероятно, не слишком много для нарушителя правилдля вас).

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -z         │  x  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -x         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -f         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -c         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -C         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  --exclude  │  x  │  x   │  √   │  √  │      √       │   √   │    x    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

    Опция tar --exclude

    Обратите внимание, что в предыдущей таблице опция --exclude также не поддерживается широко -по этой причине мы не используем его в предлагаемом решении.Я бы не стал исключать нежелательный каталог (то есть тот, который вы хотите удалить) при распаковке .tar.Поэтому старайтесь не делать что-то вроде этого:

    # Don't do this....
    
    # Extract all contents from the source .tar to a temporary dir,
    # and exclude the directory that you effectively want to delete.
    tar zxf "path/to/tarfile.tar" --exclude "path1/dir1" -C "path/to/tmpdir"
    

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


  • Другие команды, используемые решением

    В таблице ниже показаны остальные команды, использованные в предлагаемом решении:

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  rm -rf     │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp     │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp -d  │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp -t  │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

    Как видите, мы можем использовать rm -rf, поскольку он хорошо поддерживается.

    Будьте осторожны с mktemp ...

    mktemp и его опции -t и -d, по-видимому, менее широко поддерживаются.(Примечание: я не уверен, поддерживается ли он в Free BSD или нет - отсюда индикатор ?).

    Итак, хотя мое предлагаемое решение использует mktemp, вы можете использоватьmkdir -p вместо этого, поскольку это широко поддерживается, как показано в следующей таблице:

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mkdir -p   │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

Ссылки

Следующие ссылки были использованы для заключения опредлагаемое решение и составьте таблицы совместимости:

  1. tar

  2. mktemp -d -t

  3. rm -rf

  4. mkdir -p

  5. Другие

...