1

假设我有 shell 程序 a、b、c,每个程序都执行另一个程序的命令。由于某些原因,我需要引号。例子:

a 'b 'c 'echo test'''

所以a 将调用b,b 将调用c,c 将调用'echo test'。您已经看到我的报价将被错误解释。另外,请注意 a、b 和 c 是调用 system() 的 C 程序。

有没有办法做到这一点,保留引号?

4

2 回答 2

3

您必须转义内部引号。不幸的是,单引号实际上是不可能的,所以我会对所有外部级别使用双引号,对最里面的引号使用单引号,因为双引号字符串可以包含单引号而不会转义。所以结果应该是:

a "b \"c 'echo test'\""

请注意,您需要为需要通过的每个级别添加反斜杠,因此如果 " 在最后一个级别使用,您需要

a "b \"c \\\"echo test\\\"\""

下一级将达到 7 个反斜杠,依此类推。

于 2012-06-06T08:17:48.523 回答
3

我没有针对 C 的现成解决方案,但在这种情况下,建议将要引用的字符串替换为每个字符串'并将'\''所有内容包含在'.

  1. 最里面的部分是echo test可以愉快地放入''并给予cc 'echo test'
  2. 然后你想把那个字符串给b. 从这里开始,因为所说的字符串包含's,所以你做'++你给 b c '\''echo test'\'': 。这里会发生什么?您已经为 的参数连接了几个连接部分:'b 'c '\''echo test'\'''b

    1. 'c ', which becomes justc`,
    2. \',变成'
    3. 'echo test',这是echo test在剥离引号之后,
    4. \'再次 ->'
    5. ''这什么都不是,只是因为'原始字符串的末尾有一个而存在。如果手动处理它可以省略,但不值得在算法中付出努力。

    所以你c 'echo test'在取消引用之后得到,这表明所述算法应该有效。

  3. 现在您b 'c '\''echo test'\'''再次执行此过程,以便为a: 提供参数,因此您将得到a 'b '\''c '\''\'\'''\''echo test'\''\'\'''\'''\'''.

  4. 更棘手的是:你现在想把它放在一个 C 字符串中,所以你必须加倍\s: system("a 'b '\\''c '\\''\\'\\'''\\''echo test'\\''\\'\\'''\\'''\\'''");

如果你对开始、结束和连续's 进行上述优化,你会得到

b 'c '\''echo test'\'

a 'b '\''c '\''\'\'\''echo test'\''\'\'

分别

system("a 'b '\\''c '\\''\\'\\'\\''echo test'\\''\\'\\'");

.

或者,您可以不使用'并仅引用空格和 '\',但这可能会更棘手......

让我尝试:

  1. c: echo test-> echo\ test-> c echo\ test
  2. 乙:b c\ echo\\\ test
  3. 一个:a b\ c\\\ echo\\\\\\\ test
  4. 系统:system("a b\\ c\\\\\\ echo\\\\\\\\\\\\\\ test")

引用丑陋,但它的作品。

经测试

#!/usr/bin/env python
import sys

import subprocess
sp=subprocess.Popen(sys.argv[1], shell=True, stdout=subprocess.PIPE)
for line in sp.stdout:
    print "%s> %s" % (sys.argv[0], line),
exit(sp.wait())

作为a,bc

import os
print 1
os.system("a 'b '\\''c '\\''\\'\\'''\\''echo test'\\''\\'\\'''\\'''\\'''")
print 2
os.system("a 'b '\\''c '\\''\\'\\'\\''echo test'\\''\\'\\'")
print 3
os.system("a b\\ c\\\\\\ echo\\\\\\\\\\\\\\ test")

作为test.py并调用

PATH=.:$PATH python -m test

由于在这种情况下 python 具有与 C 相同的引用规则,因此这是一个足够的测试。

于 2012-06-06T08:44:31.733 回答