переменная env в /etc/ld.so.conf

Это зависит от того, как вы интерпретируете EAFP. В узком смысле это относится к использованию обработки исключений, для которой разработан Python, но это невозможно в некоторых языках, а в большинстве других и необычно, и настоятельно не рекомендуется. Однако в более широком смысле EAFP используется почти во всех языках программирования, особенно в сценариях оболочки.

Я предполагаю сценарии оболочки POSIX с небольшим акцентом на Bash . Примеры кода Python — Python 3.

Есть несколько способов попросить прощения вместо разрешения...

Python — это язык программирования, наиболее тесно связанный с дихотомией Посмотрите, прежде чем прыгнуть (LBYL)против Легче попросить прощения, чем разрешения (EAFP). В Python EAFP обычно означает разрешение возбуждения и перехвата исключения, а не проверку успешности операции перед ее попыткой, что было бы способом LBYL.

Но это не единственные две возможности; иногда можно попытаться выполнить операцию, которая не вызовет исключения в случае сбоя, но проверить, не сбой ли он произошел после попытки, и действовать по-разному в зависимости от результата. В нем не используется обработка исключений, поэтому с точки зрения Python кажется странным называть его EAFP... но на самом деле он имеет гораздо больше общего с EAFP, чем с LBYL. Это своего рода "EAFP", который очень распространен в сценариях оболочки.

Я думаю, будет полезно начать с примеров Python не только потому, что эти термины тесно связаны с культурой Python, но и потому, что EAFP, LBYL и «EAFP» без исключений могут быть продемонстрированы простым и понятным образом в Питон. Предположим, dимеет типdict:

# EAFP
try:
    print(d['foo'])
except KeyError:
    print('Not found.')
# LBYL
if 'foo' in d:
    print(d['foo'])
else:
    print('Not found.')
# Exceptionless "EAFP"
v = d.get('foo')
if v is None:
    print('Not found.')
else:
    print(v)

Проверкапредположение успешного выполнения команды оболочки :LBYL

Иногда мы используем простой LBYL в сценарии оболочки. Этот код, который поставляется в файле по умолчанию .bashrcDebian и Ubuntu, проверяет, содержит ли домашний каталог обычный файл с именем .bash_aliases. В противном случае не предпринимается никаких попыток его использования. Если это так, делается попытка получить его (для запуска каждой из его строк в качестве команды в текущей оболочке ). Хотя это зависит от состояния гонки , ошибки, которые могут возникнуть в этом случае, не наносят вреда, поэтому здесь это совершенно хороший выбор конструкции :

.

if [ -f ~/.bash_aliases ]; then
   . ~/.bash_aliases
fi

Предположим, однако, чточто вы хотели войти в подкаталог и выполнить операцию, которую вы не хотели бы случайно выполнять вне его. LBYL, по крайней мере, в чистом виде — плохой выбор. В этом примере операция представляет собой рекурсивное удаление, начиная с нескольких подкаталогов, соответствующих глобусу . (...Что несколько надумано, поскольку есть ряд других способов сделать это с разумной безопасностью. Если хотите, можете себе представить, что в этом каталоге есть еще что делать до и/или после запуска rm.)

# Don't do it this way!
if [ -d drafts ] && [ -x drafts ]; then  # BAD!
    cd drafts                            # BAD!
    rm -r foo*                           # BAD!
fi                                       # BAD!

Здесь я попытался проверить, удастся ли изменить каталог на drafts. Я проверил, существует ли он и является ли он каталогом(-d)и есть ли у меня права на его выполнение (-x). Для каталога в системе *nix разрешения на выполнение позволяют мне перейти в него. (Обычно.)

Проблема, помимо значительной сложности этого подхода, заключается в том, что я мог что-то упустить. Даже если ничего не изменится, действительно ли это гарантирует , что я смогу зайти в каталог? Я все проверил? [Я оставляю это упражнение читателю.]

Кроме того, даже если бы я все проверил и убедился, что каталог существует и доступен, ну... был. В этом случае состояние гонки действительно имеет значение. Если что-то изменится, и я не смогу зайти в каталог, а команда cdне сработает, то я удалю все драгоценные подкаталоги foo*, существующие рядом с drafts, вместо мусорных, содержащихся в нем. !

Запустить команду оболочки и проверить, успешно ли :EAFP?

Вы можете заметить поразительное сходство между этими соображениями и некоторыми причинами использования EAFP в Python:избежанием сложного или трудного для чтения кода и риском того, что условия могли измениться между проверкой и попыткой операции на основе проверки . Действительно, это намного проще и надежнее, чем показанный выше плохой способ :

.

if cd drafts; then
    rm -r foo*
fi

Вместо этого вы можете увидеть, что это написано таким образом, особенно если желательно, чтобы все это имело статус выхода с ошибкой, если условие(cd drafts)не выполняется:

cd drafts && rm -r foo*

Это не использует ничего похожего на обработку исключений. Но он не смотрит, прежде чем он прыгает. Он не проверяет наличие и доступность каталога drafts. Он просто пытается измениться в него. Затем после выполнения попытки он проверяет, удалось ли это, и отказывается от продолжения выполнения команды rm, если это не так.

Если под EAFP вы подразумеваете использование обработки исключений, то это не EAFP. Я понимаю, если вы отказываетесь от сравнения; в конце концов, этот подход существовал задолго до обработки исключений и распространен в таких языках, как C. Но он преследует некоторые из тех же целей и подходит во многих подобных ситуациях.

Конечно, на самом деле это более типичная форма прощения вместо разрешения в программировании. Python редок тем, что его не обескураживают --, а даже поощряют --генерировать исключения даже в совершенно обычных ситуациях.

А ловушки?

Я частично согласен с ответом jas -. Хотя на самом деле они не являются основным способом обработки ошибок (в смысле сбоя команды ), ловушки в сценариях оболочки в некоторой степени сопоставимы с обработкой исключений в Python.

Тем не менее,есть пара важных практических различий между ловушками в сценариях оболочки и исключениями в Python:

  • Программы Python постоянно используют исключения. Большинство сценариев оболочки редко используют ловушки, если вообще используют их.
  • Исключения Python обычно вызываются внутри текущего потока выполнения (, хотя это не всегда так ). Напротив, ловушки обычно запускаются асинхронно и в основном полезны для обработки асинхронных событий, таких как сигналы, отправленные из другого процесса или из системы (, например SIGINT, когда пользователь нажимает Ctrl + C ), хотя они не ограничиваются такими случаями.

Ловушки редко используются для управления потоком в сценариях оболочки и не так часто используются для обработки ошибок, в случаях, когда есть другие варианты. Чтобы запустить команду и узнать, сработала ли она, вы проверяете ее статус выхода . Как показано выше, управляющие структуры, такие как if, предоставляют способ сделать это (и , есть и другие).

0
10.04.2020, 13:01
1 ответ

/etc/ld.so.confи файлы в /etc/ld.so.conf.dне являются сценариями оболочки. Они просто содержат одно имя каталога в строке. Вы не можете использовать конструкции оболочки, такие как $TEST_PATH. Вы должны написать полный путь.

0
19.03.2021, 02:30

Теги

Похожие вопросы