首页 > 解决方案 > Perl 在 Bash 脚本中的一个衬里

问题描述

我有一个运行的 bash 脚本,我正在尝试使用 Perl 单行代码替换文件 variables.php 中的一些文本

但是,我想检查 Perl 单行程序是否成功运行,这就是我挂断电话的地方。我可以只输出单行,它会正常工作,但我想确定它是否运行。

基本上,函数 replace_variables() 是执行更新的函数,我想检查我的单行是否正常工作的 if 语句。

我已经尝试在 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.*;$/\1 = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/\1 = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/\1 = 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.*;$/\1 = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/\1 = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/\1 = 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.*;$/\1 = Config::get("db")["user"];/; s/(dbpass)(\s+)=\s.*;$/\1 = Config::get("db")["pass"];/; s/(dbname)(\s+)=\s.*;$/\1 = 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"];

标签: bashperlone-liner

解决方案


tl;博士和解决方案

ifwith的这种用法[ ]不会给你你期望的结果。
你在找什么

...
    if run_command; then
...

更长的解释

基础知识if

  1. if是一个外壳特征
  2. 根据条件,它执行包含在两者之间的主体thenfi
  3. 检查的“条件”if是一个命令
  4. 命令通常有一个返回/退出代码。通常
    • 0为了成功
    • 1(常见)以及其他所有错误
      • 例如127找不到命令
  5. 当返回/退出代码为0时,执行body
  6. 否则跳过;或控制权传递给elifelse
  7. 语法是if <command>; then...

[ ]是从哪里来的?

  1. test是一个可以检查文件类型和比较值的命令
  2. [ ... ]是同义词test
    • 注意括号应该被两边的空格包围
    • if [ -f "/path/to/$filename" ]; then
      • ;例外:当被新行或不需要空格终止时
  3. test(or [ ]) 计算表达式并且不能执行其他命令或函数
  4. if [ expr ]; then是替代语法if test expr; then

testPS:与或一起使用时“引用”您的“$variables”的好习惯[ ]

PPS:[[ ... ]]完全不同。不是POSIX;仅在某些 shell 中可用。看看UNIX Stack Exchange 上的这个线程


推荐阅读