在 PHP 中标记 bash shell 命令的最佳方法是什么?

What is the best way to tokenize bash shell command in PHP?

我处于这样一种情况,我需要采用(可能)多字符串 bash 命令并将其压缩成一个不包含任何换行符或回车 return 字符的字符串(但产生相同的结果,即命令语义不得受到影响)。

下面是一些输入示例和相应的预期输出。

输入:

echo A
echo B

预期输出:

echo A;echo B

输入

echo "continued
string"
echo "other"

预期输出:

echo "continued"$'\n'"string";echo "other"

输入

cat file1 \
file2 \
file3

预期输出:

cat file1 file2 file3

输入

for f in `pwd`/*
do
{ echo A; echo B
echo C; echo D; }
done

预期输出:

for f in `pwd`/*; do { echo A; echo B; echo C; echo D; }; done

等等。显然我不能

preg_replace('/[\r\n]+/', ';', $input);

因为shell 支持复合命令和命令列表、多行字符串、多行命令延续运算符 ('\') 等等。似乎我别无选择,只能标记输入命令并从那里开始。我的 bash 知识水平一般,因此可能会遗漏一些案例,而这些案例也需要解决方案来处理。

是否有现有的 PHP 库或包(我搜索过 packagist 无果)可以帮助我更接近我的目标?如果不是,您将如何应对这一挑战(无需编写代码,只需将手指指向正确的方向)。

作为绝望的后备,我将不得不求助于移植 bash 源代码本身,但我真的希望有人会建议一个快捷方式。

尝试为 bash 创建一个解析器是一个非常雄心勃勃(而且模棱两可)的项目。 Bash 不断发展,在某些领域,突破了 POSIX 标准的界限。考虑缩小项目规模 - 可能以 Posix shell 为目标(它将涵盖许多 shell 变体:破折号、灰烬、...)。

考虑从 https://pubs.opengroup.org/onlinepubs/9699919799/ 开始它确定了几个引用选项。如果你仔细实施这些,你的方法(用';'替换行尾可能有效)。

另一种选择是从 bash 语法荧光笔开始,例如 vim 荧光笔。 (/usr/share/vim/vimNN/syntax/sh.vim,其中 NN 是 vim 版本)。