Порядок виконуваних файлів розпочався в баш


14

Якщо я виконую testкоманду в bash, test(оцінює умовне вираження), вбудована утиліта запускається:

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

Однак, як видно з результатів type -a testвище, testу каталозі / usr / local / bin є ще один і в каталозі / usr / bin. Як впорядковуються виконувані файли, тобто завжди вподобані вбудовані команди, а тоді решта команд залежать від порядку каталогу у змінній $ PATH? Крім того, чи можна змінити порядок розпочатого виконуваного файлу, наприклад, якщо я набираю test, тоді / usr / bin / test запускається замість bash-buildin test?


Ви можете вказати повний шлях при виклику команди, напр., /usr/bin/test -f "$file"...
jasonwryan

@jasonwryan Я знаю про це, але мене просто цікавить, чи є спосіб змінити розпочатий порядок виконання файлів.
Мартін

Відповіді:


25

Найвищий пріоритет - псевдонім bash, потім спеціальні вбудовані (тільки в режимі POSIX), потім функції, потім вбудовані, потім пошук у $PATH.

Щоб виконати вбудований, використовуйте builtin test.
Щоб виконати зовнішню програму, використовувати явний шлях: /bin/test.
Щоб ігнорувати функції та псевдоніми, використовуйте command test.
Щоб обійти лише псевдонім, використовуйте \testабо будь-який інший тип розширення.

Можливо відключити / включити вбудований за допомогою enable test.

(Оновлено згідно з коментарями нижче)
(Виправлена ​​помилкова редакція адміністратора, що disableвбудований bash - насправді існує лише enable)


1
@ 1_CR gena2x має рацію. У моїй відповіді пропущено спеціальні вбудовані елементи, які мають перевагу над функціями відповідно до POSIX (хоча деякі оболонки не сумісні; bash відповідає лише в режимі POSIX).
Жил "ТАК - перестань бути злим"

1
Схожі зміни: псевдоніми відключені , коли ви цитуєте команду (або будь-який його частини), як і в \testабо 'test'або tes't'.
Джон Кугельман

2
Це не повна картина. Здається, що будь-який тип розширення (у посібнику з bash, вся підміна, розширення в тильді і так зване розширення ) вимикає псевдоніми. Я намагався.
gena2x

1
Цитата зі сторінки Баш людини: .. «Перше слово кожної простої команди, якщо без лапок, перевіряється , щоб побачити , якщо він має псевдонім Якщо це так, то слово замінюється текстом псевдоніма Символи /, $, лапки, і =і будь-які метахарактеристики оболонки або цитуючі символи, перелічені вище, не можуть відображатися в псевдонімі. "
Джон Кугельман

2
+1 для натяків на те, щоб допомогти мені знайти джерело цієї інформації: вона знаходиться на сторінці bash man, під розділом КОМАНДА ВИКОНАННЯ, другий та третій абзаци.
twan163

6

Вбудовані команди завжди віддають перевагу зовнішнім командам. Обґрунтування полягає в тому, що вбудована команда швидша (і в кількох випадках, таких як cdабо , лише вбудована команда може мати бажаний ефект).test -o BASH_OPTION

Іноді зовнішня команда може мати можливості, яких вбудована оболонка не має. У такому випадку ви можете викликати зовнішню команду, вказавши явний шлях (тобто містить косу рису) (це обходить будь-яке занепокоєння щодо порядку введення $PATH). Якщо ви не хочете жорстко кодувати зовнішній шлях, але ви хочете запобігти використанню вбудованого, ви можете використовувати "$(type -P test)"(примітку капіталу P) в bash, "$(whence -p test)"ksh та =testzsh. Ще один спосіб змусити використовувати зовнішню команду - використовувати commandвбудований ( command -p test …) або пройти через envутиліту ( env test …).

У zsh ви можете відключити вбудовану програму за допомогою disable test. Це постійне значення (для поточної оболонки або допоміжної оболонки), поки вбудований модуль не буде відновлено enable test. У bash ви можете зробити те ж саме, enable -n testщоб відключити та enable testповторно ввімкнути.

Ви можете використовувати псевдонім або функцію для примушування до виконання іншої команди, наприклад alias test=/usr/bin/testабо test () { /usr/bin/test "$@"; }. Якщо у вас є такий псевдонім, ви можете запобігти його використанню, цитуючи будь-яку його частину, наприклад \test, виконувати звичайну функцію / вбудований / зовнішній пошук. Зауважте, що залежно від оболонки та її параметрів, визначення псевдоніму функції може бути розширено при зчитуванні функції або при її виконанні. Якщо ви визначили функцію, ви можете використовувати command testдля запобігання пошуку функцій, а також пошуку псевдоніму (тому тут testвбудований файл буде викликатись, якщо не вимкнено).


хіба envтут не буде доречно?
Стівен Пенні

Отже, якщо оболонка працює від BusyBox, чи інші, як правило, зовнішні команди того ж BusyBox розглядаються як внутрішні? напр., я додав повну dfдо PATH на першій позиції, видалив псевдонім 'df', which dfпоказує / opt / bin / df, але df
run

@papo which dfне обов'язково показує, що dfпрацює. unix.stackexchange.com/questions/85249/…
перестань бути злом"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.