Как я могу использовать кавычные аргументы для select в bash?

Вопрос или проблема

Из команды я получаю некоторые аргументы, которые хочу предложить пользователю с помощью оператора select в bash в оболочке. Аргументы, переданные командой, могут содержать пробелы и, следовательно, защищены кавычками. Вот упрощенный пример.

Это работает, как и ожидалось:

select opt in a b "c d"
do
  echo $opt
  break
done

Вывод такой, как и ожидалось:

1) a
2) b
3) c d
#? 

Но с выводом из команды в переменной это не работает, как ожидалось:

opts="a b \"c d\""
select opt in $opts
do
  echo $opt
  break
done

Хотя $opts содержит то же самое, что и жестко закодированное во втором примере select, вывод отличается:

1) a
2) b
3) "c
4) d"
#?

Итак, дело не в том, что bash съел кавычки. Они сохраняются, но кавычки не охватывают аргумент так, как это было, когда я закодировал их жестко. Как я уже написал, я получаю аргументы как вывод из команды. Они могут содержать пробелы и, следовательно, уже защищены кавычками. Как мне передать их в одном целом к оператору ‘select’? Дело не в одиночных и двойных кавычках. С одиночными кавычками происходит то же самое:

1) a
2) b
3) 'c
4) d'
#?

Это решение должно помочь вам:

#!/bin/bash

opts=(a b "c d");

select opt in "${opts[@]}"
   do echo $opt; 
   break; 
done

Используйте массив:

opts=("a" "b" "c d");select opt in "${opts[@]}"; do echo $opt; break; done

Ответ или решение

Чтобы использовать аргументы с пробелами в команде select в bash, необходимо использовать массивы. Это позволит правильно обрабатывать кавычки и сохранить целостность строк, содержащих пробелы. Ниже приведено развернутое объяснение, основанное на вашем вопросе.

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

Когда вы передаете строку с аргументами, содержащими пробелы, в команду select, и эта строка сохранена в переменной, Bash не интерпретирует кавычки как границы аргументов. Это приводит к тому, что строка разбивается на отдельные элементы. Например, строка "c d" будет интерпретироваться как два отдельных аргумента 'c' и 'd', а не как один.

Решение проблемы с использованием массивов

Лучшим решением данной проблемы является использование массивов в bash. Массивы позволяют группировать элементы, которые могут содержать пробелы, и передавать их в команду select корректно.

Пример использования массива с select

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

#!/bin/bash

# Инициализация массива с элементами
opts=("a" "b" "c d")

# Использование select с массивом
select opt in "${opts[@]}"; do
    echo "Вы выбрали: $opt"
    break
done

В этом примере мы создаем массив opts, в который добавляем строки с кавычками, чтобы обеспечить их целостность. С помощью конструкции ${opts[@]} мы предоставляем команду select аргументы в необходимом формате.

Динамическое создание массива из команды

Если вы получаете аргументы из команды, вы можете использовать следующее:

#!/bin/bash

# Команда, которая генерирует вывод с аргументами
opts_output='a b "c d"'

# Создание массива из вывода команды
# Применяем eval для корректной интерпретации кавычек
eval "opts=($opts_output)"

# Использование select с массивом
select opt in "${opts[@]}"; do
    echo "Вы выбрали: $opt"
    break
done

Здесь мы используем eval, чтобы интерпретировать строку с кавычками и пробелами как массив. После этого конструкция select работает так же, как и в предыдущем случае.

Вывод

Использование массивов в bash значительно упрощает работу с аргументами, содержащими пробелы. Это позволяет избежать подтасовок данных и обеспечивает точность выбора пользователем. Надеюсь, это поможет вам правильно работать с командой select и аргументами, получаемыми из различных источников.

Оцените материал
Добавить комментарий

Капча загружается...