Я хочу иметь возможность заполнять элементы массива произвольными строками, т. е. строки, которые могут содержать \ и пробелы, например. Я написал это:
#!/bin/bash
function populate_array () {
if [ "$#" -gt 0 ] ; then
# Enter array w/ elements as argument of executable
array=($@)
n=$#
else
# Invoke executable with no arg,, enter array element later
read -p "Enter array elements separated by spaces: " -a array
n=${#array[@]}
fi
printf "%d array elements \n" "$n"
}
populate_array "$@"
while (("$n" > 0)) # while [ "$n" -gt 0 ] ALSO WORKS
do
printf "%s \n" "${array[$n-1]}"
n=$n-1
done
exit 0
Блок while предназначен только для проверки элементов массива. Функция достаточно проста, чтобы хорошо работать для аргументов, которые не содержат space или \. Не иначе.
Попытка ввода аргументов исполняемому файлу как:
#!> bash [scriptname] lkl1239 343.4l 3,344 (34) "lklk lkl" lkaa\ lkc
Я бы хотел увидеть 6 аргументов:
lkl1239
343.4l
3,344
(34)
lklk lkl
lkaa lkc
Вместо этого я получаю бросок:
Для ( => bash: синтаксическая ошибка около неожиданного токена `34 'Пространство, содержащее строки, интерпретируется как строки x + 1, где x - количество непересекающихся пробелов ни в начале, ни в конец строки. Баш игнорирует то, что происходит после первого появления \Как это делается?
Просто укажите $@, как вы уже правильно сделали в вызове функции:
array=("$@")
Как man bash ставит:
"$@" эквивалентно [ f5]Специальные символы, как правило, должны быть экранированы с помощью обратного слэша, например:
$ array-script.sh lkl1239 343.4l 3,344 \(34\) "lklk lkl" lkaa\ lkc
6 array elements
lkaa lkc
lklk lkl
(34)
3,344
343.4l
lkl1239
Скобки обрабатываются оболочкой как метасимволы, поэтому необходимо экранировать. Обратная косая черта в lkaa \ lkc уже ускользает от промежутка между lkaa и lkc, поэтому эти две строки рассматриваются как одна. То же, что и с cd /home/user/bin/NAME\ WITH\ SPACE
И из man bash:
metacharacter
A character that, when unquoted, separates words. One of the following:
| & ; ( ) < > space tab
вы можете попробовать, поставив ниже в верхней части скрипта
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
и
IFS=$SAVEIFS
в нижней части скрипта