Можно ли имитировать поведение «$ @» в оболочке unix с помощью обычной переменной?

#!/bin/sh

[email protected]

for i in $copy
do
  echo $i
done

Не буду делать то, что

for i in "[email protected]"
do
  echo $i
done

делает.copy="[email protected]" тоже не помогает, иfor i in "$copy"

Я мог бы использовать массивы, но массивы - это bashism, а не posix.

Можно ли имитировать поведение цитируемого"[email protected]" с обычной переменной? А если так?

#
Источник
  • 0
    В bash это массивы, в POSIX sh массивов не существует. Хотя для этого могут быть некоторые уловки
Codelisting
за 1 против

В bash вы можете использовать массивы:

copy=("[email protected]")
for i in "${copy[@]}"; do
    echo "$i"
done

В оболочке posix вы можете хранить правильно цитируемую переменную:

copy=$(printf "%q " "[email protected]")

Но тогда нужно как-то переоценить выражение. Вы можете использовать небезопасный eval :

eval set -- "$copy";
for i in "[email protected]"; do
     echo "$i"
done

Или, хммм ..., вы можете выполнить несколько вспомогательных функций, которые помогут с извлечением значений из копии и количества значений в копии, а затем перебрать их с помощью вспомогательной функции. Нравится:

get() { local pos=$2; eval set -- "$1"; eval printf %s \"\$$pos\"; };
no() { eval set -- "$1"; echo $#; }

for idx in $(seq $(no "$copy")); do
    i=$(get "$copy" "$idx")
    echo "$i"
done
  • 0
    Спасибо. К сожалению, подход printf не работает в тире, поэтому ни тире, ни команда не являются posix. Назначить аргументы позиционным параметрам через set -- "foo" "bar baz" - единственный способ, который я мог придумать.
  • 0
    Как это не удается? Можете быть более конкретными?
  • 0
    dash: 1: printf: %q: invalid directive (работает в bash)
  • 0
    Правильно, верно, верно,% q не в позиции posix. Думаю, тогда вам придется самому сбегать из струны. Возможно, у вас установлен / bin / printf из GNU coreutils, попробуйте подобрать его, а не встроенный. command printf "%q " "[email protected]"
Codelisting
Популярные категории
На заметку программисту