シェル-変数の内容をファイルに書き込む


95

変数(ここではと呼ばvarれます)の内容をファイルにコピーしたいと思います。

ファイルの名前は別の変数に格納されますdestfile

これを行うのに問題があります。これが私が試したものです:

cp $var $destfile

私もddコマンドで同じことを試しました...明らかに、シェルはそれ$varがディレクトリを参照していると考えていたため、ディレクトリが見つからないことがわかりました。

どうすればこれを回避できますか?


2
変数をどのように入力しているかを示す適切な形式のコードと、関連するすべてのエラーメッセージを表示されるとおりに投稿して、質問を改善してください。
トッドA.ジェイコブス

2
「変数の内容をディレクトリにコピーする」とはどういう意味ですか?ん$varファイル名またはファイルに書き込む必要があり、いくつかのテキストを指定しますか?テキストを指定している場合、このコンテンツを書き込むファイルの名前は何ですか?
jahroy

$ varには、コピーしたいテキストが含まれており、それを書き込む必要のあるファイルはユーザー定義であるため、そもそも変数を使用しているのはこのためです。
user1546083 2012

1
おそらく、誤解を招かないように$destdir名前を付ける必要があり$destfileます...この名前$destdirは、ファイルではなくディレクトリを指定していることを示しています。これにより、質問全体がまっすぐにわかりやすくなります。
jahroy

回答:


145

次のechoコマンドを使用します。

var="text to append";
destdir=/some/directory/path/filename

if [ -f "$destdir" ]
then 
    echo "$var" > "$destdir"
fi

ifテスト$destdirファイルを表します。

>ファイルを切り捨てた後、テキストを追加します。$varファイルの既存のコンテンツにテキストを追加するだけの場合は、>>代わりに次を使用します。

echo "$var" >> "$destdir"

このcpコマンドは、テキストをファイルに書き込むためではなく、ファイルを(ファイルに)コピーするために使用されます。


4
より多くの引用符を必要とする-今、変数の値内の空白のいずれかの実行を1つのスペースに変換されます、glob表現はなど、展開されます
チャールズダフィー

2
もう1つ、閉じ引用符と]inの間にスペースが必要"$destdir"]です。
Charles Duffy

3
echoまた、変数に末尾の改行を追加します。
Ben Dilts、2015年

6
$varisの場合-e text to append、これは失敗し、実際には次のように記述されません-e
Eric

1
echo $varは変数を展開するためにシェルに依存しているので、空白や特殊文字などではあまり機能しません。perl -e 'print($ENV{var})'代わりに使用でき、変数の値を正確に出力します。
ブレイクミッチェル

38

echovarようなものが含まれている場合-e、フラグとして解釈されるという問題があります。別のオプションはですがprintfprintf "$var" > "$destdir"変数内のエスケープ文字を展開するため、変数にバックスラッシュが含まれている場合、ファイルの内容は一致しません。ただし、printfフォーマット文字列ではエスケープとしてバックスラッシュのみを解釈するため、%sフォーマット指定子を使用して、正確な変数の内容を宛先ファイルに格納できます。

printf "%s" "$var" > "$destdir"


1
三重引用符やヒアドキュメントのように、変数文字列に改行がある場合にも、printfは役立ちます。echoは改行をうまく処理しません。
Beeflobill

@beeflobillは、「エコーが改行をうまく処理しない」ことを説明できますか。私が見た唯一のことは、エコーが改行を追加することです。これはecho "$var" > destfile間違いです。
SensorSmith 2018

@SensorSmith私の実験では、文字列に「\ n」が含まれていると、エコーによって改行文字が出力されることがわかりました。ただし、文字列に実際の改行文字が含まれている場合、エコーによって文字列は印刷されません。理由はわかりません。
Beeflobill

1
基本的に移植性(および信頼性)の問題。unix.stackexchange.com/a/65819… または、私たちの間の致命的な問題については、次の手順に進んでくださいprintf
user3342816

29

変数が次の場合、上記の回答はどれも機能しません。

  • で始まる -e
  • で始まる -n
  • で始まる -E
  • \後に続くn
  • その後に余分な改行を追加しないでください

そして、それらは任意の文字列の内容に依存することはできません。

bashでは、「ここの文字列」を次のように使用できます。

cat <<< "$var" > "$destdir"

以下のコメントで述べたように、@ Trebawaの回答(私の部屋と同じ部屋で作成!)を使用printfする方がより良いアプローチです。


5
私が知ることができることから、変数の最後に改行がないかどうかに関係なく、猫は常にファイルの最後に改行を挿入します(おそらく、これはほとんどの場合良いことですが)。printf関数を使用して答えは末尾の改行を挿入しないように思われます。
Ash

@Ashの別の利点printf上はcat、前者は常に外部バイナリよりも速く実行されるシェルの組み込みであることです。
ゲーザTörök

7

私があなたの言うことを正しく理解していれば$var、ファイルにコピーしたいでしょう(それが文字列の場合)。

echo $var > $destdir

これがその方法です。cpコマンドを使用すると、シェルは最初の引数をファイルまたはディレクトリの名前として解釈します。
jahroy

5
$var引用符で囲まないと、ファイルの内容が$ varの内容と100%一致しない場合があります。たとえば、RSAキーを含む変数を「エコー」すると、ファイルに無効なキーが表示されます。
srigi 2017

6
$varスペースが含まれている場合、または失敗する-e
Eric

1

「変数の内容をコピーする」と言うとき、その変数にはファイル名が含まれていますか、それともファイル名が含まれていますか?

私はあなたがファイルにコピーしたい内容$var含む質問を仮定しています:

$ echo "$var" > "$destdir"

これにより、$ varの値が$ destdirというファイルにエコーされます。引用符に注意してください。"$ var"を引用符で囲むことが非常に重要です。名前にスペースがある場合の「$ destdir」も同様です。追加するには:

$ echo "$var" >> "$destdir"

3
var含まれている場合は失敗します-e
Eric

1
最初の引数として二重ハイフンを渡すecho そのオプションリストを終了し、これ@Ericが提起した問題を解決しますecho -- "$var" >> "$destfile"
ゲーザTörök

1

上記のすべてが機能しますが、最初に発生する必要のない問題(エスケープと特殊文字)を回避する必要もあります。変数がシェルによって展開されたときの特殊文字。そもそも(変数展開)それをしないでください。展開せずに変数を直接使用します。

また、変数にシークレットが含まれていて、そのシークレットをファイルにコピーする場合は、シェルコマンドのトレース/コマンドエコーがシークレットを明らかにする可能性があるため、コマンドラインで展開しないでください。$varつまり、コマンドラインで使用するすべての回答は、変数の内容をシェルのトレースとロギングに公開することにより、潜在的なセキュリティリスクを持つ可能性があります。

これを使って:

printenv var >file

つまり、OP質問の場合:

printenv var >"$destfile"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.