'EOF'を使用し、変数をリテラルと見なすbashスクリプトに変数を渡す[クローズ]


9

このスクリプトでは、 "$ 1"が/ testファイルに保存されることになります。

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

真実は..私は保つ必要があります

'EOF'

引数($ 1)にドル記号が含まれているため、「EOF」として。

$ 1ではなく、その引数を保存する必要があります


1
「私の引数($1)にドル記号が含まれているためです。」最初のコマンドラインパラメータを参照する場合は除きます。 スクリプトが実行される前に、置換が行われました。 コマンドラインでエスケープする必要があります。
goldilocks 2014年

実行しているこのタスクについていくつかの関連する質問をしました。質問の進行は、何が起こっているのか本当に理解しておらず、おそらく最も簡単なアプローチを選択していないことを示しています。何をしようとしているのかを知らずに手助けするのは難しいので、全体的なタスクを明確に説明し、特定のツールを使用するように回答を制限しないで質問することをお勧めします。たとえば、「catドル記号を使用して保持したい」とは言わないでください。「を変更しhttpd.confて、<この設定>で<一部の設定>を変更したい」と言います。
Gilles「SO-邪悪なことをやめなさい」2014

@ギレス、私は最終的にpython経由で別のファイルに書き込み、次にbashスクリプトを使用して編集された元のファイルにそのファイルを書き込むことにしました。このプロセスははるかに簡単です。cat / temp_file> $ 1
user72685

@ギレス、私の質問が意味をなさない理由は、bashスクリプトが渡された変数を処理する方法が原因です。エスケープしなければならないものが多すぎますが、オンザフライでエンコードおよびデコードする機能はありません。
user72685 14年

@Gilles、私にとって少し理にかなっているのはbase64だけでしたが、bashスクリプトに渡すためにそれらのものをエンコードする必要があるのはなぜですか。バック
ティック

回答:


15

あなたの前の質問に続いていくつかの未解釈のテキストといくつかの解釈されたテキストの両方をファイルに入れたいようです。その場合は、2つの異なるcats(またはechos)を使用します。

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

ここでは、いくつかのことが行われています。最初に、ヒアドキュメントの構文<<。上記の最初のように、ターミネータ文字列に引用符を含めると、ヒアドキュメント全体が解釈されず、パラメータも置換もありません。上記の2番目のように引用符を使用しない場合、などの変数はその値に置き換えられ、コマンド置換がテキストに含まれます。置換が必要かどうかに基づいて、「EOF」文字列を引用するかどうかを選択します。 cat$1

両方置くために、cat私たちが使用している同じファイルにSを>> リダイレクトを手段がファイルに追加すること:二(およびそれ以降)リダイレクションのために。1つ目は、シングルを使用し>てファイルをクリアし、最初からやり直します。

場合でも、そのノートの変数が置換されている、その変数の値に追加のドル記号がされていない再置換自身:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

出力されます:

$bar

$barの値を代入せずに。

ただし、このスクリプト全体の引数に「$」を指定する場合は、コマンドラインでエスケープするか、全体を一重引用符で囲む必要があります。または、他の質問のようにコマンド置換を使用すると、ファイル全体の内容を直接入力できます。ファイルの内容にドル記号を含めます。そこで必ず置換文字列を引用してください:

oo.sh "$(cat myfile)"

myfileas のボディを取得し、必要に応じてor する$1ことができます。私の回答と同じ制限適用されます。コマンドライン引数の長さに制限があり、ファイルがそれより長くなる可能性がある場合は、別の方法を見つける必要があります。あなたはあなたのシステムの限界が何であるかを知ることができますcatechogetconf ARG_MAX


1

1つの変数をファイルに出力したいだけのように思えます。その場合、これはうまくいきます:

echo $1 >/test

これ/testは、通常のユーザーには通常書き込み権限がないルートディレクトリにあることに注意してください。

編集:コマンドラインでドル記号を含む文字列を引用する必要があることを覚えておいてください。これが置換が発生する場所であり、スクリプトは事後的にそれについて何も実行できません。


正解は今だと思います。+1
ゴルディロックス2014年

@MichaelHomerの答えははるかに完全で、私が忘れていたhereドキュメントに関する役立つ情報が含まれています。彼の答えは受け入れられるべきです(もちろん他の誰かがより良い答えを投稿しない限り)。
Tom Zych 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.