我正在构建一个 shell 脚本来自动执行我工作中的某些流程。
我需要从 php 中提取一些变量,它们的创建方式如下:
return [
'db' => [
'table_prefix' => '',
'connection' => [
'default' => [
'host' => 'localhost',
'dbname' => 'dbname',
'username' => 'root',
'password' => '',
'model' => 'mysql4',
'engine' => 'innodb',
'initStatements' => 'SET NAMES utf8;',
'active' => '1'
]
]
],
因此,我的计划是通过以下方式提取 php 文件:
#!/bin/bash
# php file to get variables from
FILE_NAME="etc/env.php"
echo "Starting Migration..."
DATABASE=$(cat $FILE_NAME | grep "^\'dbname' =>" | cut -d "=" -f 2-)
DATABASE_HOST=$(cat $FILE_NAME | grep "^\host=" | cut -d "=" -f 2-)
DATABASE_PASS=$(cat $FILE_NAME | grep "^\password=" | cut -d "=" -f 2-)
DATABASE_USER=$(cat $FILE_NAME | grep "^\$username=" | cut -d "=" -f 2-)
echo "Value from PHP file"
echo "Database name ${DATABASE}"
echo "Database host ${DATABASE_HOST}"
echo "Database pass ${DATABASE_PASS}"
echo "Database user ${DATABASE_USER}"
但是我没有得到变量,它只是空的...有什么想法吗?
答案1
如果可用,使用 GNU grep
,你可以这样做
grep -Po "(?<='dbname' => ).*(?=,)" file
在你的脚本中:
DATABASE=$(grep -Po "(?<='dbname' => ).*(?=,)" $FILE_NAME)
DATABASE_HOST=$(grep -Po "(?<='host' => ).*(?=,)" $FILE_NAME)
DATABASE_PASS=$(grep -Po "(?<='password' => ).*(?=,)" $FILE_NAME)
DATABASE_USER=$(grep -Po "(?<='username' => ).*(?=,)" $FILE_NAME)
使用该-P
选项您可以激活类似 Perl 的正则表达式。
-o
您可以选择仅有的捕获的字符串,而不是整行。
基本上是这样的:
(?<=<string starts with>)<capture this string>(?=<string ends with>)
答案2
通常,对于 shell 脚本需要的每个功能,如果不在 shell 脚本的范围内,它都会调用其他程序来“做好一件事”(Unix 哲学),那么为什么不调用做您想做的事情的程序呢?您可能没有意识到,您可以使用 PHP 参数直接从命令行(或在这种情况下为 shell 脚本)运行 PHP -r
。下面是如何在您的示例中执行此操作(假设输入文件以 开头并以 而不是<?php
结尾),方法是使用 require 语句将 php 文件的返回用作数组(在您的例子中是数组):; ?>
,
DATABASE=$(php -r 'echo (require("input.php"))["db"]["connection"]["default"]["dbname"];')
DATABASE_HOST=$(php -r 'echo (require("input.php"))["db"]["connection"]["default"]["host"];')
DATABASE_PASS=$(php -r 'echo (require("input.php"))["db"]["connection"]["default"]["password"];')
DATABASE_USER=$(php -r 'echo (require("input.php"))["db"]["connection"]["default"]["username"];')
如果 PHP 文件在全局范围内没有 return,则在 require 语句后面加上;
一个单独的 echo 语句(-r
如果每行都以分号结尾,则该参数可以接受多行。请参阅我的回答https://unix.stackexchange.com/a/747009/343286)。