Linux 在cat<;之后使用sed<';EOT&x27;在生成的脚本中只替换一个变量

Linux 在cat<;之后使用sed<';EOT&x27;在生成的脚本中只替换一个变量,linux,bash,sed,heredoc,Linux,Bash,Sed,Heredoc,我正在为ubuntu 14中的php fpm编译、安装和部署构建一个脚本。有一次,我不得不使用这个主脚本生成另一个文件。生成的文件是一个脚本,应该包含除一个未展开的变量外的所有变量 所以我从cat/etc/init.d/php-$PhpBuildVer-fpm开始 #! /垃圾箱/垃圾箱 ###开始初始化信息 #提供:php-$PhpBuildVer fpm #所需开始时间:$all #所需站点:$all #默认开始:2 3 4 5 #默认停止:0 1 6 #简短描述:启动php-$PhpBui

我正在为ubuntu 14中的php fpm编译、安装和部署构建一个脚本。有一次,我不得不使用这个主脚本生成另一个文件。生成的文件是一个脚本,应该包含除一个未展开的变量外的所有变量

所以我从
cat/etc/init.d/php-$PhpBuildVer-fpm开始
#! /垃圾箱/垃圾箱
###开始初始化信息
#提供:php-$PhpBuildVer fpm
#所需开始时间:$all
#所需站点:$all
#默认开始:2 3 4 5
#默认停止:0 1 6
#简短描述:启动php-$PhpBuildVer fpm
#描述:启动PHP FastCGI进程管理器守护程序
###结束初始化信息
php_fpm_BIN=/opt/php-$PhpBuildVer/sbin/php fpm
php_fpm_CONF=/opt/php-$PhpBuildVer/etc/php-fpm.CONF
php_fpm_PID=/opt/php-$PhpBuildVer/var/run/php-fpm.PID
php_opts=“--fpm config$php_fpm_CONF”
等待\u pid(){
try=0
而测试$try-lt 35;执行
案件“$1”
“已创建”)
如果[-f“$2”];则
try=''
打破
fi
;;
“已删除”)
如果[!-f“$2”];则
try=''
打破
fi
;;
以撒
echo-n。
try=`expr$try+1`
睡眠1
完成
}
案件“$1”
开始)
echo-n“启动php fpm”
$php\u fpm\u BIN$php\u选项
如果[“$?”!=0];然后
回显“失败”
出口1
fi
等待\u创建的\u pid$php\u fpm\u pid
如果[-n“$try”];然后
回显“失败”
出口1
其他的
回音“完成”
fi
;;
(停止)
echo-n“优雅地关闭php fpm”
如果[!-r$php\u fpm\u PID];然后
echo“警告,未找到pid文件-php fpm未运行?”
出口1
fi
kill-QUIT`cat$php\u fpm\u PID`
等待pid已删除$php\u fpm\u pid
如果[-n“$try”];然后
echo“失败。使用强制退出”
出口1
其他的
回音“完成”
回音“完成”
fi
;;
(强制退出)
echo-n“终止php fpm”
如果[!-r$php\u fpm\u PID];然后
echo“警告,未找到pid文件-php fpm未运行?”
出口1
fi
kill-术语'cat$php\u fpm\u PID`
等待pid已删除$php\u fpm\u pid
如果[-n“$try”];然后
回显“失败”
出口1
其他的
回音“完成”
fi
;;
重新启动)
0美元一站
零美元起价
;;
重新加载)
echo-n“重新加载服务php fpm”
如果[!-r$php\u fpm\u PID];然后
echo“警告,未找到pid文件-php fpm未运行?”
出口1
fi
kill-USR2`cat$php\u fpm\u PID`
回音“完成”
;;
*)
echo“用法:$0{start | stop | force quit | restart | reload}”
出口1
;;
以撒
EOF
#这里应该替换变量。
chmod 755/etc/init.d/php-$PhpBuildVer fpm
... #删除了脚本中不相关的部分

我不是100%确定,但我认为您需要的是:

sed -i 's/\$PhpBuildVer/'"$PhpBuildVer"'/' /etc/init.d/php-$PhpBuildVer-fpm
实际上,您可以在bash中将两个引用的表达式放在彼此相邻的位置。例如,
echo'12'”34“'56'
将输出
123456
。在本例中,第一个
\$PhpBuildVer
位于
'
中,因此它可以进行字面匹配,第二个位于
'
中,以便将其展开

(但也许你应该考虑使用模板文件和PHP,或者(BLATANT插头) *构建脚本,而不是将所有文本内联到主脚本中。;)

使用
cat…>>而不是
cat…>
表示您将附加到脚本,除非您在未显示的代码中的某个地方将其添加到
rm

编辑2如果
$PhpBuildVer
中包含替换文本中
sed
解释的任何字符,则可能需要对其进行转义:

repl_text="$(sed -e 's/[\/&]/\\&/g' <<<"$PhpBuildVer")"
sed -i 's/\$PhpBuildVer/'"$repl_text"'/' /etc/init.d/php-$PhpBuildVer-fpm
我得到的结果是:

test-42.sh before substitution is:
---------
#!/bin/sh
# Provides: test-$f.sh
echo 'Hello, world!'
---------
(注意文字
$f

(现在,
$f
已消失,并已替换为其值,
42

perlpp
示例 由于*我目前是的维护者,我也将给您举一个例子:)。在我称为
test.template
的模板文件中,我将:

#!/bin/sh
# Provides: test-<?= $S{ver} ?>.sh
echo 'Hello, world!'
(使用转义引号将它们传递给perl)并获得输出:

#!/bin/sh
# Provides: test-7.1.10.sh
echo 'Hello, world!'
:)

  • perlpp的任何
    -s name=\'value\'
    命令行参数都会创建
    $s{name}
    ,您可以在模板中引用该参数
  • 打印表达式的值
    expr
  • 因此,
    输出命令行中为
    名称
    给定的

我不是100%确定,但我认为您需要的是:

sed -i 's/\$PhpBuildVer/'"$PhpBuildVer"'/' /etc/init.d/php-$PhpBuildVer-fpm
实际上,您可以在bash中将两个引用的表达式放在彼此相邻的位置。例如,
echo'12'”34“'56'
将输出
123456
。在这种情况下,第一个
\$PhpBuildVer
位于
'
中,因此它可以按字面意思匹配,第二个位于
'
中,因此它将
test-42.sh before substitution is:
---------
#!/bin/sh
# Provides: test-$f.sh
echo 'Hello, world!'
---------
test-42.sh after substitution is:
---------
#!/bin/sh
# Provides: test-42.sh
echo 'Hello, world!'
---------
#!/bin/sh
# Provides: test-<?= $S{ver} ?>.sh
echo 'Hello, world!'
perlpp -s ver=\'7.1.10\' test.template
#!/bin/sh
# Provides: test-7.1.10.sh
echo 'Hello, world!'
cat > file << 'EOF'
This line will not be interpolated: $FOO
EOF
cat >> file << EOF
and this line will: $FOO
EOF
sed 's@foo@bar@g' >> file << EOF
this line's foo is changed by sed, with interpolated $variables
EOF