简体   繁体   中英

Perl one liner in Bash script

I have a bash script that runs, and I'm trying to use a Perl one-liner to replace some text in a file variables.php

However, I would like to check if the Perl one-liner runs successfully and that's where I get hung up. I could just output the one-liner and it would work fine, but I would like to know for sure that it ran.

Basically, the function replace_variables() is the function that does the update, and it's the if statement there that I would like to check if my one-liner worked properly.

I've tried using the run_command function in that if statement, but that did not work, and I've tried putting the one-liner directly there, which also didn't work.

If I don't wrap it in an if statement, and just call the one-liner directly, everything works as intended.

here's the full file

#!/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

here's the function where the if statement fails

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
}

You can see that I commented out the one-liner just before the if statement, it works if I let that run and remove the if/else check.

here is the original file snippet before the update

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

here is the file snippet after the update would run

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

tl;dr and Solution

This usage of if with [ ] will not give you the result you expect.
What you're looking for

...
    if run_command; then
...

Longer explanation

Basics of if

  1. if is a shell feature
  2. based on the condition, it executes the body contained in between then and fi
  3. the "condition" that if checks is a command
  4. commands usually have a return/exit code. typically
    • 0 for success
    • 1 (common) and everything else for some error
      • eg 127 for command not found
  5. when the return/exit code is 0, the body is executed
  6. otherwise it is skipped; or control is passed to elif or else
  7. the syntax is if <command>; then... if <command>; then...

Where does that [ ] come from?

  1. test is a command that can check file types and compare values
    • refer man test and help test (bash only)
  2. [... ] is a synonym for test
    • NB the brackets should be surrounded by spaces on both sides
    • if [ -f "/path/to/$filename" ]; then
      • exception: when terminated by new line or ; space not required
  3. test (or [ ] ) evaluates expressions and cannot execute other commands or functions
  4. if [ expr ]; then if [ expr ]; then is alternate syntax for if test expr; then if test expr; then

PS: good practice to "quote" your "$variables" when used with test or [ ]

PPS: [[... ]] is a different thing altogether. not POSIX; available only in some shells. take a look at this thread on the UNIX Stack Exchange

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM