Bash 当一个特殊的字符来自命令行时,我们如何将其逐出?

Bash 当一个特殊的字符来自命令行时,我们如何将其逐出?,bash,grep,Bash,Grep,为了说明这一点,我举了一个例子 假设我们想用bash脚本写一个atechnic fridenly白鹭,这意味着这个家伙不知道如何逃脱特殊角色,他只会传递他想要的东西 例如,当他想在一篇文章中找到它的出现时,他使用 ./myEgrep it's myArticle 而不是 ./myEgrep it\'s myArticle** 我们如何在脚本中处理这个问题?基本上,egrep不能像人类那样被赋予并理解包含特殊字符的字符串。最困难的部分是如何在脚本中将$1封装在Xgrep$1$myArticle

为了说明这一点,我举了一个例子

假设我们想用bash脚本写一个atechnic fridenly白鹭,这意味着这个家伙不知道如何逃脱特殊角色,他只会传递他想要的东西

例如,当他想在一篇文章中找到它的出现时,他使用

./myEgrep it's myArticle
而不是

./myEgrep it\'s myArticle**

我们如何在脚本中处理这个问题?基本上,egrep不能像人类那样被赋予并理解包含特殊字符的字符串。最困难的部分是如何在脚本中将$1封装在Xgrep$1$myArticle中。我尝试了fgrep,但也没有成功。

您这里的问题是单引号由shell或bash处理,它实际上是在用户键入另一个单引号之前停止执行命令。 如果整个短语由用户以双引号表示,则不需要转义单引号或任何空格,即:

./myEgrep "it's" myArticle
我相信这很容易向用户解释,即使是不太精明的用户

然后,在脚本文件中,您需要再次将参数用双引号括起来:

Xgrep "$1" "$myArticle"
脚本中的最佳实践是几乎总是将参数用双引号括起来,因为它保留了变量中的空格

当然,这就留下了用户如何从命令行注入双引号的问题。对你来说,简单的答案是他们使用单引号来包装双引号,但对他们来说可能不是;如果他们想混用引号呢


另一个选项是处理输入并将空格转换为任意长度的任意空格的正则表达式,将单引号转换为所有引号的正则表达式,包括unicode开/闭引号?同样,易于向用户解释。任何其他方案,您都将重新发明转义码。

不是唯一的问题。如果用户键入
/myEgrep foo.*.bar
/myEgrep foo$(rm*)bar
(不要尝试!),该怎么办?当有人从shell调用工具时,他们在shell中,因此shell语法和语义适用

如果您希望他们能够使用任何参数调用您的命令,并且该调用的含义与shell中的不同,那么您需要编写一个包装工具,为他们设置一个有限/非shell环境,以便他们在其中工作,例如:

#!/bin/env bash
function myEgrep() {
    local re="$1"
    grep -E "$re" wherever
}

while IFS= read -r line; do
    cmd="${line%% *}"
    args="${line#* }"
    case $cmd in
    myEgrep ) myEgrep "$args" ;;
    esac
done

因此,您的用户执行上述脚本,可以输入您允许他们输入的任何命令,也可以包含他们喜欢的任何字符。

“我们如何在脚本中处理此问题?”您不这样做,因为您显示的命令行甚至不会运行脚本。问题在于shell,而不是grep。事实上,
在grep中甚至没有什么特别之处。@gonda:除了melpomene所说的,你可以使用
grep
-f
选项,这是一种文字匹配。