На моем сервере структура каталогов выглядит примерно так:
/myproject/code
У меня обычно есть SSH-соединение с сервером и «стоять» в этом каталоге:
root@machine:/myproject/code#
Когда я развертываю новую версию своего кода, каталог кода удаляется, поэтому у меня остается:
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
И единственное решение, которое я нашел, это переписаться и вернуться:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
Могу ли я избежать этого? Это несколько странное поведение. Если у вас есть хорошее объяснение, почему это происходит, я был бы признателен.
shell
command-line
directory
cd-command
Маркус Йоханссон
источник
источник
run
совпадает со старым каталогом. Он имеет только то же имя и родительский каталог. Сравните это с тем, что вы измельчаете свою старую машину и покупаете новую машину точно такого же цвета и модели: вы не хотели бы сидеть в машине, которую разрывают, и надеетесь, что вы окажетесь на новой целой, не так ли?cd ../code
- это не шумиха...
является ярлыком для родительского пути, который у вас есть или использовался. Если ваш текущий каталог удален, родительский путь все еще может существовать, и в этом случае он будет доступен для оценки..
. В этом каталоге выполняется поиск каталога с именем «код».Ответы:
Поскольку файлы и каталоги являются в основном инодами файловой системы , а не именами - возможно, это детали реализации, специфичные для типа файловой системы, но это верно для всех систем ext, поэтому я буду придерживаться этого здесь.
Когда создается новый каталог
code
, он связывается с новым индексом, и вот где он находится. Не ведется запись ранее удаленных файлов и каталогов, поэтому нет системы, с помощью которой система могла бы проверять, какой инод он занимал, и, возможно, перетасовывать вещи так, чтобы они снова были такими же; такая система быстро станет неработоспособной, и в любом случае, вероятно, нет никакой гарантии, что вы вернетесь туда снова - это было бы нежелательно, поскольку это означает, что вы также можете случайно оказаться в другом месте, если каталог будет создан это займет ваш (в настоящее время не используется) inode.Я не уверен, существует ли эта последняя возможность, или же отслеживается индекс удаленного каталога, который в данный момент назначен вашему текущему рабочему каталогу, так что ему ничего не будет назначено на время и т. Д.
источник
Ваша оболочка не каждый раз указывает
cd
путь, по которому она была во время последней команды, перед выполнением следующей команды.Вы удалили текущий каталог и создали каталог с тем же именем, который не является тем же каталогом, просто что-то с тем же именем / путем.
Файловые браузеры, такие как Nautilus и Windows Explorer, обычно «поднимаются» по дереву каталогов, если каталог удаляется в локальной файловой системе. Однако это не всегда верно для сетевых файловых систем, в этом случае иногда удаление не замечается, и повторное появление может привести к тому, что вы окажетесь в новом каталоге.
Оболочка может
cd
войти в текущий каталог перед выполнением следующей команды, я не знаю ни одной, которая делает (или может быть настроена для этого).источник
В большинстве UNIX-подобных систем «текущий каталог» процесса хранится в ядре как дескриптор файла, указывающий на этот каталог. Ядро фактически не хранит путь к текущему каталогу: эта информация отслеживается вашей оболочкой.
Объект файловой системы (файл или каталог) уничтожается навсегда, только когда все ссылки на него отсутствуют, а файловые дескрипторы не указывают на этот объект.
Таким образом, если каталог удален, пока существует процесс, который удерживает его в качестве текущего рабочего каталога, процесс не
cwd
позволит каталогу быть действительно удаленным. Ссылки на файловую систему, которые привязывают каталог (его запись в родительском каталоге и все его содержимое), будут удалены, но сам каталог будет продолжать существовать как своего рода «зомби». Между тем, вы можете создать новый каталог в том же месте, что и старый, который является совершенно другим объектом файловой системы, но имеет тот же путь.Таким образом, когда вы делаете
cd ../code
(или, на многих оболочкахcd .
), вы фактически пересекаете иерархию файловой системы и переходите в новый каталог, который находится по старому адресу.По аналогии, удаление каталога было бы похоже на принудительное перемещение дома на свалку (разрыв связи с предыдущим адресом). Если бы там еще кто-то жил (используя его как свою
cwd
), им пришлось бы уйти до того, как дом мог быть разрушен. Тем временем, новый дом может быть построен по старому адресу.источник
@Anthon прояснил причины, почему это происходит.
В качестве решения вы можете использовать псевдоним , например:
псевдонимы для bash хранятся в ~ / .bashrc
источник
Подтверждение Текущий рабочий каталог основан на номере инода, а не на том, что вы искали, чтобы попасть туда. Поскольку вы используете bash, вы можете использовать $ PWD следующим образом для перехода в новый каталог с тем же именем:
CD $ PWD
Чтобы проиллюстрировать это, я сделал фиктивную команду развертывания:
Создал первое развертывание, cd'd для кодирования, а затем проверил содержимое,
ls -lai
чтобы вы могли видеть inode:Теперь запустите 2-е развертывание
И проверьте содержимое каталога ... теперь в каталоге ничего нет! даже не '.' и '..'! Из этого вы можете видеть, что bash не использует запись каталога «..» при запуске,
cd ..
поскольку «..» больше не существует - я предполагаю, что это часть его обработки $ PWD. Некоторые другие / более старые оболочки не справляютсяcd ..
с этой ситуацией, сначала вы должны перейти на абсолютный путь.Перейдите
$PWD
и попробуйте снова:Обратите внимание, как изменился индекс для текущего каталога (.)?
Если ваш сценарий развертывания перенес старый каталог на другое имя, например,
mv code code.$$
в приведенном выше сценарии развертывания, он./run
будет работать, но до тех пор , пока вы его не используете,cd $PWD
вы будете запускать старый код, а не новый.Развертывание с использованием capistrano имеет ту же проблему (у них есть символическая ссылка от имени текущего к текущему выпуску), поэтому я использую псевдонимы для cd в производственных / промежуточных областях, а также соответственно устанавливаю RAIL_ENV:
источник
Путь к чему-то - это то, как вы туда попадаете, а не сама вещь. Путь к вашей кровати может проходить через вашу комнату, но как только вы окажетесь в постели, если кто-то поднимет ее и вынесет на улицу, вас больше не будет в вашей комнате.
источник
Не самодостаточный ответ, но у меня есть дополнительный момент, который поле для комментариев было слишком маленьким, чтобы его содержать.
Чтобы лучше понять, что каталог в соответствующих файловых системах - это больше, чем просто путь, попробуйте переместить текущий рабочий каталог другого процесса: в одной оболочке запустите интерактивный сеанс Python:
Затем перейдите в другую оболочку и переместите этот каталог:
Вернуться к оригиналу:
источник