Как я могу сохранить строковый литерал переменной без подстановки или интерпретации?

Обычно .tar.gz - это используемый формат распространения файлов. GNU tar позволяет заменять владельца, группу и разрешения другими значениями при добавлении файлов в архив.

$ tar -c -f archive.tar --owner=0 --group=0 .

https://www.gnu.org/software/tar/manual/html_section/tar_33.html#SEC69

Если ваша версия tar не поддерживает параметры GNU, вы можете скопировать исходные файлы в другое дерево каталогов. и обновите там группу и владельца, прежде чем создавать файл tar.gz для распространения.

3
17.09.2017, 22:35
2 ответа

Если вы используете GNU mv, вам лучше сделать:

find. -type f -exec mv -t. {} +

С другими mvс:

find. -type f -exec sh -c 'exec mv "$@".' sh {} +

Ни в коем случае нельзя вставлять {}в код sh. Это уязвимость внедрения команд, поскольку имена файлов интерпретируются как шелл-код (попробуйте с файлом с именем `reboot`, например ).

Хорошая идея заключить подстановку команды в кавычки, но поскольку вы использовали архаичную форму(`...`вместо $(...)), вам нужно экранировать внутренние двойные кавычки, иначе это не будет работать в sh. ] реализации, основанные на оболочке Bourne или AT&T ksh (, где "`basename "foo bar"`"фактически будет рассматриваться как"`basename "(с непревзойденным `, который принимается в этих оболочках ), объединенных с foo, а затемbar"`").

Кроме того, когда вы делаете:

mv foo/bar bar

Если бы barдействительно существовал и был каталогом, это был бы mv foo/bar bar/bar. mv -t. foo/barили mv foo/bar.не имеют этой проблемы.

Теперь, чтобы сохранить эти несколько аргументов (-exec, sh, -c, exec mv "$@"., sh, {},+)в переменной, вам понадобится переменная-массив. Оболочки, поддерживающие массивы: (t)csh, ksh,bash, zsh, rc, es, yash, fish.

И чтобы иметь возможность использовать эту переменную просто как $FLATTEN(, а не "${FLATTEN[@]}"в ksh/bash/yash или $FLATTEN:qв (t)csh), вам понадобится оболочка с разумной реализацией массива :rc. ], esили fish. Также zshздесь, как это бывает, ни один из этих аргументов не является пустым.

В rc/ es/zsh:

FLATTEN=(-exec sh -c 'exec mv "$@".' sh '{}' +)

Вfish:

set FLATTEN -exec sh -c 'exec mv "$@".' sh '{}' +

Затем вы можете использовать:

find. -type f $FLATTEN
9
27.01.2020, 21:07

Как насчет функции?

flatten(){
  find "$@" -type f -exec sh -c 'mv -- "$0" "${0##*/}"' {} \;
}

Использование:

> flatten.

Если вы используете zsh, для этого есть опция -gдля alias. Он позволяет определить псевдоним, который вставляется глобально, а не только в имя команды.

3
27.01.2020, 21:07

Теги

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