Является ли оболочка переносимой для запуска команды в той же строке после назначения переменной?

Существует ли какой-либо стандарт, который охватывает переносимость запуска команды после назначения переменной в одной строке?

APPLE="cider" echo hi 

Насколько переносимым является что-то подобное? Где это будет работать, а где нет?

Также: мои сценарии оболочки начинаются с #! / Bin / sh, если это имеет значение.

  • Попытка запустить sh при подключении USB-камеры
  • Могу ли я создавать, устанавливать разрешения и записывать в файл с помощью одной команды Unix?
  • Итеративный поток управления в подчиненном скрипте
  • Быстрое изменение значений переменных среды в .bash_profile
  • lftp: войти, поместить файл в удаленный каталог и выйти из одной команды: правильная цитата
  • Удаление файлов с пробелами в именах
  • bash с использованием имени файла в качестве входного
  • Наложение текста на вкладку экрана только после загрузки оболочки
  • 4 Solutions collect form web for “Является ли оболочка переносимой для запуска команды в той же строке после назначения переменной?”

    Да, если вы используете оболочку, совместимую с POSIX.

    Из определения языка команд оболочки POSIX : (соответствующие точки выделены жирным шрифтом)

    «Простая команда» представляет собой последовательность необязательных назначений переменных и перенаправления в любой последовательности, необязательно сопровождаемых словами и перенаправлениями, которые завершаются оператором управления.

    Если требуется выполнить заданную простую команду (то есть, когда любая условная конструкция, такая как список AND-OR или оператор case, не обходила простую команду), все расширения, назначения и перенаправления должны выполняться из начало текста команды до конца:

    1. Слова, которые распознаются как переменные назначения или перенаправления в соответствии с правилами грамматики оболочки , сохраняются для обработки в шагах 3 и 4.

    2. Слова, которые не являются переменными назначениями или перенаправлениями, должны быть расширены. Если после их расширения остаются какие-либо поля, первое поле считается именем команды, а остальные поля являются аргументами для команды.

    3. Перенаправления должны выполняться, как описано в разделе Перенаправление .

    4. Каждое присваивание переменной должно быть расширено для расширения тильды, расширения параметров, подстановки команд, арифметического расширения и удаления цитат до назначения значения.

    В предыдущем списке порядок шагов 3 и 4 может быть отменен для обработки специальных встроенных утилит; см. Специальные встроенные утилиты .

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


    Кроме того, да #!/bin/sh имеет значение. Из определения POSIX sh :

    Утилита sh является интерпретатором языка команд, который должен выполнять команды, считанные из строки командной строки, стандартного ввода или указанного файла. Приложение должно гарантировать, что выполняемые команды выражаются в языке, описанном в Command Command Language .

    Поэтому в основном это говорит о том, что sh должен следовать правилам, которые мы рассмотрели выше.

    Итак, пока вы работаете на совместимой с POSIX ОС, вы в порядке.

    Чтобы ответить на второй вопрос, не полностью (количество оболочек – это мозг )

     % for sh in dash ksh93 mksh rc fish bash zsh csh tcsh jsh; do printf '%s\n' "$sh: $($sh -c 'var=foo echo hi')" done dash: hi ksh93: hi mksh: hi rc: hi fish: Unknown command “var=foo”. Did you mean “set var foo”? For information on assigning values to variables, see the help section on the set command by typing “help set” Standard input: var=foo echo hi ^ fish: bash: hi zsh: hi var=foo: Command not found. csh: var=foo: Command not found. tcsh: jsh: hi 

    В большинстве современных Korn-подобных раковин он будет работать. Но я не думаю, что это стандарт, я уверен, что кто-то вроде Стефана Чазеласа будет знать, насколько он распространен.

    Да, так было с первых дней sh

    http://www.freebsd.org/cgi/man.cgi?query=sh&apropos=0&sektion=0&manpath=Unix+Seventh+Edition&arch=default&format=html

     The environment for any simple-command may be augmented by prefixing it with one or more assignments to parameters. Thus these two lines are equivalent TERM=450 cmd args (export TERM; TERM=450; cmd args) 

    Учитывая команду в вашем примере, echo будет выполняться, но то, что происходит с $APPLE немного сложнее.

    Это верно, как указано в ответе @ Patrick здесь, что если оболочка вызывает процесс, все переменные, объявленные в командной строке, предшествующей ее вызову, указываются для экспорта в его среду. Кроме того, эти переменные также указываются для истечения срока действия с помощью вызванного процесса – так …

     unset var; var=val cmd; echo ${var-unset.} 

    … печать должна быть unset.

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

    Например, echo почти наверняка является встроенной утилитой оболочки – как и большинство оболочек, которые я знаю, чтобы обеспечить ее как таковую, – но она не является специальным встроенным POSIX. Таким образом, это в основном функция оболочки, которая должна эмулировать внешний исполняемый файл. Это, вероятно, сказано здесь более четко :

    Термин «встроенный» подразумевает, что оболочка может выполнить утилиту напрямую и не нуждается в ее поиске. Реализация может решить сделать любую утилиту встроенной; однако специальные встроенные утилиты, описанные здесь, отличаются от обычных встроенных утилит …

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

    Специальные встроенные утилиты в этом разделе не обязательно должны предоставляться способом, доступным через семейство функций exec, определенное в объеме системных интерфейсов POSIX.1-2008.

    Таким образом, переменная, объявленная в командной строке echo , гибнет с echo , но одна из объявленных в командной строке set сохраняется (хотя bash по умолчанию нарушает это правило) . То же самое верно, когда cmd является функцией оболочки:

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

    Linux и Unix - лучшая ОС в мире.