ここでドキュメントを処理するには、実行する前にスクリプトを展開してください。

ここでドキュメントを処理するには、実行する前にスクリプトを展開してください。

次のコードを考えてみましょう。

#!/bin/bash

var=$(
        cat <<-EOF
                Foo Bar
        EOF
)

echo "${var}"

これはタブで期待どおりに機能します。つまり、var変数は割り当てられたままです。Foo Bar

ただし、端末からこのファイルを削除するかcp、代わりにこのスクリプトの内容を別のファイルにコピーして貼り付ける状況を検討してください。scp

スクリプトにはタブの代わりにスペースが含まれているため、上記の同じスクリプトはタブの代わりにスペースが原因でエラーが発生します。

unexpandそれで、プログラムを進める前にスクリプトを修正したいと思います。

上記のコードをこのように修正してみました。

#!/bin/bash

unexpand --first-only $0 | sponge $0

var=$(
        cat <<-EOF
                Foo Bar
        EOF
)

echo "${var}"

これは2番目に効果があり、なぜこれが起こるのかを知っています。

しかし、このプログラムを最初に正しく実行したいと思います。タブの代わりにスペースを使用して最初に正しく実行されるようにスクリプトを変更するにはどうすればよいですか?

注:ファイルを2つの別々のスクリプトに分割すると、これを行うことができることがわかりますが、そうしたくありません。私はただ1つのスクリプトを持っていたいと思います。

答え1

実行中のスクリプトのソースコードを修正したいのは、コアクマの道だと思います。

(テストされていません)はどうですか?

#!/usr/bin/env bash

: ${TMPDIR='/usr/tmp'}
tmpfile=$(mktemp)
tooldir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [[ "$tooldir" != "$TMPDIR" ]]; then
    # copying first to get the same permissions on the tmp as on the original
    cp "$0" "$tmpfile" &&
    unexpand --first-only "$0" > "$tmpfile" &&
    "$tmpfile" "$@"
fi

var=$(
        cat <<-EOF
                Foo Bar
        EOF
)

echo "${var}"

関連情報