首页 > 解决方案 > 如何使用 bash shell 脚本从 PHP 配置文件中读取变量

问题描述

我正在尝试使用 bash 从 php 配置文件中读取一些变量,它在大多数情况下都可以工作,但我在尝试使用传回的值时遇到了问题。
该变量可以在 config 中找到,但是当它被传回时,它周围仍然有来自 PHP 的单引号或双引号。

这是我正在使用的。

DBPASS="$(grep -oE '\$database_password = .*;' $CONFIG | tail -1 | sed 's/$database_password = //g;s/;//g')"

现在,变量可以用单引号或双引号括起来,并且单引号可能出现在密码字段中。所以我不能把它们都去掉。

知道怎么做吗?

更新

所以换一种方式,我在 bash 脚本(它基本上备份了一个 CMS)中添加了一些内容,它将查找并编写一个小的 PHP“帮助程序”。该助手将只读取配置,构建一个数组并将其传递回 bash 脚本。

HELPER="backup-helper.php";

CONFIG="../core/config/config.inc.php"

if [ ! -f "$HELPER" ]; then
    echo '<?php' >> $HELPER;
    echo '$config = "$argv[1]";' >> $HELPER;
    echo 'include_once($config);' >> $HELPER;
    echo 'echo $dbase;' >> $HELPER; 
    echo 'echo $modx_core_path;' >> $HELPER;

    echo 'return "this";' >> $HELPER;
    chmod 755 $HELPER;

    php $HELPER  $CONFIG;
fi

所以这基本上只是寻找帮助文件并在它不存在时创建它,然后运行它来测试 - 这一切都有效。

我可以轻松地添加逻辑以从配置文件中创建我需要的数组,但是:

如何格式化它(要传回的数组)以便 bash 理解它?如何将它(数组)传递回 bash?(基本上我如何告诉 bash 期望返回值?)

标签: bashshell

解决方案


如果你感到幸运,可以这样:

eval $(sed -Ene '/^\$database_(username|password)/{s/ = /=/;s/^\$//;s/;$//;p;}' config.php)

我在这里只想说你绝对不应该这样做,这是一个坏主意,我只是作为一个反例。如果您编写这样的 shell 脚本,您最终将自取其辱。

像这样的东西会更安全:

db_username="$(php -r 'include("config.php"); print $database_username;')"
db_password="$(php -r 'include("config.php"); print $database_password;')"

当然,这取决于周围有一个 PHP 解释器来处理 PHP 脚本的读取和解析。如果这是不可能的,那么您将冒着以不完全符合 PHP 解释 PHP 脚本的方式编写基于 shell 的 PHP 解释器的风险。买家要小心,可能含有坚果等。

你可以像这样做一些非常丑陋的事情:

#!/usr/bin/env bash

shopt -s extglob

while read -r line; do
  #echo "line = $line"
  case "$line" in
    '$database_username = '*|'$database_password = '*)
      output="${line#\$database_+([[:alpha:]]) = }"
      output="${output#\"}"     # strip leading double quote
      output="${output%\";}"    # strip trailing double quote and semicolon
      ;;
  esac
  case "$line" in
    '$database_username = '*)
      db_username="$output"
      ;;
    '$database_password = '*)
      db_password="$output"
      ;;
  esac
done < config.php

printf 'u = %s\np = %s\n' "$db_username" "$db_password"

这具有 NO PIPELINES 的优点,它的所有功能都包含在 bash 脚本中。但是,如果您的 config.php 包含分号后面的空格,或分号之前的空格,或者用转义换行符断开并继续的行,或者在多行上构建的变量,例如$database_password .= "MOAR";或任何数量的其他东西,它就会中断完全有效的 PHP。

我的强烈偏好是二号门,使用 PHP 解释器来解释你的 PHP。


更新

如果您的 PHP 配置在一个数组中(例如 Drupal),您可以使用以下内容将该数组导出到 bash:

declare -A conf
while IFS== read -r -d '' key value; do
  conf["$key"]="$value"
done < <( php -r 'include("config.php"); foreach ($conf as $key => $value) printf("%s=%s\0",$key,$value);')'

read这使用 bash 进程以可以被 bash命令安全读取的格式提供 PHP 数组的转储。如果您有很多想要从 PHP 配置中读取的内容,并且您只想启动 PHP 一次而不是为您获取的每个值启动一次,这可能是有利的。

请注意,如果您的任何键包含等号,您可能需要对此进行调整。此外,关联数组是 bash 4 的一个特性。


推荐阅读