. / против для запуска программ под терминалом

13

Мне нужно уточнить, как мы запускаем исполняемые файлы под терминалом. Это может быть неубедительный вопрос, но в чем разница между запуском исполняемого файла ./an_executableи . an_executable(предположим, что мы находимся в каталоге, где находится an_executable)

Я уже знаю, что первое заставляет оболочку искать an_executable в текущем каталоге ( .), но почему /после .использования последней версии это не нужно ?

Заранее спасибо.

ZipZap
источник
См. Также askubuntu.com/q/182012/26972
ysap

Ответы:

22

. executableСинтаксис не работает только с любым исполняемым (или делает это?). Это псевдоним sourceвстроенного bash . Так что разница в основном касается скриптов bash, и правда в том, что они совершенно разные вещи :)

./executableпросит запустить исполняемый файл "нормально". ./является относительной ссылкой на текущий путь. Это позволяет избежать попыток оболочки (bash) найти исполняемый файл в каталоге, в $PATHкотором он находится (что было бы, если бы вы вообще не указали путь с помощью команды). Причина, по которой вы не можете просто сделать executableэто одна из причин безопасности; представьте, что вы распаковываете архив, который вы скачали, и он содержит вредоносную версию ls. Если бы он запускался прямо из вашего текущего каталога, вы бы запустили эту версию, даже не подозревая об этом.

С другой стороны, . executableговорит "источник файла с именем executable". Поскольку вы прямо называете файл, и он действительно не должен быть исполняемым, ограничение безопасности для $ PATH не применяется. Sourcing будет только "запускать" (или, кажется, запускать) сценарии оболочки. Что это делает:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Итак ... В чем разница между исполнением и поиском? Предполагая, что тот же сценарий оболочки, выполнение it ( ./script) порождает новую оболочку, запускает сценарий внутри этой оболочки, а когда сценарий завершается, закрывает эту оболочку и возвращается к родительской оболочке. По сути, он запустит новый bashпроцесс для выполнения скрипта).

( . script) заставит текущую оболочку читать команды из файла, как если бы они вводились в командной строке. Там нет новой оболочки порожденной.

Очень простой способ увидеть, как это ведет себя, - написать скрипт, который содержит только exit. Если вам ./scriptэто кажется, ничего не произойдет, это потому, что запущен новый процесс оболочки, exitкоманда завершает работу этой новой оболочки и ваша текущая оболочка не изменяется.

Если вы . script, ваш текущий терминал закроется, потому что exitкоманда выполняется в текущей оболочке. Так что это эквивалентно вводу exitв командной строке.

roadmr
источник
Действительно, я имел дело со сценарием оболочки, когда заметил это поведение. Большое спасибо, вот ответ, который мне был нужен. :)
zipzap
Еще один вопрос (если вы не возражаете): если мой сценарий содержит только несколько простых сообщений с echo, и я запускаю его с помощью ./script, то почему я могу видеть сообщения в родительской оболочке, если подоболочка закрывается? как только закончится казнь?
zipzap
2
Поскольку подоболочка является отдельным процессом , она использует тот же терминал, что и вызывающая оболочка. Это похоже на то, как вы все еще можете видеть lsвывод: вы набираете команду, она запускается, показывает вывод, а затем заканчивается, но вывод остается в терминале.
roadmr
2
Не путайте оболочку с терминалом; это разные вещи. Откройте терминал, и командная строка будет дана bashвнутренней оболочкой. Если вы напечатаете bash, вы будете запускать другую оболочку; до первой оболочки, это просто программа для запуска. Если вы напечатаете exit, вы закроете последнюю оболочку, которую вы запустили, но все равно будете в первой оболочке (той, с которой вы запустили терминал). Опять же, все это происходит в одном терминале.
roadmr
1
@DavidZ Я упоминал об этом :) «Sourcing будет только« запускать »(или, кажется, запускать) сценарии оболочки».
roadmr