cp SOMEFILE .. копирует в другой каталог после cd'ing через символическую ссылку

Рассмотрим следующую настройку:

~/Desktop/Public/subdir ~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link) 

Теперь я делаю:

 cd ~/Desktop/subdir 

Это приводит меня в связанный каталог.

Если я сейчас выдаю команду:

 cd .. 

Я вернусь в каталог Desktop . Это означает, что команда cd чувствительна к контексту – она ​​помнит, что я ввел subdir через символическую ссылку.

Однако выдача команды

 cp testfile .. 

скопирует testfile в Desktop/Public .

Я предпочитаю поведение cd по (часто непредсказуемому) поведению cp . В любом случае, интересно, в чем причина этой разницы в поведении? Просто устаревшая вещь или есть веская причина?

3 Solutions collect form web for “cp SOMEFILE .. копирует в другой каталог после cd'ing через символическую ссылку”

Причина, по которой cd знает, что вы ввели каталог через symlink состоит в том, что она встроена в оболочку. Команда cp является внешним двоичным файлом и передается только через аргументы командной строки и переменные среды. Переменные среды не содержат данных о том, как вы ввели текущий каталог.

Если вы используете bash , вы можете сделать функцию cd той же, что и cp если вы хотите, чтобы все было согласованным. set -P выполнит это. С manpage:

  -P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the logical chain of directories when performing commands which change the current directory. 

Когда cd работает, как описано, это может быть только трюк cd или вашей оболочки. .. является записью в родительский каталог. В вашем случае родительский subdir может быть только Public а не Desktop . Таким образом, cp правильно думает, и вы получите такое же поведение с переадресацией (например, > ).

В примере cd используется только «удобный» трюк, чтобы вести себя так, как будто это происходит. См. https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links

Если вам действительно нужна функциональность, вы должны использовать что-то вроде

 cp testfile "${PWD##*/}" 

(копировать в родительский каталог текущего каталога, в соответствии с отслеживанием оболочки). В zsh вы можете упростить это до cp testfile $PWD:h

Скорее наоборот: cp ведет себя как любое другое приложение, оно интерпретирует .. как родительский каталог текущего каталога. Это потому, что ядро ​​интерпретирует .. как родительский каталог текущего каталога.

Когда вы запускаете cd через символическую ссылку, путь, который вы передаете в cd , не делает родительский каталог целевого каталога очевидным. Когда вы запускаете cd ~/Desktop/subdir , пункт назначения не является /home/konstantin/Desktop/subdir – это символическая ссылка. Целевой каталог: /home/konstantin/Desktop/Public/subdir . (Или, чтобы быть педантичным: каталог назначения – это подкаталог поддиректора подкаталога Public of … подкаталога, называемого home корневого каталога.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop : свойство, которое родительский каталог /…stuff…/subdir is /…stuff… выполняется только при отсутствии подкаталогов.

Потому что часто удобно думать о символических ссылках на каталоги, как если бы они были каталогами, оболочки выполняют символическое отслеживание ссылок. Когда вы запускаете cd , оболочка запоминает, какой путь (возможно, используя символические ссылки) вы использовали для достижения цели. И когда вы используете .. в аргументе для cd (или подобных встроенных оболочек, таких как pushd ), оболочка выполняет текстовую интерпретацию .. вместо того, чтобы интерпретировать ее как текущий каталог: cd /some/stuff/../more is преобразован в cd /some/more . Таким образом, cd ведет себя так, как будто символические ссылки на самом деле являются каталогами.

Текстовая интерпретация .. известна как логическое отслеживание каталогов, а интерпретация файловой системы .. известна как отслеживание физического каталога. Если вы хотите использовать отслеживание физического каталога (т. Е. Отключить текстовую интерпретацию .. ), передайте параметр -P на cd . Опция -L заставляет логическое отслеживание, если оно отключено. По умолчанию отключено логическое отслеживание; вы можете отключить его с помощью set -P в bash или с помощью setopt chase_links в zsh.

Команда pwd отображает текущий каталог, отслеживаемый оболочкой. Как и cd , вы можете передать параметр -L или -P для принудительного логического или физического отслеживания.

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

Переменная оболочки PWD отслеживает текущий каталог ( $PWD содержит ту же строку, что и pwd ). Если вы хотите удалить последний текстовый компонент отслеживаемого пути в текущий каталог, вместо добавления /.. который работает только с логическим отслеживанием, вы можете использовать текстовый метод.

 cp testfile "${PWD##*/}" 

или в zsh:

 cp testfile $PWD:h 

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

 cp testfile "$(cd .. && pwd)" 
  • Symlink везде
  • Перечислите прямые символические ссылки (ссылки, которые не указывают на другую символическую ссылку)
  • Symlink всех каталогов внутри одного каталога в другой каталог
  • Копировать дерево каталогов, изменяя цель абсолютных символических ссылок
  • Символьная ссылка не является рекурсивной
  • Как заставить создать символическую ссылку?
  • root не может подключиться к symlinked socket другого пользователя
  • readlink -f не работает с несколькими файлами
  • Могу ли я сделать символическую ссылку на разные местоположения на разных машинах?
  • Почему root утрачивает разрешение символической ссылки 1-го и 2-го уровней?
  • Выполнение символической ссылки на разных физических дисках
  • Linux и Unix - лучшая ОС в мире.