GNU/Linux >> Linux の 問題 >  >> Linux

ファイルからロードされた文字列の変数をbashに展開させる

eval を使用した回答の多く そして echo ただし、複数行、シェル メタ文字のエスケープの試行、bash による展開を意図していないテンプレート内でのエスケープなど、さまざまな点で中断します。

私は同じ問題を抱えており、このシェル関数を作成しました。これは、私が知る限り、すべてを正しく処理します。これは、bash のコマンド置換規則により、テンプレートから末尾の改行のみを削除しますが、他のすべてがそのまま残っている限り、それが問題になることはありません.

apply_shell_expansion() {
    declare file="$1"
    declare data=$(< "$file")
    declare delimiter="__apply_shell_expansion_delimiter__"
    declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
    eval "$command"
}

たとえば、 parameters.cfg でこのように使用できます これは実際には変数を設定するだけのシェル スクリプトであり、template.txt これらの変数を使用するテンプレートです:

. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt

実際には、これを一種の軽量テンプレート システムとして使用しています。


私は、この質問に対する答えだと思うものに出くわしました:envsubst コマンド:

echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt

この出力:hello 42 world

ファイル destination.txt 内のデータで作業を続けたい場合 、これを次のようなファイルにプッシュします:

envsubst < source.txt > destination.txt

お使いのディストリビューションでまだ利用できない場合は、GNU パッケージ gettext にあります。 .

@Rockallite

  • 「$」の問題に対処するために、小さなラッパー スクリプトを作成しました。

(ところで、https://unix.stackexchange.com/a/294400/7088 で説明されている envsubst の「機能」があり、入力内の変数の一部のみを展開しますが、例外をエスケープする方がはるかに便利であることに同意します。)

これが私のスクリプトです:

#! /bin/bash
      ## -*-Shell-Script-*-
CmdName=${0##*/}
Usage="usage: $CmdName runs envsubst, but allows '\$' to  keep variables from
    being expanded.
  With option   -sl   '\$' keeps the back-slash.
  Default is to replace  '\$' with '$'
"

if [[ $1 = -h ]]  ;then echo -e >&2  "$Usage" ; exit 1 ;fi
if [[ $1 = -sl ]] ;then  sl='\'  ; shift ;fi

sed 's/\\\$/\${EnVsUbDolR}/g' |  EnVsUbDolR=$sl\$  envsubst  "[email protected]"

Linux
  1. SedでBash文字列変数への参照を使用しますか?

  2. Bash で、ファイルの各行の後に文字列を追加するにはどうすればよいですか?

  3. Bash シェル スクリプト内から Vim を開く

  1. Bash:改行なしでファイルの末尾に文字列を追加します

  2. Bashでファイルが空かどうかを確認するには?

  3. Linux で Bash を使用してすべての出力をファイルにリダイレクトしますか?

  1. DIFF 内の 1 つのファイルからの行の一覧表示

  2. Bash履歴ファイルから特定の行を削除します

  3. フォルダーから最も古いファイルを削除する Bash スクリプト