Чому в цей скрипт оболонки включені зворотні косої риски?


21

У своїй копії conda.shсценарію я бачу такі рядки:

if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
    SYSP=$(\dirname "${CONDA_EXE}")
else
    SYSP=$(\dirname "${CONDA_EXE}")
    SYSP=$(\dirname "${SYSP}")
fi

Мені цікаво, чому є зворотний нахил попереду dв dirname. Я не вірю, що це потрібно. Таке використання зворотних нахилів з'являється і в інших місцях у вихідному файлі. Чи є причина для цього, що я пропускаю?


Відповіді:


30

Зворотна коса придушить розширення псевдоніму, тобто він виконує оригінальну команду та гарантує, що версія псевдоніма не працює. Сценарії можуть несвідомо запускатися з розширенням псевдоніму, коли система встановила shopt -s expand_aliases(лише BASH) або якщо вона виконується за допомогою source.

./conda.sh          # usually no alias expansion (unless `shopt -s expand_aliases` in BASH)
source ./conda.sh   # alias expansion
. ./conda.sh        # alias expansion

Деякі sysadmins люблять вводити зворотну косу рису в усьому як запобіжний захід проти побічних ефектів псевдонімів, на всякий випадок, якщо вони були ненавмисно дедалі десь в іншому місці, і псевдонім розширюється, як було пояснено раніше. Наприклад, якщо система alias dirname='dirname -z'десь встановила це і умова дозволяє розширити псевдонім, тоді, на жаль, dirname -zзамість цього буде викликати скрипт, який намагається викликати dirname , що не було призначено для сценарію.

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

Крім того, commandзамість зворотної косої версії можна придушити псевдонім. Таким чином, замість цього \dirnameможна використовувати command dirname, що може виглядати читабельніше. (Для таких вбудованих команд cdслід builtinзамість цього використовувати ). Я віддаю перевагу цьому замість цього, оскільки він також обходить функцію з такою ж назвою, як і будь-які псевдоніми.


1
Також варто зазначити unalias -a, що видаляє всі псевдоніми.
Centimane

19
@Centimane Так, але не забудьте зробити, \unalias -aщоб придушити розширення псевдоніму
Бен С

Чи міг також написати sysadmin /usr/bin/dirname?
RonJohn

@RonJohn Так, він міг би мати в цьому конкретний випадок. Однак для деяких програм різні дистрибутиви розміщують їх у різних каталогах. Один екземпляр, який спадає на думку, - це /bin/edUbuntu vs /usr/bin/edна CentOS. Повний шлях робить сценарій менш портативним.
doneal24

@ doneal24, як щодо чогось подібного DIRNAME=$(which dirname), оскільки whichне бачить псевдонімів?
RonJohn

20

Якщо conda.shфайл призначений для отримання, то зворотні риски призначені для обходу псевдонімів. Bash зазвичай вимикає розширення псевдоніму для виконання сценарію, але для джерел файлів, які можуть працювати в інтерактивних оболонках, це не так. Так просто dirnameможна запустити псевдонім з ім'ям dirname, але \dirnameбуде пропускати розширення псевдоніму та запускати функцію чи команду з ім'ям dirname. (Хоча не лише косі риси, хоча будь-яке цитування буде).


5
Або command dirname.
Kusalananda

7
(на \command dirnameвсякий випадок, якщо хтось також зробив псевдонім command.): |
муру

Чому він обходить псевдоніми? Це функціональність - особливий випадок чогось, або його потрібно було жорстко закодувати в баш (тобто хак)?
extremeaxe5

@ extremeaxe5 bash не робить псевдоніму розширення, якщо (будь-яка частина) слово цитується.
муру

1
@ extremeaxe5, якщо ви запитуєте, чому ця функція взагалі існує, я не знаю. Саме в стандарті POSIX , однак: «ім'я команди слово [...] має бути розглянуто з метою визначити , чи є він без лапок , дійсне ім'я псевдоніма»
Мура
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.