Bash 脚本中的 Perl 一行
Perl one liner in Bash script
我有一个 bash 脚本 运行s,我正在尝试使用 Perl 单行代码替换文件中的一些文本 variables.php
但是,我想检查 Perl 单行 运行 是否成功,这就是我被挂断的地方。我可以只输出一行,它会工作正常,但我想确定它 运行.
基本上,函数 replace_variables() 是执行更新的函数,它是那里的 if 语句,我想检查我的 one-liner 是否正常工作。
我试过在那个 if 语句中使用 run_command 函数,但这没有用,我试过将单行直接放在那里,但也没有用。
如果我不将其包装在 if 语句中,而只是直接调用单行代码,一切都会按预期进行。
这是完整文件
#!/bin/bash
export CLI_CWD="$PWD"
site_variables() {
if [ -f "$CLI_CWD/variables.php" ]; then
return true
else
return false
fi
}
replace_variables() {
# perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
if [run_command ]; then
echo "Updated variables.php successfully"
else
echo "Did not update variables.php"
fi
}
run_command() {
perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
}
if [ site_variables ]; then
replace_variables
else
>&2 echo "Current directory ($(pwd)) is not a project root directory"
exit 4
fi
这里是if语句失败的函数
replace_variables() {
# perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
if [run_command ]; then
echo "Updated variables.php successfully"
else
echo "Did not update variables.php"
fi
}
你可以看到我在 if 语句之前注释掉了一行代码,如果我允许 运行 并删除 if/else 检查,它就会起作用。
这里是更新前的原始文件片段
//Load from Settings DB
$dbuser = 'username';
$dbpass = 'password';
$dbname = 'database_name';
这是更新后的文件片段 运行
//Load from Settings DB
$dbuser = Config::get("db")["user"];
$dbpass = Config::get("db")["pass"];
$dbname = Config::get("db")["database"];
tl;dr 和解决方案
if
与 [ ]
的这种用法不会给您预期的结果。
你在找什么
...
if run_command; then
...
更长的解释
if
的基础知识
if
是一个 shell 特征
- 根据条件执行
then
和fi
之间的主体
if
检查的“条件”是命令
- 命令通常有一个return/exit代码。通常
0
成功
1
(常见)和其他所有错误
- 例如
127
找不到命令
- 当return/exit代码为0时,执行正文
- 否则跳过;或控制传递给
elif
或 else
- 语法是
if <command>; then...
[ ]
是从哪里来的?
test
是一个可以检查文件类型和比较值的命令
- 参考man test和
help test
(仅限bash)
[ ... ]
是 test
的同义词
- 注意括号应该被space包围
if [ -f "/path/to/$filename" ]; then
- 异常:当被换行或
;
终止时space不需要
test
(或[ ]
)计算表达式,不能执行其他命令或函数
if [ expr ]; then
是 if test expr; then
的替代语法
PS:与 test
或 [ ]
一起使用时“引用”您的“$variables”的好习惯
PPS: [[ ... ]]
完全是另一回事。不是 POSIX;仅在某些 shell 中可用。看看 this thread on the UNIX Stack Exchange
我有一个 bash 脚本 运行s,我正在尝试使用 Perl 单行代码替换文件中的一些文本 variables.php
但是,我想检查 Perl 单行 运行 是否成功,这就是我被挂断的地方。我可以只输出一行,它会工作正常,但我想确定它 运行.
基本上,函数 replace_variables() 是执行更新的函数,它是那里的 if 语句,我想检查我的 one-liner 是否正常工作。
我试过在那个 if 语句中使用 run_command 函数,但这没有用,我试过将单行直接放在那里,但也没有用。
如果我不将其包装在 if 语句中,而只是直接调用单行代码,一切都会按预期进行。
这是完整文件
#!/bin/bash
export CLI_CWD="$PWD"
site_variables() {
if [ -f "$CLI_CWD/variables.php" ]; then
return true
else
return false
fi
}
replace_variables() {
# perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
if [run_command ]; then
echo "Updated variables.php successfully"
else
echo "Did not update variables.php"
fi
}
run_command() {
perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
}
if [ site_variables ]; then
replace_variables
else
>&2 echo "Current directory ($(pwd)) is not a project root directory"
exit 4
fi
这里是if语句失败的函数
replace_variables() {
# perl -pi -e 's/(dbuser)(\s+)=\s.*;$/ = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/ = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/ = Config::get("db")["database"];/' "$CLI_CWD/variables.php"
if [run_command ]; then
echo "Updated variables.php successfully"
else
echo "Did not update variables.php"
fi
}
你可以看到我在 if 语句之前注释掉了一行代码,如果我允许 运行 并删除 if/else 检查,它就会起作用。
这里是更新前的原始文件片段
//Load from Settings DB
$dbuser = 'username';
$dbpass = 'password';
$dbname = 'database_name';
这是更新后的文件片段 运行
//Load from Settings DB
$dbuser = Config::get("db")["user"];
$dbpass = Config::get("db")["pass"];
$dbname = Config::get("db")["database"];
tl;dr 和解决方案
if
与 [ ]
的这种用法不会给您预期的结果。
你在找什么
...
if run_command; then
...
更长的解释
if
的基础知识
if
是一个 shell 特征- 根据条件执行
then
和fi
之间的主体
if
检查的“条件”是命令- 命令通常有一个return/exit代码。通常
0
成功1
(常见)和其他所有错误- 例如
127
找不到命令
- 例如
- 当return/exit代码为0时,执行正文
- 否则跳过;或控制传递给
elif
或else
- 语法是
if <command>; then...
[ ]
是从哪里来的?
test
是一个可以检查文件类型和比较值的命令- 参考man test和
help test
(仅限bash)
- 参考man test和
[ ... ]
是test
的同义词- 注意括号应该被space包围
if [ -f "/path/to/$filename" ]; then
- 异常:当被换行或
;
终止时space不需要
- 异常:当被换行或
test
(或[ ]
)计算表达式,不能执行其他命令或函数if [ expr ]; then
是if test expr; then
的替代语法
PS:与 test
或 [ ]
PPS: [[ ... ]]
完全是另一回事。不是 POSIX;仅在某些 shell 中可用。看看 this thread on the UNIX Stack Exchange