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


13

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

Я вже знаю, що перший змушує оболонку шукати an_executable у поточному каталозі ( .), але чому це не /потрібно після .використання останньої версії?

Заздалегідь спасибі.


Дивіться також 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.

Отже ... Яка насправді різниця між виконанням та пошуку? Якщо припустити той самий скрипт оболонки, його виконання ( ./script) породжує нову оболонку, запустить сценарій всередині цієї оболонки, а коли скрипт вийде, закрийте цю оболонку та поверніться до батьківської оболонки. По суті, він запустить новий bashпроцес виконання сценарію).

( . script) призведе до того, що поточна оболонка зчитує команди з файлу так, ніби вони були введені в командному рядку. Не породжена нова оболонка.

Дуже простий спосіб побачити, як це поводиться, - це написати сценарій, який містить лише цей exit. Якщо ви ./scriptце зробите, то, здається, нічого не відбудеться, це тому, що запускається новий процес оболонки, exitкоманда закриває цю нову оболонку і вашу поточну оболонку.

Якщо ви . script, ваш поточний термінал закриється, оскільки exitкоманда працює в поточній оболонці. Отже, це рівнозначно набору тексту exitв командному рядку.


Дійсно, я мав справу зі сценарієм оболонки, коли помітив таку поведінку. Дуже дякую, ось потрібна відповідь. :)
zipzap

інше поставлене питання (якщо ви не заперечуєте): якщо мій скрипт містить просто кілька простих повідомлень із луною, і я запускаю його. як тільки страта закінчується?
zipzap

2
Оскільки, хоча підпакет - це окремий процес , він використовує той же термінал , що і оболонка виклику. Це схоже на те, як ви все ще можете бачити lsвихід: ви вводите команду, вона запускається, показує вихід, а потім закінчується, але вихід залишається в терміналі.
roadmr

2
Не плутайте оболонку з терміналом; вони різні речі. Відкрийте термінал, і командний рядок надається bashоболонкою, що працює всередині нього. Якщо ви введете bash, буде запущена інша оболонка; до першої оболонки, це просто програма, яку потрібно запустити. Якщо ви введете exit, ви закриєте останню оболонку, яку ви розпочали, але все ще будете в першій оболонці (тій, що була запущена терміналом). Знову ж таки, все це відбувається в межах одного терміналу.
roadmr

1
@DavidZ Я це згадав :) "Sourcing буде лише" запускати "(або, здається, працювати) сценарії оболонки."
roadmr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.