Почему некоторые команды GNU Coreutils имеют -T/--no-target-directory
опцию? Кажется, что все, что он делает, может быть достигнуто с помощью семантики .
(собственной точки) в традиционной иерархии каталогов Unix.
Принимая во внимание:
cp -rT /this/source dir
Эта -T
опция предотвращает создание копии dir/source
подкаталогом. Скорее /this/source
идентифицируется с dir
и содержимое отображается между деревьями соответственно. Так, например, /this/source/foo.c
идет dir/foo.c
и так далее, а не к dir/source/foo.c
.
Но это может быть легко достигнуто без использования -T
опции:
cp -r /this/source/. dir # Probably worked fine since dawn of Unix?
Семантически компонент задней точки копируется как дочерний элемент dir
, но, конечно, этот «дочерний элемент » уже существует (поэтому его не нужно создавать) и фактически является dir
самим собой, поэтому эффект /this/path
идентифицируется с dir
.
Это работает нормально, если текущий каталог является целью:
cp -r /this/tree/node/. . # node's children go to current dir
Есть ли что-то, что вы можете сделать только с этим, -T
чтобы рационализировать его существование? (Помимо поддержки операционных систем, которые не реализуют каталог точек, обоснование, не упомянутое в документации.)
Разве вышеприведенный точечный фокус не решает те же условия гонки, о которых говорится в документации GNU Info -T
?
.
Трюк делает работу при копировании файла, только не при переименовании его базового имени в то же время!cp /path/to/file /target/dir/.
Если/target/dir/file
существует и является каталогом, вы получаете такую же диагностику! Но вы показали-T
, что нельзя сделать без него за один шаг, без условий гонки: скопируйте файл и измените его имя, не передавая его в подкаталог..
уловка, о которой вы говорите, заключается в добавлении/.
к источнику .Проблема с
cp
/mv
/,ln
поскольку они были изначально разработаны, состоит в том, что они представляют собой две команды в одной ( копировать в и копировать в ).это либо копирование A в B, либо копирование A в B ( копирование A в B / A ) в зависимости от того,
B
существует ли и является ли каталог каталогом или нет (и больше вариантов, если B является символической ссылкой на каталог).Это плохо, потому что это неоднозначно. Таким образом, реализации GNU добавили варианты, чтобы обойти это.
копии от А до Б независимо. Если
B
существует и является каталогом, это не удастся (если вы не пройдете-r
). В любом случае вы не получитеA
файл внутри,B
если вы намеревалисьA
скопировать его в B.А также:
это копия в .
источник
cp A B
команду, она не сделает то, что вы хотели. И в действии[ -e B ] || [ -L B ] || cp A B
все еще есть состояние гонки, которогоcp -Tn A B
нет.-T
Может обеспечить провал , если каталог неправильно существует для того, что должно быть файл назначения:То есть вместо успешного завершения при неожиданном копировании в подкаталог возникает предупреждение и плохой статус выхода, что может привести к прерыванию работы сценария, и человек проверяет, почему существует каталог, в котором его не должно быть. Будь один.
источник
Использование флага также намного понятнее и снижает риск непреднамеренных эффектов, когда команда используется в сценарии, а не вводится вручную. Вставка точек в пути в скрипте может привести к неожиданным неприятностям.
источник