Shell-将变量内容写入文件


95

我想将变量(这里称为var)的内容复制到文件中。

文件名存储在另一个变量中destfile

我在执行此操作时遇到问题。这是我尝试过的:

cp $var $destfile

我还用dd命令尝试了相同的操作...显然,shell认为这$var是指目录,因此告诉我找不到该目录。

我该如何解决?


2
请通过发布一些格式正确的代码来改善您的问题,这些代码可以显示如何填充变量,以及所有相关错误消息的显示形式。
Todd A. Jacobs

2
“将变量的内容复制到目录”是什么意思?是否$var指定文件名或应写入文件的某些文本?如果指定文本,那么您要向其写入此内容的文件的名称是什么?
jahroy 2012年

$ var包含我要复制的文本,应该将其写入的文件是用户定义的,因此,我首先使用变量的原因。
user1546083 2012年

1
也许$destdir应该命名,$destfile以免引起误解...该名称$destdir表明它指定的是目录而不是文件。这将使您的整个问题变得直截了当且易于理解。
jahroy 2012年

Answers:


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
需要更多报价-现在,变量的值中的空白任何运行将被转换为单一的空间,水珠表达式将扩大,等等
查尔斯·达菲

2
另一件事-您需要在右引号和]in 之间留一个空格"$destdir"]
查尔斯·达菲

3
echo还向变量添加尾随换行符。
Ben Dilts

6
如果$var-e text to append,则会失败,并且实际上不会写成-e
Eric

1
因为echo $var依赖于外壳程序来扩展变量,所以它对空白和特殊字符之类的东西并不是很有效。您可以改用perl -e 'print($ENV{var})'它,它会精确输出变量的值。
布莱克·米切尔

38

echo有一个问题,如果var包含类似的东西-e,它将被解释为一个标志。另一个选项是printf,但printf "$var" > "$destdir"会扩展变量中的所有转义字符,因此,如果变量包含反斜杠,则文件内容将不匹配。但是,由于printf在格式字符串中仅将反斜杠解释为转义符,因此可以使用%s格式说明符将确切的变量内容存储到目标文件中:

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


1
如果变量字符串中有换行符(例如,三重引号或heredoc),则printf也很好。echo不能很好地处理换行符。
Beeflobill

@beeflobill您能解释一下“ echo如何不能很好地处理换行符”。我唯一看到的是echo添加了换行符。哪有echo "$var" > destfile错。
SensorSmith

@SensorSmith在我的实验中,我看到当字符串具有“ \ n”时,该回显将打印换行符。但是,如果字符串具有实际的换行符,则echo不会将其打印出来。我不知道为什么
Beeflobill

1
基本上是可移植性(和可靠性)问题。unix.stackexchange.com/a/65819… 还是对我们当中的致命人员来说:printf更好,继续前进。
user3342816

29

如果您的变数,上述答案均无效:

  • 以。。开始 -e
  • 以。。开始 -n
  • 以。。开始 -E
  • 包含一个\后跟一个n
  • 不应在其后附加多余的换行符

因此,不能依靠它们来获取任意字符串内容。

在bash中,您可以将“ here字符串”用作:

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

如下面的评论所述,使用@Trebawa的答案(与我的房间相同!)printf是一种更好的方法。


5
据我所知,cat总是在文件末尾插入换行符,而不管变量末尾没有换行符(尽管在大多数情况下这都是一件好事)。使用printf答案似乎是避免插入尾随换行符。
Ash Ash,

@Ash的另一个优点printfcat是,前者是一个shell内置的,这将始终执行不是外部的二进制更快。
盖佐Török

7

如果我理解正确,那么您想复制$var到一个文件中(如果它是一个字符串)。

echo $var > $destdir

这是完成的方式。使用该cp命令将使Shell将第一个参数解释为文件或目录的名称。
jahroy 2012年

5
如果不使用$var引号引起来,则在某些情况下文件的内容与$ var的内容不是100%相等。例如,当“回显”包含RSA密钥的var时,您在文件中得到无效的密钥。
srigi

6
如果$var包含空格或-e
Eric 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

以上所有工作均有效,但还必须解决首先不需要发生的问题(转义符和特殊字符):外壳扩展变量时的特殊字符。只是首先不要做(可变扩展)。直接使用变量,无需扩展。

另外,如果您的变量包含机密,并且您想将该机密复制到文件中,则可能不希望在命令行中进行扩展,因为shell命令的跟踪/命令回显可能会泄露机密。就是说,$var在命令行中使用的所有答案都可能通过将变量内容暴露给外壳的跟踪和日志记录而具有潜在的安全风险。

用这个:

printenv var >file

这就是说,在OP问题中:

printenv var >"$destfile"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.