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)" 
  • Символьная ссылка не является рекурсивной
  • Как следовать символическим ссылкам в NFS?
  • Скопировать символическую ссылку И где она указывает на использование rsync
  • Поведение команды `du` с флагом` -L`
  • Показать содержимое символической ссылки
  • Сценарий разрешения FS
  • Solaris tar: «Не удалось создать символическую ссылку: не каталог»
  • Создание символической ссылки в / bin автоматически создает вторую ссылку в / usr / bin и какая команда выбирает / usr / bin
  • Добавление к пути против привязки из / bin
  • ln дает разные результаты при многократном запуске
  • Не удается удалить сломанную символическую ссылку
  • Interesting Posts

    Разрешить пользователю использовать sudo без пароля

    Запустить приложение при запуске

    Почему мы не можем убить зомби?

    Получение моего Smart Card Reader для работы в Linux

    Что делают эти команды («tar`)? Есть ли способ лучше?

    Почему моя распашная раковина открывает fstab, содержит так много записей subvol btrfs?

    MIME-тип изменяется, если файл редактируется в системах * nix

    Как устранить проблему подключения Intel Edison и Bluetooth-гарнитуры HM1100?

    Может ли сращиваться () / tee () работать с сокетами, а не только с трубами?

    Драйверы Ubuntu на операционной системе Chromium?

    Параметр kernel quiet по сравнению с loglevel = 4 и debug по сравнению с loglevel = 7

    Gparted: изменить размер (разделение) первичного раздела?

    Поместить длинный список адресов электронной почты в многострочную макро переменную

    kerberos preauth pkinit не удалось инициализировать: не было настроено правильно для поддержки pkinit

    Как выполнить цикл for в bash как строку

    Linux и Unix - лучшая ОС в мире.