我需要/opt/nginx/conf.d/default.conf
通过 shell 脚本创建包含此内容的文件,如果该文件不存在则创建该文件:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
}
如何通过 shell 脚本编写多行内容?
我创建了目录
sudo mkdir -p /opt/nginx/conf.d
但我不知道如何写入文件。
答案1
摘要:用于>>
追加,用于[ -f file ]
测试。
尝试
if [ ! -f myfile ]
then
cat <<EOF > myfile
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name $server ;
root /usr/share/nginx/html;
}
EOF
fi
- 该语法
cat <<EOF
称为“这里的文档”。 $server
将被其值替换,如果未定义则为空。- 正如所指出的,您可以使用单引号
'EOF'
来避免替换 var(如果有)。 你也可以有多个回声(如果回声太多,维护起来可能会很痛苦)
echo "## foo.conf" > foo.conf echo param1=hello >> foo.conf echo param2=world >> foo.conf
前置
bash 中没有直接前置,要么使用临时文件
mv file file_tmp
cat new_content file_tmp > file
rm file_tmp
或编辑它
sed -i -e '1r new_file' -e 'wq' file
答案2
如果 /opt/nginx/conf.d/default.conf 文件确实不是存在,然后将静态字符串 print(f) 到文件中:
[ -f /opt/nginx/conf.d/default.conf ] || printf 'server {\n listen 80 default_server;\n listen [::]:80 default_server;\n server_name _;\n root /usr/share/nginx/html;\n}\n' > /opt/nginx/conf.d/default.conf
答案3
没有什么可以阻止您将换行符传递给echo
.在单引号或双引号内,在类似 Bourne 的 shell 中,换行符并不比任何其他字符更特殊
if [ ! -e "$file" ]; then
echo "server {
listen 80 default_server;
listen [::]:80 default_server;
server_name $server;
root /usr/share/nginx/html;
}" > "$file"
fi
请注意,我们不会将最后一个行分隔符添加为echo
自身。
如果要输出的文本可能包含反斜杠或以 开头-
,您可能需要改用printf
。要么像 for orprintf '%s\n' "text"
一样自动添加尾随换行符,然后在要输出的文本中添加换行符:echo
printf %s
if [ ! -e "$file" ]; then
printf %s "server {
listen 80 default_server;
listen [::]:80 default_server;
server_name $server;
root /usr/share/nginx/html;
}
" > "$file"
fi
您printf '%s\n' ...
还可以将多个参数传递给printf
将打印的每个参数并添加换行符,因此您可以执行以下操作:
new_lines=(
'server {'
' listen 80 default_server;'
' listen [::]:80 default_server;'
" server_name $server;"
' root /usr/share/nginx/html;'
'}'
)
[ -e "$file" ] || printf '%s\n' "${new_lines[@]}" > "$file"
您可以在其中决定每行使用的引用类型。
但请注意,如果没有传递任何参数,printf '%s\n'
仍然会打印一个空行。在 中zsh
,您可以print -rC1 --
改为使用。或者你可以定义一个:
println() {
[ "$#" -eq 0 ] || printf '%s\n' "$@"
}
辅助功能。
另请注意,如果该目标作为常规文件存在,则noclobber
POSIX shell 的选项会导致>
重定向运算符失败。
所以:
set -o noblobber # same as set -C
printf '%s\n' "$newcontent" > "$file"
如果它已经存在(作为常规文件),则确保$newcontent
不会写入$file
;如果它是一个设备(如符号链接/dev/null
)或目录或 fifo 等,$newcontent
仍会写入那里;因此,它不会完全避免 TOCTOU 竞争条件,因为 shell 仍然需要首先检查文件的类型)。
为了避免以无竞争的方式写入已经存在的文件,无论其类型如何,您可以使用zsh
它可以让您打开带有以下O_EXCL
标志的文件:
zmodload zsh/system
(sysopen -w -o excl -u 1 -- $file && print -r -- $newcontent > $file)
1 除非前面有双引号内的反斜杠。