Bash-c с позиционными параметрами

Я не уверен, имеете ли Вы в виду - или --, таким образом, вот некоторая информация об обоих:

- стенография, которую некоторые программы принимают для обращения к STDIN, стандартный вход программы. Таким образом, в конвейере как echo foo | cat - (хотя - является на самом деле ненужным в этом экземпляре), cat получает "нечто" и новую строку как ее вход от STDIN.

-- указывает на конец аргументов. В программах, которые имеют дело с файлами, это часто означает, что то, что следует, только будет именами файлов и не, скажем, параметрами командной строки. В таком экземпляре это используется, чтобы попытаться обойти имена файлов, которые похожи на опции (например, если Вам назвали файл -e и программа также принимает a -e аргумент). Другой способ обойти это состоит в том, чтобы сделать что-то как command ./-e, который на самом деле более совместим через программы, поскольку это не требует, чтобы базовая программа реализовала обработку --.

15
27.08.2014, 13:36
2 ответа

Это дает вам возможность устанавливать/выбирать $0 при использовании встроенного скрипта. В противном случае $0 было бы просто bash.

Тогда вы можете сделать, например:

$ bash -c 'wc -c < "${1?}"' getlength foo
4
$ bash -c 'wc -c < "${1?}"' getlength bar
getlength: bar: No such file or directory
$ bash -c 'wc -c < "${1?}"' getlength
getlength: 1: parameter null or not set

Не все оболочки, которые использовались для этого. Панцирь Борна делал. Панцирь Korn (и Альмквист) выбрал первый параметр в $1. POSIX в конечном итоге пошла по пути Борна, поэтому ksh и ash производные вернулись к этому позже (подробнее об этом на http://www.in-ulm.de/~mascheck/various/find/#shell). Это означало, что долгое время для sh (которая в зависимости от системы была основана на оболочке Борна, Альмквиста или Корна), вы не знали, идет ли первый аргумент в $0 или $1, поэтому для переносимости нужно было делать что-то вроде:

sh -c 'echo foo in "$1"' foo foo

Или:

sh -c 'shift "$2"; echo txt files are "$@"' tentative-arg0 3 2 *.txt

К счастью, POSIX указал новое поведение, где первый аргумент уходит в $0, так что теперь мы можем переносить:

sh -c 'echo txt files are "$@"' meaningful-arg0-for-error *.txt
10
27.01.2020, 19:50

Это поведение определено POSIX :

sh -c имя_команды [аргумент ...]

Считывать команды из операнда command_string. Установите значение специального параметра 0 (см. Специальные параметры ) из значения операнда имя_команды и позиционных параметров ($ 1, $ 2 и т. Д.) Последовательно из оставшихся операндов аргументов.

Что касается того, почему вам нужно такое поведение: это сглаживает разрыв между скриптом и строкой -c . Вы можете напрямую конвертировать между ними без каких-либо изменений в поведении. Другие области полагаются на то, что они идентичны.

Это также соответствует тому, как в целом работают программные аргументы: в конечном итоге это сводится к вызову одной из функций exec , в которой первым предоставленным аргументом также является $ 0 , и одинаково часто этот аргумент совпадает с исполняемым файлом, который вы запускаете. Однако иногда вам нужна особая ценность, и другого способа получить ее просто не будет. Учитывая, что аргумент существует, он должен соответствовать чему-то, и пользователь должен иметь возможность установить, что это такое.

Эта последовательность (и, вероятно, историческая случайность) приводит к ситуации, которую вы обнаружите.

3
27.01.2020, 19:50

Теги

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