Что такое абсолютный и относительный путь в Linux? Почему скрипт запускают как ./script?
Перешёл с Windows и не до конца понял систему путей. Когда писать полный путь от корня, а когда можно короткий? И главное — почему свой скрипт нельзя запустить просто по имени, а нужно ./script.sh, хотя я уже внутри этой папки? В чём логика этой точки со слэшем?
2 ответа
Два типа путей отличаются точкой отсчёта.
Абсолютный — всегда от корня /, не зависит от того, где вы находитесь:
/home/user/projects/app.js
/etc/nginx/nginx.conf
Относительный — от текущего каталога (узнать его можно командой pwd). Здесь работают два спецсимвола:
. # текущий каталог
.. # родительский каталог
cd ../logs # подняться вверх и зайти в logs
cat ./config.txt # файл в текущей папке
Теперь про ./script.sh. Когда вы вводите команду по имени, оболочка ищет её не в текущей папке, а только в каталогах из переменной PATH:
echo $PATH
# /usr/local/bin:/usr/bin:/bin — текущей папки тут НЕТ
Текущий каталог намеренно не входит в PATH ради безопасности: иначе подложенный в папку файл с именем ls мог бы выполниться вместо настоящей команды. Поэтому, чтобы явно сказать «запусти файл вот отсюда», указывают относительный путь ./ — точка означает «текущий каталог»:
chmod +x script.sh # сначала делаем файл исполняемым
./script.sh # запускаем по явному пути
Про права (rwx). Запуск возможен только при флаге x (execute). Посмотреть права — ls -l:
-rwxr-xr-x 1 user user 120 script.sh
drwxr-xr-x 2 user user 4096 logs
Первый символ: - файл, d каталог. Дальше три тройки rwx — права для владельца, группы и остальных (read / write / execute). Без x оболочка ответит Permission denied, поэтому chmod +x идёт перед первым запуском.
Короткое уточнение, чтобы связать всё в одну картину: ./script.sh — это и есть относительный путь, просто записанный явно. Запись script.sh без ./ оболочка трактует как «команда из PATH», а ./script.sh — как «файл по пути от текущей папки».
Если скрипт планируете звать откуда угодно по имени — положите его в каталог из PATH (часто ~/.local/bin или /usr/local/bin) и не забудьте про chmod +x. Тогда ./ уже не понадобится.