Usando subshell para passar parâmetros com espaços

1

Eu tenho um shell chamado "name_value.sh" que eu quero passar parâmetros gerados em um sub-shell. Como posso garantir que o comando que recebe parâmetros do sub shell retenha espaços?

NOTA: Este é um exemplo extremamente simplificado do que estou fazendo. Por favor, leia completamente antes de responder.

Um exemplo simplificado é:

./name_value.sh $(echo "no_spaces"; echo "with spaces")

Onde name_value.sh se parece com isto:

#!/bin/bash
echo "Name=$1"
echo "Value=$2"

A saída desejada é:

Name=no_spaces
Value=with spaces

Este é um exemplo muito simplificado. Meu sub shell real é complexo, faz loops e gera dezenas de pares nome / valor que devem ser todos gerados ao mesmo tempo e passados para name_value.sh ao mesmo tempo. Eu também não tenho controle sobre o arquivo de shell que estou chamando.

Eu tentei ecoar com aspas e usando printf com "% q". Eu também considerei colocar os resultados do subshell em um array primeiro, mas também não consegui fazer isso funcionar. Eu preciso do shell pai para interpretar o sub shell como se o texto fosse inserido no lugar do sub shell.

    
por Tim 01.07.2017 / 22:39

2 respostas

4

Sim. Defina a variável IFS (que geralmente contém espaço, tabulação, nova linha) para ser apenas uma nova linha. Dessa forma, espaços e tabulações não serão usados para a divisão de palavras. Isso lhe dará a saída desejada.

IFS=$'\n'
set -o noglob # disable the second effect of leaving that
              # $(...) unquoted.
./name_value.sh $(echo "no_spaces"; echo "with spaces")

No entanto, o que eu gostaria de fazer é ler o script de stdin.

# name_value.sh
IFS= read -r name
IFS= read -r value
echo "Name=$name"
echo "Value=$value"

então

( echo no_spaces; echo with spaces ) | ./name_value.sh

Eu acho que essa abordagem é mais robusta.

    
por 02.07.2017 / 00:52
1

Quando você usa este comando

./name_value.sh $(echo "no_spaces"; echo "with spaces")

O bash executa os comandos "sub-shells" em "$ ()" e retorna a string de saída

Exemplo

Comando de entrada: ./name_value.sh $ (echo "no_spaces"; echo "com espaços")

Comando processado: ./name_value.sh no_spaces com espaços

O próximo passo é executar o script bash com três argumentos

Primeiro argumento: no_space

Segundo argumento: com

Terceiro argumento: espaços

Isto é o mesmo que chamar o script manualmente com o comando

./name_value.sh no_spaces with spaces

Para resolver o seu problema, você precisa inserir as aspas ao redor da chamada do sub-shell "$ ()"

Você precisa disso

./name_value.sh $(echo "no_spaces") "$(echo "with spaces")"

E o comando processado é

./name_value.sh no_spaces "with spaces"

E finalmente, sua saída será

Name=no_spaces
Value=with spaces
    
por 02.07.2017 / 02:12

Tags