Важное различие между bash и zsh заключается в способе run2
вызовов run
, а именно в эффекте оставить $ 1
без цитирования.
run $ 1
применяет оператор «remove-if-empty» к $ 1
, то есть вызывает run
с первым аргументом, переданным в run2
, за исключением того, что если первый аргумент run2
был пуст (или если run2
был вызван без аргументов), то run
будет называется без аргументов. run $ 1
применяет оператор «split + glob» к $ 1
, то есть разбивает первый аргумент на run2
на фрагменты, разделенные пробелами¹, интерпретирует каждую часть как шаблон подстановки² и заменяет каждый шаблон подстановки, который соответствует одному или нескольким файлам, списком совпадений. Таким образом, run2 'ab' c
вызывает run
с аргументом ab
в zsh (аргумент передается без изменений), но вызывает run
с двумя аргументами a
и b
в bash (разделены на части, разделенные пробелами).
Мне нужен способ передать первый аргумент, который представляет собой строку с пробелами, и добавить этот стиль
$ @
в другую команду. напримерrun2 "a b" c
должен выдать1: a 2: b 3:
Ваше описание и ваш пример говорят разные вещи. Если вы хотите передать первый аргумент другой команде, используйте , запустите «$ 1»
, чтобы убедиться, что аргумент не разделен. Передача аргументов без изменений - это весь смысл "$ @"
.
Похоже, что вы действительно хотите разбить первый аргумент run2
на фрагменты, разделенные пробелами. В bash это можно сделать, отключив подстановочные знаки, а затем (предполагая, что IFS
не изменен по умолчанию), используя расширение без кавычек.
run2 () ( set -f; run $1; )
( echo "$ (somecommand)"
по сути эквивалентно запуску somecommand
в подоболочке, и похоже, что это то, что вы имели в виду, а не echo $ ( somecommand)
, который применяет split + glob к выходным данным команды, поэтому я удалил избыточную подстановку команды echo.)
В zsh вы можете использовать символ =
в параметре подстановка для выполнения разделения мира (без подстановки) для значения.
run2 () { run $=1; }
Синтаксис zsh несовместим с синтаксисом простого sh. Если вы хотите получить сценарий sh из zsh, вы можете использовать построение emulate
:
emulate sh -c '. myscript.sh'
Используйте emulate ksh
для имитации (некоторых функций) ksh. Это не эмулирует все функции bash, но позволяет использовать массивы.
¹ В целом, на основе значения IFS
.
² Если это не было отключено с помощью set -f
.