вывод кавычек / экранирования из локальной встроенной системы для передачи обратно только встроенным? - PullRequest
0 голосов
/ 07 мая 2019

Редактировать: В основном переписано для ясности / усвояемости.Также я нашел один возможный ответ с использованием xargs.Я предпочитаю избегать внешней команды - я приму свой собственный ответ, только если нет альтернативы.

Я пытаюсь передать вывод local (объявленные локальные переменные как разделитель новой строки key=value список), возвращаясь к другому вызову local, но я сталкиваюсь с краем моего понимания цитирования / экранирования bash.

Значения легко обрабатывать без пробелов, но значения с внутренними пробелами вызывают проблемы с кавычками / разбиением.Проще показать, чем рассказать.Использование BASH_VERSION=4.4.23(1)-release.Я буду идти по ступенькам;в конце поста есть более длинный сценарий воспроизведения.

  1. Определите некоторые локальные переменные и напечатайте их с помощью встроенной функции 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'
    
  2. Вызовите 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
}

1 Ответ

0 голосов
/ 08 мая 2019

В итоге я перешел в приемлемое решение с помощью внешней команды xargs, которую я представил ниже.

function import_locals(){
    local $(export_locals_xargs)
    local
}
function export_locals_xargs(){
    local one=1
    local two=$(echo word1 word2)
    local three=$(echo "word1 ain't word2")
    local | xargs printf "%s\n"
}
IFS=$'\n' import_locals

Будет выведено:

one=1
three='word1 ain'\''t word2'
two='word1 word2'

Повтор отдельных выходных переменных:

one: 1
two: word1 word2
three: word1 ain't word2
...