Завершающий слеш в путях Linux
Данному вопросу часто не уделяют должного внимания и зря, он не так прост, как кажется, поэтому мы решили уделить ему отдельную заметку.
В Linux символом разделения каталогов является слеш, если после имени файла стоит этот символ, то подразумевается, что данный файл является каталогом. А в Linux, как мы помним, всё есть файл.
Также в Linux очень часто обходятся без расширения имен файлов, потому как тип файла определяется по содержимому (сейчас мы не берем во внимание графические оболочки). Поэтому запись:
~/video
Может быть как файлом, так и каталогом. Если же мы напишем так, то перед нами предположительно каталог:
~/video/
Почему предположительно? Потому что мы можем написать слеш и после имени файла, но если мы попробуем выполнить с ним любую файловую операцию, то система выдаст нам ошибку, потому как данный файл не является каталогом.
Т.е. закрывающий слеш – не императив, а всего лишь указатель на предполагаемый тип файла. Его отсутствие вызывает состояние неопределенности, что может привести к некоторым казусам.
Например, в нашем скрипте написано в цикле что-то вроде:
mv -f "$file" /new_path/video
Данная конструкция имеет неопределенность, потому что если мы забудем создать папку video, то все файлы будут перемещены в новый файл video и последовательно его перезапишут. Т.е. мы останемся без видео, у нас сохранится только последний файл.
Если же мы напишем:
mv -f "$file" /new_path/video/
То при отсутствии директории получим ошибку:
mv: невозможно создать обычный файл ' video/': Это не каталог
Если же мы попробуем указать вместо каталога обычный файл, например, там действительно существует файл video, скажем как результат предыдущего ошибочного запуска скрипта, то ошибка будет иной:
mv: не удалось получить доступ к ' video /': Это не каталог
Т.е. систему не обмануть, и она всегда при файловой операции проверит тип файла, независимо от того поставили вы закрывающий слеш или нет.
Но наличие слеша устраняет неопределенность, потому что явно предписывает системе работать с путем как с каталогом и никак иначе. Кстати, при автоподстановке по Tab пути к каталогам сразу дополняются закрывающим слешем.
Достаточно ли просто добавить завершающий слеш в путь скрипта? А вот здесь все не так просто. Да, мы уберем неопределенность, да получим ошибку. Но что, если это случится уже после того, как скрипт отлажен и запущен в работу? Допустим целевой каталог переместили, переименовали или удалили?
В этом случае мы получим ошибку, запишем ее в лог и дальше? А дальше вопрос, когда именно администратор его прочитает. Ведь все мы любим читать логи за чашкой утреннего кофе, не правда-ли?
Поэтому в скриптах такие вещи всегда лучше проверять явно, например:
if ! [ -d /new_path/video/ ]; then
mkdir -p /new_path/video
fi
В данном случае мы проверили существование каталога и создали его при отсутствии, но никто не мешает выполнить и другие действия, скажем, направить сообщение на почту администратора и прекратить работу скрипта.
В любом случае это лучше, чем просто получить ошибку (или даже многочисленные ошибки) выполнения с записью в лог.
А после того, как мы выполнили подобную проверку и предприняли явные действия, то там уже становится все равно, есть закрывающий слеш в команде перемещения или нет.
Данному вопросу часто не уделяют должного внимания и зря, он не так прост, как кажется, поэтому мы решили уделить ему отдельную заметку.
В Linux символом разделения каталогов является слеш, если после имени файла стоит этот символ, то подразумевается, что данный файл является каталогом. А в Linux, как мы помним, всё есть файл.
Также в Linux очень часто обходятся без расширения имен файлов, потому как тип файла определяется по содержимому (сейчас мы не берем во внимание графические оболочки). Поэтому запись:
~/video
Может быть как файлом, так и каталогом. Если же мы напишем так, то перед нами предположительно каталог:
~/video/
Почему предположительно? Потому что мы можем написать слеш и после имени файла, но если мы попробуем выполнить с ним любую файловую операцию, то система выдаст нам ошибку, потому как данный файл не является каталогом.
Т.е. закрывающий слеш – не императив, а всего лишь указатель на предполагаемый тип файла. Его отсутствие вызывает состояние неопределенности, что может привести к некоторым казусам.
Например, в нашем скрипте написано в цикле что-то вроде:
mv -f "$file" /new_path/video
Данная конструкция имеет неопределенность, потому что если мы забудем создать папку video, то все файлы будут перемещены в новый файл video и последовательно его перезапишут. Т.е. мы останемся без видео, у нас сохранится только последний файл.
Если же мы напишем:
mv -f "$file" /new_path/video/
То при отсутствии директории получим ошибку:
mv: невозможно создать обычный файл ' video/': Это не каталог
Если же мы попробуем указать вместо каталога обычный файл, например, там действительно существует файл video, скажем как результат предыдущего ошибочного запуска скрипта, то ошибка будет иной:
mv: не удалось получить доступ к ' video /': Это не каталог
Т.е. систему не обмануть, и она всегда при файловой операции проверит тип файла, независимо от того поставили вы закрывающий слеш или нет.
Но наличие слеша устраняет неопределенность, потому что явно предписывает системе работать с путем как с каталогом и никак иначе. Кстати, при автоподстановке по Tab пути к каталогам сразу дополняются закрывающим слешем.
Достаточно ли просто добавить завершающий слеш в путь скрипта? А вот здесь все не так просто. Да, мы уберем неопределенность, да получим ошибку. Но что, если это случится уже после того, как скрипт отлажен и запущен в работу? Допустим целевой каталог переместили, переименовали или удалили?
В этом случае мы получим ошибку, запишем ее в лог и дальше? А дальше вопрос, когда именно администратор его прочитает. Ведь все мы любим читать логи за чашкой утреннего кофе, не правда-ли?
Поэтому в скриптах такие вещи всегда лучше проверять явно, например:
if ! [ -d /new_path/video/ ]; then
mkdir -p /new_path/video
fi
В данном случае мы проверили существование каталога и создали его при отсутствии, но никто не мешает выполнить и другие действия, скажем, направить сообщение на почту администратора и прекратить работу скрипта.
В любом случае это лучше, чем просто получить ошибку (или даже многочисленные ошибки) выполнения с записью в лог.
А после того, как мы выполнили подобную проверку и предприняли явные действия, то там уже становится все равно, есть закрывающий слеш в команде перемещения или нет.