Dav*_*her 16 shell bash binary
我有一个 bash 函数,它将文件作为参数,验证文件是否存在,然后将来自 stdin 的任何内容写入文件。天真的解决方案适用于文本,但我遇到了任意二进制数据的问题。
echo -n '' >| "$file" #Truncate the file
while read lines
do # Is there a better way to do this? I would like one...
echo $lines >> "$file"
done
Run Code Online (Sandbox Code Playgroud)
Cal*_*leb 15
您的方法是为它在任何分隔符 ( $IFS) 用于拆分读取的空间中写入的所有内容添加换行符。与其将其分解成换行符,不如将整个内容传递下去。您可以将上面的全部代码缩减为:
cat - > $file
Run Code Online (Sandbox Code Playgroud)
您不需要截断位,这将截断并将整个 STDIN 流写入其中。
编辑:如果您使用的是 zsh,则可以> $file代替 cat 使用。您正在重定向到一个文件并截断它,但是如果有任何东西在那里等待接受 STDIN,它将在那时被读取。我认为你可以用 bash 做这样的事情,但你必须设置一些特殊的模式。
要从字面上读取文本文件,请不要使用 plain read,它以两种方式处理输出:
read解释\为转义字符;用于read -r关闭此功能。read在 中的字符上拆分为单词$IFS;设置IFS为空字符串以关闭此功能。逐行处理文本文件的常用习惯用法是
while IFS= read -r line; do …
Run Code Online (Sandbox Code Playgroud)
有关此习语的解释,请参阅为什么while IFS= read如此频繁地使用,而不是IFS=; while read..?.
要从字面上写一个字符串,不要只使用 plain echo,它以两种方式处理字符串:
echo进程会转义反斜杠。(在 bash 上,这取决于是否xpg_echo设置了该选项。)-n或-e(确切的设置取决于外壳)。从字面上打印字符串的可移植方式是使用printf. (在 bash 中没有更好的方法,除非您知道您的输入看起来不像是 的选项echo。)使用第一种形式打印确切的字符串,如果要添加换行符,则使用第二种形式。
printf %s "$line"
printf '%s\n' "$line"
Run Code Online (Sandbox Code Playgroud)
这仅适用于处理text,因为:
您无法在 shell 中处理二进制数据,但大多数 unice 上的现代版本实用程序可以处理任意数据。要将所有输入传递到输出,请使用cat. 切线echo -n ''是一种复杂且不可移植的无所事事方式;echo -n将同样好(或不取决于外壳),并且:更简单且完全可移植。
: >| "$file"
cat >>"$file"
Run Code Online (Sandbox Code Playgroud)
或者,更简单,
cat >|"$file"
Run Code Online (Sandbox Code Playgroud)
在脚本中,您通常不需要使用,>|因为noclobber默认情况下是关闭的。