0

第一个问题:

假设我们编写了一个简单的程序,它接受命令行参数并打印到文件中。如果用户输入

writetofile 你好!0\nw%orl\t!@#y

bash 回复

!0: 未找到事件。

如果用户不知道使用引号 ('') 或转义字符 ('\') 之类的东西,我该如何处理这些东西而不是 bash 将其理解为命令?

第二个问题:

一旦我得到这些参数,我如何将它们解释为特殊字符而不是字符序列。(即 \t 是制表符,而不是 '\''t')

也就是说,如何确保程序将其写入文件:

Hello!0
 w%orl    !@#y

并不是

Hello!0\n w%orl\t!@#y
4

3 回答 3

2

您无法让 bash 停止将命令行解析为命令行。在您的特定情况下,set +H将禁用历史扩展,从而允许 !0 作为文字,但是如果您包含(parenthesis), $variables,和其他十几个 shell 语法元素,#comments命令仍然会失败。ampersand &

请注意,这仅适用于 shell 的解析阶段,不适用于按字面传递execve或类似的任何数据。

要么让用户引用数据('single quotes'将处理除其他单引号之外的所有内容),要么让您的程序本身读取数据以便交互进行

$ writetofile
Please enter your gibberish and press enter: Hello!0\n w%orl\t!@#y
Thank you for your eloquent contribution.
$
于 2013-02-17T18:12:15.590 回答
1

第一个问题:使用单引号。即:writetofile 'Hello!0\nw%orl\t!@#y'

第二个问题:使用 printf。

于 2013-02-17T15:43:06.030 回答
1

关于第二个问题:正如@Jims 所说,您可以使用 printf(1) 打印字符串。好主意,但请注意,这只会起作用,因为您(似乎)想要识别的转义符,例如\tand \n,与 printf 识别的转义符相同。

这些转义很常见,但它们没有任何基本内容,因此您的问题的一般答案 - 以及如果您想识别 printf 没有的转义的答案 - 是让您的程序解释它们。执行此操作的类 C 代码将类似于:

char *arg = "foo\\tbar\\n"; /* the doubled backslashes are to make this valid C */
int arglen = strlen(arg);
for (i=0; i<arglen; i++) {
    if (arg[i] == '\\') { // we've spotted an escape
        // interpret a backslash escape
        i++; // we should check for EOS here...
        switch (arg[i]) {
          case 'n': putchar('\n'); break;
          case 't': putchar('\t'); break;
          // etc
         }
     } else {
         // ordinary character: just output it
         putchar(arg[i]);
     }
 }

(插入错误处理和良好的风格,品尝)。

于 2013-02-17T19:00:18.163 回答