【问题标题】:Perl one liner in Bash scriptPerl 在 Bash 脚本中的一个衬里
【发布时间】:2021-05-19 15:22:37
【问题描述】:

我有一个运行的 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 检查,它就可以工作。

这里是更新前的原始文件sn-p

//Load from Settings DB
    $dbuser     = 'username';
    $dbpass     = 'password';
    $dbname     = 'database_name';

这里是更新后运行的文件 sn-p

//Load from Settings DB
    $dbuser = Config::get("db")["user"];
    $dbpass = Config::get("db")["pass"];
    $dbname = Config::get("db")["database"];

【问题讨论】:

  • 您可能会收到诸如-bash: [run_command: command not found 之类的错误,因为您在打开[ 后缺少一个空格 - 但正如答案所示,您根本不需要[ .. ]
  • 如果你确实得到了那个错误输出,那应该是问题的一部分,因为它比“它不起作用”更有帮助。
  • 以编程方式修改代码可能是一项非常强大的技术,但对于普通情况,最好将所有内容都包含在源文件中并根据#define 选择要运行的代码(在语言中此类工具)或命令行参数或环境变量。

标签: bash perl one-liner


【解决方案1】:

tl;博士和解决方案

if[ ] 的这种用法不会给您预期的结果。
你在找什么

...
    if run_command; then
...

更长的解释

if的基础知识

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

[ ] 来自哪里?

  1. test 是一个可以检查文件类型和比较值的命令
    • 参考 man testhelp test(仅限 bash)
  2. [ ... ]test 的同义词
    • NB 括号应该包围两边有空格
    • if [ -f "/path/to/$filename" ]; then
      • 例外:当被换行符或; 不需要空格时
  3. test(或[ ])计算表达式,不能执行其他命令或函数
  4. if [ expr ]; thenif test expr; then 的替代语法

PS:与test[ ] 一起使用时“引用”您的“$variables”的良好做法

PPS:[[ ... ]] 完全不同。不是POSIX;仅在某些 shell 中可用。看看this thread on the UNIX Stack Exchange

【讨论】:

  • 谢谢,这很容易。如果你不知道,我是 Bash 的新手,那就成功了。谢谢。
  • 我将很快添加解释。编辑我的答案以包含它。如果您认为这一切都很合适,请考虑接受答案以让其他人知道解决方案:)
猜你喜欢
  • 1970-01-01
  • 2015-01-15
  • 2015-09-10
  • 2015-12-27
  • 1970-01-01
  • 2013-02-05
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多