ファイルにエコーを適用できますが、シェルスクリプトソースではインデントを使用できますか? [コピー]

ファイルにエコーを適用できますが、シェルスクリプトソースではインデントを使用できますか? [コピー]

複数行の文字列をファイルに反映するネストされたインデントされたステートメントがある場合、元のシェル(私の場合はbash)のインデントがターゲットファイルに送信されます。

これを防ぐために、エコーされた出力からインデントを削除しましたが、ソースコードからインデントされたコード形式は失われます。例:

#! /bin/bash

function configure_default_vhost() {

    case "$2" in
        [--production])
              echo "<VirtualHost *:80>
# These lines are "breaking" out of the preffered indenting
redirect 404 /
ErrorDocument 404
</VirtualHost>
" > /etc/apache/sites-availabe/000-default.conf
    esac
}

私の目標は、できるだけ次のようなものを得ることです。

#! /bin/bash

function configure_default_vhost() {

    case "$2" in
        [--production])
              echo "<VirtualHost *:80>
                    # These lines are aligned with the preffered indenting
                    redirect 404 /
                    ErrorDocument 404
                    </VirtualHost>
                    " > /etc/apache/sites-availabe/000-default.conf
    esac
}

(注:この質問はHEREDOCに関する質問と重複する可能性があると記載されています。この質問に答えるべき正しい場所がどこにあるのかわからないので、ここに入力します(そうでない場合はお知らせください)。コードブロックのインデントに関するものです。heredocはこれを行ういくつかの方法の1つです。実際にheredocは私が望む解決策ではありません。

答え1

修飾子と一緒に「here-document」を使用できます-。タブを使用してインデントできます。echoからに切り替える必要がありますcat

cat <<-EOF > /etc/apache/sites-availabe/000-default.conf
        <VirtualHost *:80>
        redirect 404 /
        ErrorDocument 404     
        </VirtualHost>
EOF

あるいは、結果でタブを保持するには、HERE文書を前処理してsed4つのスペースにインデントすることもできます。

sed 's/^    //' <<EOF
....{
....(------)func () {
....(------)return
....(------)}
....}
EOF

スクリプトの書式設定方法を示すために、スペースとタブの.代わりにスペースとタブを使用しました。(------)

答え2

さまざまな方法:

  • printf '%s\n' > "$conf_file" \
      '<VirtualHost *:80>' \
      '  redirect 404 /' \
      '  ErrorDocument 404' \
      '</VirtualHost>'
    

    エスケープシーケンスを拡張するには、%s次のように置き換えます%b

    printf '%b\n' > "$conf_file" \
      '<VirtualHost *:80>' \
      '\tredirect 404 /' \
      '\tErrorDocument 404' \
      '</VirtualHost>'
    
  • @chorobaのcat <<- EOFアプローチただし、インデントはタブ文字でのみ行われ、すべて削除されます。

  • ...
      indent='
      '; cut -b "${#indent}-" << EOF > "$conf_file"
      <VirtualHost *:80>
        redirect 404 /
        ErrorDocument 404     
      </VirtualHost>
    EOF
    

    $indent(トリムするインデント文字数を保存するのはコツです(今回は、インデントにはタブ文字ではなく空白文字を使用する必要があります)。

  • ...
      cut -d'|' -f2- << EOF > "$conf_file"
      |echo "<VirtualHost *:80>
      |  redirect 404 /
      |  ErrorDocument 404     
      |</VirtualHost>
    EOF
    

    エスケープシーケンスは拡張されませんが、変数とコマンドの置換は拡張されます。EOFこれを防ぐために引用符を使用します(cut... << 'EOF'例:)。

  • 最初の行のインデントに基づいて切り捨てることもできます。

    show() {
      expand | awk 'NR == 1 {match($0, /^ */); l = RLENGTH + 1}
                    {print substr($0, l)}'
    }
    ...
      show << EOF > "$conf_file"
        <VirtualHost *:80>
          redirect 404 /
          ErrorDocument 404     
        </VirtualHost>
    EOF
    

答え3

echoスイッチと一緒に使用-e(バックスラッシュエスケープ解析可能):

#!/bin/bash

function configure_default_vhost() {
    conf_file="/etc/apache/sites-availabe/000-default.conf"
    case "$2" in
        [--production])
            # The ">" overwrites; the ">>" appends. 
            {
                echo -e "<VirtualHost *:80>"
                echo -e "\tredirect 404 /"
                echo -e "\tErrorDocument 404"
                echo -e "</VirtualHost>"
            } > "$conf_file"
    esac
}

関連情報