Создавать списки аргументов, содержащие пробелы

В bash можно избежать аргументов, содержащих пробелы.

foo "a string"

Это также работает для аргументов команды или функции:

bar() {
    foo "$@"
}

bar "a string"

Пока все хорошо, но что, если я хочу манипулировать аргументами перед вызовом foo?

Это не работает:

bar() {
    for arg in "$@"
    do
        args = "$args \"prefix $arg\""
    done

    # Everything looks good ...
    echo $args

    # ... but it isn't.
    foo $args

    # foo "$args" would just be silly
}

bar a b c

Итак, как вы составляете списки аргументов, если аргументы содержат пробелы?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
6 860
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Используйте массивы (один из скрытые особенности в Bash).

как именно? Я обновил свой вопрос, пытаясь использовать массив, но это не сработало.

tarsius 04.01.2009 23:14

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

JesperE 05.01.2009 02:01
Ответ принят как подходящий

Есть (как минимум) два способа сделать это:

  1. Используйте массив и расширьте его с помощью "${array[@]}":

    bar() {
        local i=0 args=()
        for arg in "$@"
        do
            args[$i] = "prefix $arg"
            ((++i))
        done
    
        foo "${args[@]}"
    }
    

    Итак, что мы узнали? "${array[@]}" относится к ${array[*]}, как "$@" для $*.

  2. Или, если вы не хотите использовать массивы, вам нужно использовать eval:

    bar() {
        local args=()
        for arg in "$@"
        do
            args = "$args \"prefix $arg\""
        done
    
        eval foo $args
    }
    

блин, надо было раньше приехать - мог бы избавить тебя от работы :)

user3850 05.01.2009 03:56

Вы можете использовать массивы так, как вы предлагаете, с небольшими изменениями. Строка, вызывающая foo, должна читать

 foo "${args[@]}"

У меня тоже была проблема с этим. Я писал сценарий bash для резервного копирования важных файлов на моем компьютере с Windows (cygwin). Я тоже пробовал использовать массив, но у меня остались проблемы. Не знаю, как именно я это исправил, но вот части моего кода, которые важны на случай, если он вам поможет.

WORK = "d:\Work Documents\*"
#   prompt and 7zip each file
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
do
    echo "Add $x to archive? (y/n)"
    read DO
    if [ "$DO" == "y" ]; then
        echo "compressing $x"
        7zip a $W_OUTPUT "$x"
    fi
    echo ""
done

Вот более короткая версия, не требующая использования числового индекса:

(пример: создание аргументов для команды find)

dir=$1
shift
for f in "$@" ; do
    args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
shift так не работает в Bash. Вместо этого должен быть dir=$1; shift.
Benjamin W. 11.10.2018 16:51

Действительно, исправил.

Jaen 12.10.2018 20:28

Другие вопросы по теме