Виконуючи програму 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. Визначення .
візьме виконуваний файл поточної папки.
.
- завжди представляє виконання з поточного каталогу. І ..
завжди означає виконання з попереднього каталогу.