POSIX互換の方法でHEREDOCテキストをシェルスクリプト変数に入れようとしています。私はそう試みる:
#!/bin/sh
NEWLINE="
"
read_heredoc2() {
while IFS="$NEWLINE" read -r read_heredoc_line; do
echo "${read_heredoc_line}"
done
}
read_heredoc2_result="$(read_heredoc2 <<'HEREDOC'
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
)"
echo "${read_heredoc2_result}"
これにより、次のエラーが発生しました。
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ | | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
次の方法はうまくいきますが、ランダムな出力変数を使用するのがどれほど扱いにくいのか気にしません。
#!/bin/sh
NEWLINE="
"
read_heredoc1() {
read_heredoc_first=1
read_heredoc_result=""
while IFS="$NEWLINE" read -r read_heredoc_line; do
if [ ${read_heredoc_first} -eq 1 ]; then
read_heredoc_result="${read_heredoc_line}"
read_heredoc_first=0
else
read_heredoc_result="${read_heredoc_result}${NEWLINE}${read_heredoc_line}"
fi
done
}
read_heredoc1 <<'HEREDOC'
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
HEREDOC
echo "${read_heredoc_result}"
正しい出力:
_ _ _
| | | (_)
_ __ ___ _ _ _ __ | | __ _ ___ ___ ___ _ __ | |_ _ __ ___
| '_ ` _ \| | | | '_ \| |/ _` |/ __/ _ \/ _ \| '_ \| | | '_ \ / _ \
| | | | | | |_| | |_) | | (_| | (_| __/ (_) | | | | | | | | | __/
|_| |_| |_|\__, | .__/|_|\__,_|\___\___|\___/|_| |_|_|_|_| |_|\___|
__/ | |
|___/|_|
どんなアイデアがありますか?
ベストアンサー1
問題は、大きな打撃を受けた状態で、内部$( ... )
エスケープ(およびその他)シーケンスは、区切り文字自体にそのシーケンスがない場合でも構文解析されます。改行文字がエスケープされているため、二重線\
が表示されます。あなたが見ているのは実際にBashの解析問題です。他のシェルではこれを行いません。バックティックは以前のバージョンでも問題になる可能性があります。私は持っていますこれがBashのバグであることを確認しました。、今後のバージョンで修正される予定です。
少なくとも機能を大幅に簡素化できます。
func() {
res=$(cat)
}
func <<'HEREDOC'
...
HEREDOC
出力変数を選択するにはパラメータ化できます。
func() {
eval "$1"'=$(cat)'
}
func res<<'HEREDOC'
...
HEREDOC
または、次のことがないやや醜いものeval
:
{ res=$(cat) ; } <<'HEREDOC'
...
HEREDOC
必要なのは、後で変数を引き続き使用できるようにすることで{}
はありません。()
これをどれだけ頻繁に実行し、どの目的で実行するかに応じて、1つまたは他のオプションを好むことができます。最後は最も簡潔なワンタイムです。
が利用可能な場合、zsh
元のコマンドの置き換え+ heredocはそのまま機能しますが、これらの項目をさらに縮小することもできます。
x=$(<<'EOT'
...
EOT
)
Bashはこれをサポートしておらず、他のシェルにはあなたが持っている問題がないと思います。