コードを含むファイルを<< EOF >>する方法


100

コードをファイルに出力したいcat <<EOF >>

cat <<EOF >> brightup.sh
!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
   curr=$((curr+406));
   echo $curr  > /sys/class/backlight/intel_backlight/brightness;
fi
EOF

しかし、ファイル出力を確認すると、次のようになります。

!/bin/bash
curr=1634
if [  -lt 4477 ]; then
   curr=406;
   echo   > /sys/class/backlight/intel_backlight/brightness;
fi

一重引用符を付けてみましたが、出力には一重引用符も含まれています。この問題を回避するにはどうすればよいですか?


2
また、シバンを修正する必要があります。最初の行は文字通りで#!/bin/bashあり、それ以外の何もない必要があり#!ます。これが有効なシバン行になるものであり、その後に続くのはインタープリターへのパスです。
Tripleee、2015年

1
を見てman bash、を検索してくださいHere Documents。そこにすべての詳細。
香港

1
余談ですが、プロセス置換の最新の構文はではあり$(command)ません`command`。ファイルの内容を取得するため、bashは有する$(<file)
tripleee

回答:


158

最小限の変更が必要です。後のヒアドキュメント区切り文字を単一引用符で囲みます<<

cat <<'EOF' >> brightup.sh

または同等のバックスラッシュエスケープ:

cat <<\EOF >>brightup.sh

引用しないと、ヒアドキュメントは変数の置換を受け、バッククォートは評価されたように評価されます。

すべてではなく一部の値を展開する必要がある場合は、防止する値を個別にエスケープする必要があります。

cat <<EOF >>brightup.sh
#!/bin/sh
# Created on $(date # : <<-- this will be evaluated before cat;)
echo "\$HOME will not be evaluated because it is backslash-escaped"
EOF

生成されます

#!/bin/sh
# Created on Fri Feb 16 11:00:18 UTC 2018
echo "$HOME will not be evaluated because it is backslash-escaped"

@fedorquiで提案されているように、ここに関連セクションがありますman bash

ヒアドキュメント

このタイプのリダイレクトは、区切り文字(末尾の空白なし)のみを含む行が見つかるまで、現在のソースから入力を読み取るようにシェルに指示します。その時点までに読み取られたすべての行は、コマンドの標準入力として使用されます。

ヒアドキュメントの形式は次のとおりです。

      <<[-]word
              here-document
      delimiter

wordでは、パラメーター展開、コマンド置換、算術展開、またはパス名展開は実行されません。wordのいずれかの文字が引用符で囲まれている場合、区切り文字はwordの引用符の削除の結果であり、ヒアドキュメントの行は展開されません。 単語が引用符で囲まれていない場合、ヒアドキュメントのすべての行は、パラメータ展開、コマンド置換、および算術展開の対象になります。後者の場合、文字シーケンス\は無視され、\を使用して、文字\、$、および `を引用する必要があります。


1
ヒアドキュメントの変数の拡張を回避するにはどうすればよいですか?これの複製として。私が行ったように、私はBashのドキュメントリファレンスを含めただけで、異論はありません(訪問数が13,000回しかないため、担当者はほぼ100人になりましたので、非常に役に立ちます)。
fedorqui 'SO stop harming'

@fedorquiこの質問への回答を実際に移植したいのでしょうか?または、重複するマーキングを逆に切り替えることもできます。私は質問のスコアを見ただけで、回答のスコアはそれほど多くありませんでした。
Tripleee

うーん、それらをマージして、これをターゲットの質問として持つのはどうですか?重複した質問のタイトルは適切ですが、長すぎます。しかし、それはどういうわけか、最近かなりの注目を集めました(私は月にいくつかの賛成票をています)。
fedorqui 'SO stop harming'

@fedorquiマージの概念は好きですが、実際にそれが起こるのを見たことがありません。私が状況を正しく理解していれば、手間と複雑さがメリットをはるかに上回っているため、MODは単純なマージを単純に処理できません。私が1〜2回行ったのは、有用で賛成の回答を削除し、別の質問の下に再投稿することですが、この回避策はほとんどお勧めできません。
tripleee

いつ行う価値があるのか​​はわかりません。良い質問が投稿されたときに私がmodを行ったサイトで、以前から別の良い質問があることに気付かずにそれを行いました。私の90以上のスコアの回答を削除することは、その質問が孤立するため、良い計画とは思えません。
fedorqui 'SO stop harming'

20

または、EOFマーカーを使用して、展開が行われないように最初のマーカーを引用する必要があります。

#-----v---v------
cat <<'EOF' >> brightup.sh
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
   curr=$((curr+406));
   echo $curr  > /sys/class/backlight/intel_backlight/brightness;
fi
EOF

IHTH


1
私はあなたの投稿を編集しますが、安全のために#!/ bin / bashではなく#!/ bin / bashにすべきではありませんか?
Matthew Hoggan、2015年

@MatthewHoggan:うん、そうだね!それをキャッチしてくれてありがとう。私は今それを修正しています。
シェルター、2015年

16

これはうまくいくはずです。私はそれをテストしたところ、期待どおりに機能しました。拡張、置換、または何が行われてもいません。

cat <<< '
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
  curr=$((curr+406));
  echo $curr  > /sys/class/backlight/intel_backlight/brightness;
fi' > file # use overwrite mode so that you don't keep on appending the same script to that file over and over again, unless that's what you want. 

以下を使用しても機能します。

cat <<< ' > file
 ... code ...'

また、ヒアドキュメントを使用する場合<< EOF、置換や変数の展開などが行われることにも注意してください。したがって、次のようなことをしています:

cat << EOF > file
cd "$HOME"
echo "$PWD" # echo the current path
EOF

常に変数$HOMEとの展開になります$PWD。したがって、ホームディレクトリが/home/foobarで、現在のパスがの/home/foobar/bin場合、次のfileようになります。

cd "/home/foobar"
echo "/home/foobar/bin"

期待される代わりに:

cd "$HOME"
echo "$PWD"

2
単一引用符で囲まれたhere文字列には、明らかに単一引用符を含めることはできません。これは禁止事項になる可能性があります。OPの単純な例ではもちろんそうではありませんが、ここではドキュメントが単一引用符と二重引用符の両方を含める必要があるスクリプトがある場合の唯一の健全な回避策です。また、接線的に、ヒア文字列<<<はBash 3以降でのみ使用でき、他のシェルに移植できません。
Tripleee、2015年

<<<Zshでも利用可能
Alexej Magura

3
今日、ヒアドキュメントの冒頭にすぐにファイル名を付けることができることを学びました。@AlexejMagura、ありがとう!
chaseadamsio 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.