bash:如何传递包含特殊字符的命令行参数

bash:如何传递包含特殊字符的命令行参数

program我自己编写了一个需要正则表达式作为输入的Linux 程序。

我想在bashshell 中调用该程序,并将该正则表达式作为命令行参数传递给该程序(还有其他命令行参数)。典型的正则表达式如下所示

[abc]\_[x|y]

不幸的是,字符[]|是 中的特殊字符bash。因此,调用

program [abc]\_[x|y] anotheragument

不起作用。有没有办法通过使用某种转义字符或引号等来传递表达式?

(调用program "[abc]\_[x|y] anotheragument"也不起作用,因为它将两个参数解释为一个。)

答案1

您可以:

  1. 使用反斜杠转义每个特殊符号(如\[abc\]_\[x\|y\])或
  2. 用双引号括住整个参数(如"[abc]_[x|y]")。

编辑:作为一些已经指出,双引号不会阻止变量扩展或命令替换。因此,如果你的正则表达式包含可以被 bash 解释为其中之一的内容,使用单引号反而。

答案2

使用单引号。单引号确保不会解释任何字符。

$ printf %s 'spaces  are  not  interpreted away
neither are new lines
nor variable names $TESTING
nor square brackets [TESTING]
nor pipe characters or redirection symbols | > <
nor the semicolon ;
nor backslashes \a \b \c \\
the only thing that does not work is the single quote itself
'

如果需要嵌入单引号,有两种解决方案:

$ printf '%s\n' '[ Don'"'"'t worry, be happy! ]'
[ Don't worry, be happy! ]
$ printf '%s\n' '[ Don'\''t worry, be happy! ]'
[ Don't worry, be happy! ]

答案3

man bash

有三种引用机制:转义字符、单引号和双引号。

未引用的反斜杠 (\) 是个 转义字符。它保留其后的下一个字符的字面值,但 <newline> 除外。如果\出现 <newline> 对,并且反斜杠本身没有被引用,则\<newline> 被视为行延续(也就是说,它从输入流中删除并被有效忽略)。

将字符括在单引号中可保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。

将字符括在双引号中将保留引号内所有字符的字面值,但以下情况除外$`\并且,当启用历史记录扩展时,。 那些角色$`在双引号内,反斜杠保留其特殊含义。 反斜杠仅在其后跟以下字符之一时才保留其特殊含义:$`\, 或者<换行符>。双引号可以在双引号内引用,方法是在双引号前面加上反斜杠。如果启用,则将执行历史记录扩展,除非出现在双引号中的字符使用反斜杠进行转义。未被移除。

特殊参数*@在双引号中具有特殊含义(参见参数以下)。

形式的单词$'细绳受到特殊对待。这个词扩展为细绳,使用反斜杠转义字符替换,如 ANSI C 标准所指定。如果存在反斜杠转义序列,则按如下方式解码:

       \A     警示(铃声)
       \b     退格键
       \e
       \E     转义符
       \F     换页
       \n     新队
       \r     回车
       \t     水平制表符
       \v     垂直制表符
       \\     反斜杠
       \'     单引号
       \”     双引号
       \嗯嗯   八位字符,其值为八进制值嗯嗯
              (一至三位数)
       \X赫赫   八位字符,其值为十六进制值赫赫
              (一个或两个十六进制数字)
       \u哈哈哈哈Unicode(ISO/IEC 10646)字符,其值为
              十六进制值哈哈哈哈(一至四位十六进制数字)
       \U哈哈哈哈哈哈
              Unicode(ISO/IEC 10646)字符,其值为
              十六进制值哈哈哈哈哈哈(一至八个十六进制数字)
       \CX    控制X特点

扩展的结果是单引号,就好像没有美元符号一样。

以美元符号开头的双引号字符串 ($”细绳)将导致根据当前语言环境翻译字符串。如果当前语言环境是C或者POSIX,美元符号将被忽略。如果字符串被翻译并替换,则替换内容将被双引号引起来。

答案4

虽然它可能不像正则表达式那样有用,但某些字符序列可能会被解释为 Bash 变量名。为了防止这种情况发生并避免它们被扩展,请使用单引号而不是双引号:

program '[abc]_[x|y]' anotherargument

单独引用每个参数(如果需要引用),以便将它们解释为独立参数。在某些情况下,您还可以使用数组:

param_array=('[abc]_[x|y]' anotherargument)    # create an array
param_array+=(yetanother)     # append another element to the array
program "${param_array[@]}"   # use the array elements as arguments to program

相关内容