Передача и анализ массива от одного сценария оболочки к другому - PullRequest
0 голосов
/ 18 июня 2020

Из-за ограничения в 9 параметров в скрипте моя цель - передать около 30 строк, объединенных в массив, от вызывающего скрипта (scriptA) до вызываемого скрипта (scriptB).

Мой scriptA выглядит примерно так это ...

#!/bin/bash
declare -a arr=( ab "c d" 123 "string with spaces" 456 )
. ./scriptB.sh "Task Name" "${arr[@]}"

Мой scriptB выглядит примерно так ...

#!/bin/bash
arg1="$1"
shift
arg2=("$@")
read -a arr1 <<< "$@"
j=0
for i in "${arr1[@]}"; do
#echo ${arr1[j]}
((j++))
case "$j" in
"1")
param1="${i//(}"
echo "$j=$param1"
;;
"2")
param2="${i}"
echo "$j=$param2"
;;
"3")
param3="${i}"
echo "$j=$param3"
;;
"4")
param4="${i}"
echo "$j=$param4"
;;
"5")
param5="${i//)}"
echo "$j=$param5"
;;
esac
done

ВЫВОД:

1=ab
2=c
3=d
4=123
5=string

Проблема:

1. I see parenthesis ( and ) gets added to the string which I have to strip them out
2. I see an array element (with spaces) though quoted under double quotes get to interpreted as separate elements by spaces.

1 Ответ

0 голосов
/ 22 июня 2020

read -a arr1 <<< "$@"

неверно. "$@" здесь равно "$*", а затем read разделит ввод на пробелы (пробелы, табуляции и новые строки), а также интерпретирует \ косые черты и присваивает результат массиву arr1. Не забудьте использовать read -r.

Do:

arr1=("$@")

для присвоения массиву. Затем вы можете напечатать:

for ((i=1;i<${#arr1};++i)); do 
   printf "%d=%s\n" "$i" "${arr1[$i]}"
done

из 9 параметров в скрипте, моя цель - передать около 30 строк, объединенных в массив, из вызывающего скрипта (scriptA)

Хорошо. Но "${arr[@]}" в любом случае передает несколько аргументов. Если вы хотите передать массив как строку, передайте его как строку (обратите внимание, что eval - это зло ):

arr=( ab "c d" 123 "string with spaces" 456 )
./scriptB.sh "Task Name" "$(declare -p arr)"
# Then inside scriptB.sh, re-evaulate parameter 2:
eval "$2" # assigns to arr

Обратите внимание, что scriptB.sh получен в вашем примере, поэтому передача аргументов .... все равно не имеет смысла.

Я вижу элемент массива (с пробелами), хотя в двойных кавычках он интерпретируется как отдельные элементы пробелами

Да, потому что вы интерпретировали контент с помощью read, который разделяет ввод на символы в IFS, который по умолчанию установлен на пробел, табуляцию и новую строку. Вы можете распечатать аргументы в отдельных строках и соответственно изменить IFS:

IFS=$'\n' read -r -a arr1 < <(printf "%s\n" "$@")

или даже использовать строку с нулевым завершением:

mapfile -t -d '' arr1 < <(printf "%s\0" "$@")

, но это просто причудливые и бесполезные способы записи arr1=("$@").

Обратите внимание, что в фрагменте кода arg2 является массивом.

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