简体   繁体   English

如何使用bash shell脚本从PHP配置文件读取变量

[英]How to read variables from a PHP config file using a bash shell script

I am trying to read some variables from a php config file using bash & it is working for the most part, but I am having issues trying to use the values passed back. 我正在尝试使用bash从php配置文件中读取一些变量,并且在大多数情况下都有效,但是在尝试使用传递回的值时遇到了问题。
The variuable is found in config, but when it is passed back it still has the single or double quotes from PHP around it. 该变量在config中找到,但是当它传递回时,它周围仍带有PHP的单引号或双引号。

Here is what I am using. 这是我正在使用的。

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

now, the variables may be wrapped in either single or double quotes AND a single quote may be present in a password field. 现在,变量可以用单引号或双引号引起来,并且密码字段中可以包含单引号。 So I can't just strip all of them out. 所以我不能只是将它们全部剥离。

any idea how to do this? 任何想法如何做到这一点?

UPDATE 更新

So going another way with this, I have added a bit to the bash script (which basically backs up a CMS) that will look for and write a little PHP "helper". 因此,通过另一种方式,我在bash脚本中添加了一些内容(基本上备份了CMS),该脚本将查找并编写一些PHP“帮助程序”。 That helper will just read the config, build an array & pass it back to the bash script. 该助手将只读取配置,构建一个数组并将其传递回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

So this is basically just looking for the helper files & creating it if it does not exist, then runs it to test - this all works. 因此,这基本上只是寻找帮助文件并创建它(如果它不存在),然后运行它进行测试-一切正常。

I can easily add the logic to create an array of what I need from the config file, but: 我可以轻松地从配置文件中添加逻辑以创建所需数组,但是:

how do I format it (the array to be passed back) so that bash will understand it? 我如何格式化它(要传递回的数组),以便bash能够理解? how do I pass it (the array) back to bash? 如何将其(数组)传递回bash? (basically how do I tell bash to expect a return value?) (基本上我如何告诉bash期望返回值?)

If you're feeling lucky, something like this: 如果您感到幸运,请执行以下操作:

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

I'll just say here that you absolutely shouldn't do this, it's a bad idea, and I only included as a counterexample. 我在这里只说您绝对不应该这样做,这是一个坏主意,我仅作为反例。 You WILL eventually shoot yourself in the foot if you write shell scripts like this. 如果您编写这样的shell脚本,最终将使自己陷入困境。

Something like this would be safer: 这样的事情会更安全:

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

Of course, it depends on having a PHP interpreter around to handle the reading and parsing of the PHP script. 当然,这取决于周围有PHP解释器来处理PHP脚本的读取和解析。 If that just isn't possible, then you run the risk of writing your shell-based PHP interpreter in a way that isn't fully compliant with how PHP interprets PHP scripts. 如果那是不可能的,那么您将冒着与PHP解释PHP脚本的方式不完全兼容的方式编写基于shell的PHP解释器的风险。 Buyer beware, may contain nuts, etc. 买家当心,可能包含坚果等。

You could do something really ugly like this: 你可以做这样的事情真的很丑:

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

This has the advantage of NO PIPELINES, all its functionality is self-contained within a bash script. 这具有NO PIPELINES的优点,其所有功能均独立于bash脚本中。 But it will break if your config.php contains spaces trailing the semicolon, or spaces before the semicolon, or lines broken and continued with escaped newlines, or variables that are built over multiple lines with things like $database_password .= "MOAR"; 但是,如果您的config.php包含在分号后面的空格,或者在分号之前的空格,或者行被折断并以转义的换行符继续,或者在多行上构建的变量带有$database_password .= "MOAR";变量,则它将中断$database_password .= "MOAR"; or any number of other things that might be perfectly valid PHP. 或其他可能完全有效的PHP。

My strong preference is Door Number Two, using a PHP interpreter to interpret your PHP. 我的首选是2号门,使用PHP解释器来解释您的PHP。


UPDATE 更新

If your PHP configuration is in an array (as with Drupal, for example), you might be able to export that array to bash with something like the following: 如果您的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);')'

This uses bash process to provide a dump of the PHP array in a format that can safely be read by bash's read command. 它使用bash进程提供PHP数组的转储,其格式可以由bash的read命令安全地读取。 This might be advantageous if you have A LOT of things you want to read from your PHP config, and you only want to launch PHP once rather than for every value you're fetching. 如果您有很多想从PHP配置中读取的东西,并且只想启动PHP而不是获取的每个值,则这可能是有利的。

Note that you might have to adjust this if any of your keys contain an equals sign. 请注意,如果您的任何键都包含等号,则可能必须对此进行调整。 Also, associative arrays are a feature of bash 4. 而且,关联数组是bash 4的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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