如何使用bash shell脚本

时间:2018-05-02 20:01:05

标签: bash shell

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

这是我正在使用的。

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

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

任何想法如何做到这一点?

更新

所以换一种方式,我在bash脚本(基本上备份了CMS)中添加了一些内容,它将寻找并编写一些PHP" helper"。那个助手只会读取配置,构建一个数组&将其传递回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

所以这基本上只是寻找辅助文件&amp;如果它不存在则创建它,然后运行它来测试 - 这一切都有效。

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

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

1 个答案:

答案 0 :(得分:2)

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

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);')'

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

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