Использование внутреннего разделителя полей при захвате данных массива из команды в скрипте bash
Когда я запускаю команду
git cherry origin/Server_Dev
в моем репозитории git я получаю список коммитов вида
+ 95b117c39869a810595f1e169c64e728d2d7443d
+ e126f1b996ecf1d2a8cf744c74daa92cce338123
+ 869169a6cb0bbe8f1922838798580a1e74ec3884
+ 667819b617c88bd886dc2001f612b5c7a4d396c3
+ fd41328a84b0a127affa6fe4328c93e933de378c
+ cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
Это хорошая вещь.
Теперь я хочу выполнить эту команду из скрипта bash и записать вывод в массив, используя следующий код:
commit_hashes=(`git cherry origin/Dev`)
echo ${commit_hashes[@]}
который дает следующий вывод:
+ 95b117c39869a810595f1e169c64e728d2d7443d + e126f1b996ecf1d2a8cf744c74daa92cce338123 + 869169a6cb0bbe8f1922838798580a1e74ec3884 + 667819b617c88bd886dc2001f612b5c7a4d396c3 + fd41328a84b0a127affa6fe432
8c93e933de378c + cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
Это не хорошая вещь
Мой список коммитов возвращается в виде строки, которую я должен сначала разбить, прежде чем использовать. После некоторых поисков я обнаружил, что если я добавлю IFS=""
в моем сценарии до сбора данных, мои проблемы будут решены.
Поэтому я отредактировал свой код для чтения
IFS=""
commit_hashes=(`git cherry origin/Dev`)
echo ${commit_hashes[@]}
какой выход
+ 95b117c39869a810595f1e169c64e728d2d7443d
+ e126f1b996ecf1d2a8cf744c74daa92cce338123
+ 869169a6cb0bbe8f1922838798580a1e74ec3884
+ 667819b617c88bd886dc2001f612b5c7a4d396c3
+ fd41328a84b0a127affa6fe4328c93e933de378c
+ cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
Это полностью положило конец моему чувству реальности.
Мне нравится знать, почему вещи делают то, что они делают, поэтому после еще нескольких поисков я обнаружил, что это называется Internal Field Separator
и он используется в системах Unix интерпретаторами команд для определения, где разбивать шаблоны на токены.
Это я понимаю
Что я не понимаю, так это
- Почему установка этой переменной в пустую строку позволила ей обрабатывать данные моего массива в здравом смысле.
- Почему я должен был установить это в первую очередь, вместо того, чтобы интерпретатор осознавал, что он имеет дело с данными массива и обрабатывает их соответствующим образом.
- Какой эффект при установке Внутреннего разделителя полей на пустую строку будет иметь место в общей схеме вещей, поскольку по умолчанию он содержит символы для пробела, табуляции и новой строки.
Была бы признательна за помощь в обдумывании этих трех пунктов.
1 ответ
Смотри man bash / Arrays. Все хорошо с вашим массивом. Когда вы делаете
echo ${commit_hashes[@]}
echo показывает все элементы массива в одной строке, как сказано. Когда ты сказал
for i in `seq 10`; do
echo ${commit_hashes[$i]}
done
вы увидите, что отображается только одна запись в строке.
Когда вы установите IFS=
в пустую строку, однако, результат git cherry
не разбивается на несколько значений. Вся строка, включая символы новой строки, присваивается первому элементу массива. если ты
echo ${commit_hashes[0]}
во втором случае вы увидите, что эхо показывает все выходные строки.