Виконуючи програму C a.out, використовуючи термінал Ubuntu, чому мені завжди потрібно вводити ./раніше a.out, а не просто писати a.out? Чи є для цього рішення?
Виконуючи програму C a.out, використовуючи термінал Ubuntu, чому мені завжди потрібно вводити ./раніше a.out, а не просто писати a.out? Чи є для цього рішення?
Відповіді:
Коли ви вводите назву такої програми, як a.outсистема шукає файл у вашому PATH. У моїй системі встановлено значення PATH
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Ваш, певно, схожий. Для перевірки введіть echo $PATHтермінал.
Система переглядає ці каталоги в заданому порядку, і якщо вона не може знайти, програма видає command not foundпомилку.
Попереджуючи команду, ./ефективно пише: "забудь про PATH, я хочу, щоб ти дивився лише в поточному каталозі".
Аналогічно ви можете сказати системі шукати лише в іншому конкретному місці, попередньо додавши команду до відносного або абсолютного шляху, такого як:
../засоби в батьківському каталозі, наприклад, ../helloшукайте привіт у батьківському каталозі.
./Debug/hello: "шукати helloу підкаталозі налагодження мого поточного каталогу."
або /bin/ls: "шукати lsв каталозі /bin"
За замовчуванням поточний каталог не стоїть на шляху, оскільки він вважається ризиком безпеки. Дивіться, чому так. не в шляху за замовчуванням? на Superuser чому.
Можна додати поточний каталог до вашого PATH, але з причин, наведених у пов'язаному питанні, я б не рекомендував його.
.до своїх PATH(як це підказують інші 2 відповіді) через ризик безпеки, зазначений у цій відповіді.
., ви можете використовувати повний або відносний шлях до виконуваного файлу, наприклад, /home/user/foo/a.outабо./build/a.out
.це особливе, оскільки це означає "мій поточний каталог", тому може бути будь-яка директорія, яку користувач знаходить у них з привілеями для читання та виконання. Це потенційно небезпечніше, ніж додавання конкретного повністю кваліфікованого шляху.
.не має особливого статусу, це просто шлях , який міг би так само добре почати з /і ./blahбуде працювати так само добре catабо grepяк Баш рядку.
Причина цього проста.
Припустимо, у вас є команда з тим самим іменем, що і програма у поточному каталозі. Потім запуск команди в оболонці викликає ваш додаток замість вбудованої команди. Це було б проблемою безпеки, якщо нічого іншого.
Вимагаючи ./використання спереду, оболонка знає, що ви хочете виконати програму із заданим іменем, а не вбудованою командою з цим ім'ям.
./виконує файли, яких немає у вашому $PATH, скоріше він виконує файл у поточному каталозі (або іншому через ./home/stefano/script.sh). Тепер PATH - це змінна середовище, яка містить усі місця, де bash може шукати виконувані програми, не маючи повного (абсолютного) шляху до них.
Ця відокремлення потрібна, щоб уникнути запуску неправильного файлу. Тобто, якщо lsу вашому домашньому каталозі є файл, який викликається , він не перебуває у вашому PATH, не дозволить Bash переплутати його з реальним ls. Змінна PATH також визначає порядок пошуку:
execсистемний виклик (спеціальний метод ядра, як запускаються програми), система шукає файл, переглядаючи кожен із каталогів вашої PATH. Як тільки програма знайдена, навіть якщо вона знаходиться в декількох каталогах, пошук переривається і перший знайдений запускається.Щоб запустити файл, вам потрібно встановити виконавчий біт у дозволах:
Оскільки ви вже в командному рядку, ви можете просто ввести chmod +x finename.
Або ви можете встановити дозволи, клацнувши правою кнопкою миші файл і вибравши Властивості :

Тепер ви можете скопіювати файл у будь-який із каталогів PATH, щоб побачити, які з них є - і вони встановлені на основі користувача - типу echo $PATH.
stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Якщо ви створюєте виконуваний файл, catі переміщуєте його /usr/local/sbin, він запускається замість належного cat, який знаходиться в /bin. За допомогою type catта whereis cat. Ви можете дізнатися, де знаходяться Ваші файли .
gcc, що автоматично встановлює біт виконання.
./перед виконанням програми?У терміналі щоразу, коли ви вводите назву програми, скажімо gedit, термінал буде шукати деякі (заздалегідь визначені) каталоги, які містять програми (бінарні програми). Назви цих каталогів містяться у змінній, що називається PATH. Ви можете побачити, що є в цій змінній, виконавши echo $PATH. Бачите ці каталоги, розділені :? Ті каталоги , що термінал буде йти пошук, якщо ви просто ввести gedit, nautilusабо a.out. Як бачите, шляху вашої a.outпрограми там немає. Коли ви це робите ./a.out, ви говорите терміналу: "загляньте в поточний каталог і запустіть a.out, а не заходьте PATH.
Якщо ви не хочете вводити ./кожен раз, вам потрібно буде додати a.outкаталог каталогу $PATH. У наступних інструкціях я припускаю, що шлях a.outє /path/to/programs/, але ви повинні змінити його на власний шлях.
Просто додайте наступний рядок до кінця файлу ~/.pam_environment:
PATH DEFAULT=${PATH}:/path/to/programs
Джерело: Стійкі змінні середовища
Вийдіть із системи та увійдіть знову. Тепер ви зможете працювати a.outбез ./жодного каталогу.
Якщо у вас є інші програми в інших каталогах, ви можете просто додати їх до вищевказаного рядка. Однак я б радив, наприклад, мати один каталог під назвою "myPrograms" і помістити під нього всі ваші програми.
Примітка: змініть
userNameвласне ім'я користувача Ubuntu.
Що робити, якщо у вас є інші програми, які ви хочете запустити? І всі вони в різних папках? Ну, "більш організованим" рішенням було б створити папку, що називається binпід домашньою каталогом, та додати символьні посилання (ярлики) під цю папку. Ось як:
mkdir /home/userName/bin
binпід домашнім каталогом.ln -s /path/to/programs/a.out /home/userName/bin
a.outпрограми під bin.Вийдіть із системи та увійдіть знову. Тепер ви зможете працювати a.outбез ./жодного каталогу.
Тепер, коли у вас є інша програма де-небудь ще, скажімо, програма b.inна вашому робочому столі, все, що вам потрібно зробити: це ln -s /home/userName/Desktop/b.in /home/userName/bin, і ви зможете запустити її і без цього ./.
Примітка: завдяки коментарю @ Джо , коли ви робите резервні копії, символічні посилання потрібно обробляти спеціально. За замовчуванням їх
rsyncвзагалі не обробляє, тому при відновленні їх там немає.
Як зазначив Джордж у своїй відповіді, це допомагає вам зазначити, що ваше виконання файлу в поточному робочому каталозі ( pwd).
Я пам'ятаю, як давно дав це питання своєму старшому, він сказав, що я повинен додати .свій шлях, щоб коли я a.outце робив, він виглядав у поточному каталозі та виконує це. У цьому випадку мені не потрібно робити ./a.out.
Але особисто я рекомендував би проти цього. Зі мною цього не бувало, але якщо ви перебуваєте в каталозі чужорідних мереж або щось подібне, а шкідливий виконуваний файл, який називається, lsіснує там, то мати .на своєму шляху дуже погана ідея. Не те, що ви будете стикатися з цією проблемою дуже часто, просто кажучи.
.до $PATH. Дуже небезпечна ідея.
Окрім інших відповідей, ось істотна частина, з man bashякої це добре пояснюється:
ВИКОНАННЯ ВИКОНАННЯ
Після розбиття команди на слова, якщо це призводить до простого
команда та необов'язковий список аргументів, такі дії
прийнято.
Якщо ім'я команди не містить косої риски, оболонка намагається знайти
це. Якщо існує функція оболонки за цим ім'ям, ця функція є
викликається як описано вище у ФУНКЦІЙ. Якщо назва не відповідає а
Функція, оболонка шукає її у списку вбудованих оболонок. Якщо
знайдено відповідність, що викликається вбудований файл.
Якщо назва не є ні функцією оболонки, ні вбудованою, і не містить
косої риски, bash шукає кожен елемент PATH для пошуку каталогу -
заклик виконуваного файлу під цим іменем.
"./" має сенс, коли ви запускаєте відому вам та конкретну програму, наприклад, власну. Ця програма повинна бути присутня у вашому поточному каталозі. "./" не має сенсу, коли ви запускаєте стандартну команду, яка знаходиться десь у $ PATH. Команда "котра команда для запуску" повідомляє, де знаходиться команда для запуску в $ PATH.
$ gcc hello.c -o /path/to/someplace/hello
створить виконуваний файл у якомусь місці. Якщо це місце знаходиться на вашому шляху, ви зможете запустити файл. Ви можете скопіювати це, якщо ви хочете створити мітку для дії "складіть цей вихідний код за допомогою gcc та розмістіть виконуваний файл у певному місці, яке знаходиться на вашому шляху".
Я б запропонував вам створити новий каталог під назвою "testbin" або щось подібне і поставити його на свій шлях, щоб зберегти існуючі каталоги шляху.
./виключає непотрібний пошук шляху. ./змусити шукати лише в поточному каталозі. Якщо ми не дамо, ./то він буде шукати різні шляхи, встановлені в системі, наприклад /usr/bin, /usr/sbin/і т.д.
"./" означає, що ви хочете виконати файл у поточному каталозі його ярлик для введення всього шляху, наприклад:
[root@server ~]#/path/to/file/file.pl
те саме, що:
[root@server file]#./file.pl
у попередньому прикладі ви перейшли через каталог та його довідники до місця розташування файлу та використали "./" для запуску файлу у поточному каталозі.
той, що передує, " [root @ server ~] # / path / to / file / file.pl " також виконає файл, якщо ви лінуєтеся "cd" пройти до місця розташування файлу.
Це дуже просто і має безліч застосувань.
/usr/bin. Наприклад, встановлено Python 2.7, Python 2.6, але / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Якщо ви знаходитесь у шляху /usr/local/binта виконує Python, він завжди виконуватиме Python 2.7. Визначення .візьме виконуваний файл поточної папки.
.- завжди представляє виконання з поточного каталогу. І ..завжди означає виконання з попереднього каталогу.