Редактировать: В основном переписано для ясности / усвояемости.Также я нашел один возможный ответ с использованием xargs.Я предпочитаю избегать внешней команды - я приму свой собственный ответ, только если нет альтернативы.
Я пытаюсь передать вывод local
(объявленные локальные переменные как разделитель новой строки key=value
список), возвращаясь к другому вызову local, но я сталкиваюсь с краем моего понимания цитирования / экранирования bash.
Значения легко обрабатывать без пробелов, но значения с внутренними пробелами вызывают проблемы с кавычками / разбиением.Проще показать, чем рассказать.Использование BASH_VERSION=4.4.23(1)-release
.Я буду идти по ступенькам;в конце поста есть более длинный сценарий воспроизведения.
- Определите некоторые локальные переменные и напечатайте их с помощью встроенной функции
local
: function export_locals(){
local one=1
local two=$(echo word1 word2)
local three=$(echo "word1 ain't word2")
local # aka local -p
}
, которая выводит некоторые варианты: one=1
three='word1 ain'\''t word2'
two='word1 word2'
- Вызовите
export_locals
из другой функции и передайте вывод другому вызову встроенного local
: function import_locals(){
local $(export_locals)
local
}
При использовании по умолчанию IFS
это не удастся.set -x
показывает причину: + local one=1 'three='\''word1' 'ain'\''\'\'''\''t' 'word2'\''' 'two='\''word1' 'word2'\'''
bash: local: `ain'\''t': not a valid identifier
bash: local: `word2'': not a valid identifier
bash: local: `word2'': not a valid identifier
Использование IFS=$'\n'
удерживает его от разбиения значений two
или three
, но они заканчиваются бонусными одинарными кавычками: + local one=1 'three='\''word1 ain'\''\'\'''\''t word2'\''' 'two='\''word1 word2'\'''
+ local
one=1
three=''\''word1 ain'\''\'\'''\''t word2'\'''
two=''\''word1 word2'\'''
В этот момент echo $two
будет выводить 'word1 word2'
Я ищу способы удалить лишние кавычки, которые не нарушат разбиение поля, не сломают более сложные входные данные, такие как $three
, и в идеале не полагаютсяпо внешним командам.Я также предпочитаю не связываться с IFS, но я не думаю, что это в картах.
Сценарий воспроизведения:
#!/usr/bin/env bash
set -x
# declare 2 vars and export them
function export_locals(){
local one=1
local two=$(echo word1 word2)
local three=$(echo "word1 ain't word2")
local # aka local -p
}
# insert vars into different local namespace
function import_locals(){
echo ${one:-nah} ${two:-nope} # nothing up my sleeve
local $(export_locals)
local
echo ${one:-nah} ${two:-nope} ${three:-nope}
}
function test_export_import_locals(){
export_locals # just to show what it prints
import_locals # bad attempt
IFS=$'\n' import_locals # good (ish?) attempt
}