POSIX тест і -а


9

Я перевірив мій сценарій з чекбашизмами і отримав такі попередження:

possible bashism in check_ssl_cert line 821 (test -a/-o):
if [ -n "${ALTNAMES}" -a -n "${COMMON_NAME}" ] ; then

У розділі 4.62.4 специфікації POSIX я знаходжу

первинний - первинний Виконує двійкові та результати первинних та первинних. Оператор -a має перевагу перед оператором -o.

Чому -aі -oвважається нестерпною?

Відповіді:


11

Справа не стільки в тому, що вона не є портативною, а в тому, що немає [впровадження, де вона є надійною, коли передано більше 4 аргументів.

Навіть у басі:

$ ALTNAMES='='  bash -c '[ -n "${ALTNAMES}" -a -n "${COMMON_NAME}" ]'
bash: line 0: [: too many arguments

У відповідному розділі зазначено:

> 4 аргументи :

Результати не визначені.

[OB XSI] [Опція запуску] У системах, що відповідають XSI, комбінації праймеріз та операторів оцінюються, використовуючи описані раніше правила пріоритетності та асоціативності. Крім того, бінарні порівнянні рядків '=' і "! =" Мають порівняльний рядок, який має вищий пріоритет, ніж будь-який одинарний первинний. [Варіант Кінець]

-aі його -oслід заборонити. Правильний спосіб - замість цього скористатися операторами &&та || оболонками :

if [ -n "$foo" ] && [ -n "$bar" ]; then

Я навіть вважаю це більш розбірливим.


Дякую, тож єдиним рішенням було б провести два тести? `if [-n" $ {ALTNAMES} "] && [-n" $ {COMMON_NAME}];
Маттео

3
Не єдиний, але, безумовно, найкращий і рекомендований як заміна на -aта-o
Stéphane Chazelas

Добре дякую (тільки я мав на увазі, що немає жодного способу провести єдиний тест ...).
Маттео

1
Так, ви можете зробити це [ "x$ALTNAMES" != x -a "x$COMMON_NAME" != x ](досі не визначено відповідно до POSIX, але портативний та надійний), або[ "${ALTNAMES:+x}${COMMON_NAME:+x}" = xx ]
Стефан Шазелас

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.