Variável não expandida dentro de outra variável bash

4

Estou lendo um arquivo csv no script bash da seguinte forma:

resource='/data/bscs/'
while IFS='|'read seqid fname fpath 
do
    echo "FILENO:         $seqid"
    echo "FILENAME:       $fname"
    echo "FILE_PATH:    $fpath"                    
done < "report.csv"

Meu arquivo csv tem os seguintes valores:

3 | sample1.txt | $ resource / operation /

Eu quero que o $ resource se expanda dentro de $ fname. Em vez disso, estou recebendo esta saída:

FILENO:         3
FILENAME:       sample1.txt
SOURCE PATH:    $resource/operation

Eu tentei o seguinte:

"${fpath}" $(echo $fpath)  

Como posso conseguir isso?

    
por Menon 02.04.2015 / 16:03

3 respostas

5

Você pode usar eval , mas o próximo mantenedor irá amaldiçoar seu nome. Você tentou apenas anexar a variável ao usar os dados analisados ou expandir a variável quando criar os dados?

Se o arquivo for criado dessa forma, você não pode usar apenas algumas técnicas [redigidas] para convencer o remetente a mudar suas maneiras perversas?

Se a mudança literal não for possível, você deve ter controle sobre quais variáveis são possíveis. Caso contrário, seu script estará vulnerável a todos os tipos de ataques de injeção, como entradas como 3|sample1.txt|$(rm --arr --eff /)/operation/ . Como você obviamente tem isso sob controle, você pode fazer algumas substituições literais de variáveis com seus valores caso a caso:

IFS='/' read -a pathnames <<< "$fpath"
for pathname in "${pathnames[@]}"
do
    if [ "${pathname::1}" = '$' ]
    then
        variable_name="${pathname:1}"
        printf '%s' "${!variable_name}"
    else
        printf '%s' "$pathname"
    fi
done

Com algum clichê adicional para adicionar barras entre nomes de caminho.

    
por 02.04.2015 / 16:15
4

Você também pode usar a expansão indireta de variáveis

$fpath='echo $resource/operation'
echo ${!fpath}

Isso expandirá o valor do recurso dentro do fpath.

    
por 02.04.2015 / 16:20
3

A expansão variável acontece apenas uma vez e não é recursiva.

Você mesmo pode expandir o valor:

resource=/data/bscs
fpath='$resource/operation'
echo ${fpath/'$resource'/$resource}

Note que isto é muito mais seguro que eval , porque todas as possíveis variáveis a serem substituídas devem estar listadas no código.

    
por 02.04.2015 / 16:18