Ниже приведен упрощенный сценарий bash parseArg.sh: -
#!/usr/bin/env bash
function parse(){
local propsFile=$1
echo "search file is : >$propsFile<"
while IFS='=' read -r packageKey packageValue;
do
echo "package value is >$packageValue<"
packageProcessor $packageValue
echo "---------------------------------------------------------"
done < "$propsFile"
}
function packageProcessor(){
echo "Total args : $#"
echo "All args value : >$@<"
for arg in "$@"
do
echo "$arg"
done
}
$@
Ниже приведен файл конфигурации repos.conf в том же каталоге: -
cm5-centos6.6 = "https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/ cm5-centos6.6 cm5/centos6.6 cm5/centos6.6 cm5-centos_6_6 "Cdh 5 for CentOS 6.6""
Когда я выполняю команду ниже в том же каталоге: -
sh parseArg.sh parse repos.conf
Я ожидал 6 аргументов, но это дает всего 10 аргументов. Ниже приведен фактический результат: -
search file is : >repos.conf<
package value is >"https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/ cm5-centos6.6 cm5/centos6.6 cm5/centos6.6 cm5-centos_6_6 "Cdh 5 for CentOS 6.6""<
Total args : 10
All args value : >"https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/ cm5-centos6.6 cm5/centos6.6 cm5/centos6.6 cm5-centos_6_6 "Cdh 5 for CentOS 6.6""<
"https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/
cm5-centos6.6
cm5/centos6.6
cm5/centos6.6
cm5-centos_6_6
"Cdh
5
for
CentOS
6.6""
---------------------------------------------------------
Ой, вам нужно найти более надежный формат файла конфигурации. Возможно, JSON или YAML.
@glennjackman: не уверен, насколько легко будет разбор yaml или json в bash. поэтому подумал об использовании файла конфигурации в этом формате.
Вам также необходимо проверить аргументы командной строки вашего скрипта: sh parseArg.sh rm -rf . на самом деле выполнит эту команду rm катастрофически: выдаст ошибку для "unknown subcomand: rm"





В функции parse переменная packageValue будет содержать единственную строку со значением:
"https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/ cm5-centos6.6 cm5/centos6.6 cm5/centos6.6 cm5-centos_6_6 "Cdh 5 for CentOS 6.6""
В значении переменной присутствуют начальные и конечные кавычки. Кавычки в этой строке - простые символы.
Единственный возможный способ разбить это на 6 отдельных компонентов - это использовать eval, чтобы заставить оболочку соблюдать «внутренние» кавычки. Сначала вам нужно удалить начальные и конечные кавычки:
tmp=${packageValue#\"}
packageValue=${tmp%\"}
packageProcessor "$packageValue"
Затем в функции packageProcessor вам нужно будет использовать eval для назначения строки как массива, но вам нужно временно отключить генерацию имени файла: вы хотите воспользоваться преимуществом разделения слов, но не подвергаться воздействию расширения пути.
set -f
eval "elements=($1)"
set +f
Теперь вы можете
declare -p elements
for arg in "${elements[@]}"; do echo "$arg"; done
Сказав все это, не делайте этого. Это по своей сути небезопасно. Используйте формат хранения данных, который не допускает небезопасных вызовов eval только для разделения ваших данных.
Если вы полностью контролируете содержимое этого файла конфигурации, используйте синтаксис оболочки, чтобы сделать его сценарием, из которого вы можете получить:
declare -a cm5_centos_6_6=(https://archive.cloudera.com/cm5/redhat/6/x86_64/cm/5/ cm5-centos6.6 cm5/centos6.6 cm5/centos6.6 cm5-centos_6_6 "Cdh 5 for CentOS 6.6")
команда "declare -p elements" генерирует вывод declare -a elements = '([0] = "archive.cloudera.com/cm5/redhat/6/x86_64/cm/ 5" [1] = "cm5-centos6.6" [2] = "cm5 / centos6.6" [3] = " cm5 / centos6.6 "[4] = " cm5-centos_6_6 "[5] = " Cdh 5 для CentOS 6.6 ") '. Есть ли способ отключить это.
удалите эту строку. Я добавил его для отладки и для демонстрации успеха.
Вы не прислушиваетесь к совету "не делайте этого", не так ли?
Согласно бизнес-требованиям, у нас есть только три параметра для хранения конфигурации (json, xml или простой файл конфигурации). Я не уверен, насколько сложно разбирать json или xml в bash. Итак, мы решили использовать простой файл конфигурации. На данный момент я не очень хорошо разбираюсь в питоне. Возможно, позже, когда мы включим python, мы переместим нашу конфигурацию из простой конфигурации в xml.
Пожалуйста, посмотрите: shellcheck.net