web-dev-qa-db-ja.com

変数が別の変数bash内で拡張されていません

次のようにbashスクリプトでcsvファイルを読み取っています。

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

私のcsvファイルには次の値があります:

3 | sample1.txt | $ resource/operation /

$ resourceを$ fname内に展開させます。代わりに、私はこの出力を取得しています:

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

私は以下を試しました:

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

どうすればこれを達成できますか?

6
Menon

eval を使用できますが、次のメンテナがあなたの名前を呪います。解析されたデータを使用するときに変数を追加するだけ、またはデータを作成するときに変数を展開してみましたか

その方法でファイルが作成された場合、いくつかの[編集済み]テクニックを使用して、作成者に邪悪な方法を変更するように説得することはできませんか?

変更が文字通り不可能である場合、あなたはどの変数が可能であるかを制御する必要があります。そうでない場合、スクリプトは、3|sample1.txt|$(rm --arr --eff /)/operation/などの入力など、あらゆる種類のインジェクション攻撃に対して脆弱です。あなたが明らかに制御下にあるので、ケースバイケースで変数をその値でリテラル置換することができます:

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

パス名の間にスラッシュを追加するための追加のボイラープレート。

6
l0b0

変数の展開は一度だけ行われ、再帰的ではありません。

自分で値を拡張できます:

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

これはevalよりはるかに安全であることに注意してください。置換する可能性のあるすべての変数をコードにリストする必要があるためです。

3
choroba