2016-06-17 5 views
10

Я хочу позвонить/bin/sh и использовать параметр -c для передачи команды '+ x' , т. е. выполнить программу с именем «+ x», имя которой начинается со знака «плюс».Обработка аргументов '-' в аргументах/bin/sh: POSIX против реализаций с помощью Bash/Dash/FreeBSD sh

Поскольку «+ x» интерпретируется как/bin/sh как опция (в частности, отключить опцию «x»),/bin/sh следует запретить интерпретировать его как опцию. Я получаю следующие различные результаты в зависимости от/bin/ш я использую:

(1) Первый вариант:

/bin/sh -c -- +x 

Использование тире и Баш на Linux: Команда + х выполняется.

Использование команды FreeBSD sh: выполняется команда - и задана опция + x.

(2) Второй вариант:

/bin/sh -c +x 

Использование тире и Баш на Linux: + х опция установлена, и есть ошибка, потому что опция -c отсутствует аргумент.

Использование команды FreeBSD sh: выполняется команда + x.

(3) Третий вариант:

/bin/sh -c - +x 

Использование тире и Bash на Linux: + X выполняется.

Использование команды FreeBSD sh: выполняется команда - и устанавливается опция + x.

(4) Четвертый вариант: (ДОБАВЛЕНО как предложено в комментариях)

/bin/sh -c+x 

Использование тире и Баш на Linux: Invalid/Illegal опцию '+'

Использование ш в FreeBSD: Bad -c опцион


Мой вопрос: что предлагает POSIX?

Я читаю спецификации POSIX для ш здесь: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html

Цитирование из него: «. Один дефис должен рассматриваться в качестве первого операнда, а затем игнорируется Если оба„-“и„-“являются заданные в качестве аргументов, или если другие операнды предшествуют одному дефису, результаты не определены ».

Я не уверен, относится ли эта цитата к одной тире, помещенной сразу после '-c'.

Итак, какой из них справа, Dash/Bash или FreeBSD? Или, если оба правильные, потому что POSIX позволяет обоим, как сделать это переносимо?

+1

Для Хорошая мера: что делает '/ bin/sh -c + x'? –

+0

@bishop Я так не думаю. '/ bin/sh' будет просто видеть аргументы' -c' и '+ x', поэтому' getopt() 'следует рассматривать как'/bin/sh -c + x'. –

+1

Ссылка на POSIX для 'sh' находится здесь: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html –

ответ

6

Ответ на вопрос «Что назначает Posix» уже присутствует в OP. Но важная особенность стандарта Posix не подсвечивается: опция -c не принимает аргумента.

Вы можете увидеть это в Обзоре:

sh -c [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]... 
     command_string [command_name [argument...]] 

Что -c флаг делает вызвать позиционные параметры («операнды») должны быть истолкованы по-разному. Без -c, они интерпретируются как [command_file [argument...]]:

sh [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]... 
    [command_file [argument...]] 

Это, кстати, почему sh -c+x ошибка. Если -c принял аргумент, тогда было бы законным включать аргумент в то же слово.

Таким образом, чтобы ответить на более конкретные вопросы:

  1. Posix говорит: «Один дефис должен рассматриваться в качестве первого операнда, а затем игнорируется ...». Это относится к - сразу после -c?

    A: Да, это так. -c - это полный вариант, поэтому - является операндом. В отличие от этого, - в -o - не будет рассматриваться как операнд. (Это будет рассматриваться как недопустимое имя опции.)

  2. Какой из них справа, Dash/Bash или FreeBSD?

    A: В этом случае Dash and Bash совместимы с Posix, а FreeBSD - нет. Оболочка FreeBSD значительно предшествует текущей спецификации Posix, и я не считаю, что она когда-либо утверждала, что она полностью соответствует любой спецификации Posix.

  3. Как можно использовать sh для запуска команды, имя которой начинается с +?

    A: Я думаю, что следующий будет работать на любой оболочке:

    sh -c " +x" 
    

    " +x" не будет признан в качестве опции, поскольку он не начинается с + или - и sh -c вызывает операнд анализируется как команда оболочки, поэтому ведущие пробелы будут игнорироваться. У меня нет копии FreeBSD's ash, чтобы играть с этого момента, поэтому я приветствую исправления.

    Или вы можете использовать простую команду соединения:

    sh -c "{ +x; }" 
    

    Возможно ясным (предполагая, что оболочку вы используете реализуете Posix стандарта предопределённых command) является:

    sh -c "command +x" 
    
+0

Typo in answer: '" + x "' -> '" + x "'. – Kusalananda

+0

То же самое: я думал, что 'sh -c '+ x'' будет работать, но у меня нет FreeBSD для тестирования, и комментарий @ Rhymoid отговорил меня. Я думаю, что это к лучшему, потому что '' + x'' кажется сложным (и, возможно, хрупким). Команда 'sh -c '+ x'' кажется более понятной для намерения, будучи переносной. – bishop

+0

Если пространство слишком странное, 'sh -c ':; + x'' также должен работать. – melpomene