Гарантирует ли POSIX пути к любым стандартным утилитам?

Вам действительно не нужен sed для этого, если вы используете bash.

s="org.gnome.Terminal.Legacy.Keybindings"
g=${s//.//}/

Прочтите раздел Parameter Expansion справочной страницы bash (${parameter/pattern/string}), там также есть много других полезных вещей.

С помощью sed вы также можете указать несколько выражений, иногда это более читабельно.

s="org.gnome.Terminal.Legacy.Keybindings"
g=$(sed -e 'y,.,/,' -e 's,$,/,' <<<$s)

Обратите внимание, что с командой yвам не нужно экранировать команду ., yпринимает буквенные символы.

22
03.09.2019, 16:31
2 ответа

Нет, главным образом по той причине, что не требуется, чтобы системы соответствовали по умолчанию или соответствовали только стандарту POSIX (исключение любого другого стандарта ).

Например, Solaris (, сертифицированная совместимая система ), выбрала обратную совместимость для своих утилит в /bin, что объясняет, почему они ведут себя загадочным образом, и предоставляют совместимые с POSIX -утилиты в разных местах (/usr/xpg4/bin. ], /usr/xpg6/bin... для различных версий XPG (, теперь объединенных со стандартом POSIX ), которые фактически являются частью необязательных компонентов в Solaris ).

Даже shне обязательно будет в /bin. В Solaris /bin/shраньше была оболочкой Bourne (, поэтому она не совместима с POSIX )до Solaris 10, а теперь ksh93 в Solaris 11 (все еще не полностью совместима с POSIX, но на практике в большей степени, чем /usr/xpg4/bin/sh).

Из С,вы можете использовать exec*p()и предположить, что вы находитесь в среде POSIX (, в частности, в отношении PATHпеременной среды ).

Вы также можете установить переменную окружения PATH

#define _POSIX_C_SOURCE=200809L /* before any #include */
...
confstr(_CS_PATH, buf, sizeof(buf)); /* maybe append the original
                                      * PATH if need be */
setenv("PATH", buf, 1);
exec*p("ps"...);

Или вы можете определить во время сборки путь к утилитам POSIX, которые вы хотите запустить (, имея в виду, что в некоторых системах, таких как системы GNU, вам потребуются дополнительные шаги, такие как установка POSIXLY_CORRECTпеременной для обеспечения соответствия ).

Вы также можете попробовать:

execlp("sh", "sh", "-c", "PATH=`getconf PATH`${PATH+:$PATH};export PATH;"
                         "unset IFS;shift \"$1\";"
                         "exec ${1+\"$@\"}", "2", "1", "ps", "-A"...);

В надежде, что в $PATHесть sh, что он похож на -Борна, что также есть getconfи что он подходит для интересующей вас версии POSIX.

35
27.01.2020, 19:42

На самом деле, я бы скорее ответилда. POSIX гарантирует:

  1. Что там есть абсолютный путь к соответствующей стандартам -версии каждой указанной утилиты,
  2. И что вы должны иметь возможность найти этот абсолютный путь и выполнить эту утилиту.

Хотя не обязательно гарантируется, что каждая утилита будет находиться в определенном каталоге во всех системах (/bin/ps), всегда гарантируется возможность быть найденной в системном PATH по умолчанию в виде исполняемого файла..

Действительно, единственный стандартный -указанный в стандарте способ сделать это — это (в C )через unistd.h's _CS _PATH или в оболочке через комбинация утилит commandи getconf, т. е. PATH="$(command -p getconf PATH)" command -v psвсегда должна возвращать уникальный абсолютный путь POSIX -ps, поставляемый в конкретной системе. То есть, несмотря на то, что реализация -определяет , какие пути включены в системную переменную PATH по умолчанию, эти утилиты должны всегда быть доступными, уникальными и совместимыми в одном из пути, указанные в нем.

См. :< unistd.h >, команда .

4
27.01.2020, 19:42

Теги

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