无法将“#”字符作为命令行参数传递

Posted

技术标签:

【中文标题】无法将“#”字符作为命令行参数传递【英文标题】:Unable to pass '#' character as a command-line argument 【发布时间】:2020-03-09 07:02:46 【问题描述】:

我无法将以# 开头的字符串作为命令行参数传递。

这是一个简单的测试:

#include <stdio.h>

int main(int argc, char *argv[])

    for (int i = 1; i < argc; i++)
        printf("%s ", argv[i]);

    putchar('\n');

    return 0;

如果我输入如下参数:

2 4 # 5 6

argc 的值是 3 而不是 6。它读取# 并停在那里。我不知道为什么,并且在我的 C 编程语言C Primer Plus 的副本中找不到答案。

【问题讨论】:

*** 上突出显示的语法很好地说明了您的问题 :) 【参考方案1】:

# 在 Unix shell 中开始注释,很像 C 中的 //

这意味着当 shell 将参数传递给程序时,它会忽略 # 之后的所有内容。用反斜杠或引号对其进行转义意味着它会像其他参数一样被处理,并且程序应该按预期工作。

2 4 \# 5 6

2 4 '#' 5 6

2 4 "#" 5 6

请注意,# 是仅在单词开头的注释字符,因此这也应该有效:

2 4#5 6

【讨论】:

这似乎是一个不错的列表unix.stackexchange.com/a/270979 @cd-00 您需要了解 shell 的工作原理。这与您的 C 代码无关。 啊,所以你可以在 interactive shell 会话中输入 cmets,这样 shell 可以在你完成输入后立即忽略它。多么有用的功能。 @Joker_vD 虽然您认为 shell 是一个命令行界面,但它实际上是一个脚本解释器。您可以像交互式 CLI 一样使用它这一事实是一个不错的奖励。为什么当您“运行脚本”与以交互方式输入命令时,解释的行为会有很大不同? echo echo Hello, World | bash 呢。那是互动的吗?或者bash &lt;&lt;END @Joker_vD:我经常在交互式会话中键入 cmets 以在我的 shell 历史中参考。有时这是为了记录一个提交哈希或其他 ID 发送到标准输出;有时要注意一个命令失败,作为对我未来自己的一个说明;有时是为临时基准测试记录时间数据。它一个有用的功能。【参考方案2】:

通过命令行参数传递值时,您必须按照以下说明进行操作。 以下字符在某些情况下对 shell 本身具有特殊含义,可能需要在参数中进行转义:

` Backtick (U+0060 Grave Accent)
~ Tilde (U+007E)
! Exclamation mark (U+0021)
# Hash (U+0023 Number Sign)
$ Dollar sign (U+0024)
& Ampersand (U+0026)
* Asterisk (U+002A)
( Left Parenthesis (U+0028)
) Right parenthesis (U+0029)
 (⇥) Tab (U+0009)
 Left brace (U+007B Left Curly Bracket)
[ Left square bracket (U+005B)
| Vertical bar (U+007C Vertical Line)
\ Backslash (U+005C Reverse Solidus)
; Semicolon (U+003B)
' Single quote / Apostrophe (U+0027)
" Double quote (U+0022)
↩ New line (U+000A)
< Less than (U+003C)
> Greater than (U+003E)
? Question mark (U+003F)
  Space (U+0020)1

【讨论】:

那他们应该如何逃脱呢? \ - 使用反斜杠转义 .EX: 2 4 \#,$,&amp;,* 5 6【参考方案3】:

这是因为您使用的是类似sh 的外壳。引用# 或使用\ 转义它,它会起作用。

这在sh 中称为评论。它会导致#(空格散列)和它后面的任何参数被丢弃。它的使用类似于 C 中的 cmets,用于记录代码。

$ 开头的字符串在sh 中称为变量。如果您没有设置变量,它将扩展为一个空字符串。

例如,所有这些都是将# 传递给您的应用程序的有效方法:

2 4 '#' 5 6
2 4 "#" 5 6
2 4 \# 5 6

这些将是传递以$ 开头的字符串的有效方法:

2 4 '$var' 5 6
2 4 '$'var 5 6
2 4 \$var 5 6

请注意,"s 中的变量仍在扩展中。

【讨论】:

以上是关于无法将“#”字符作为命令行参数传递的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何将密码(包含特殊字符)作为命令行参数传递?

将元组作为命令行参数传递

Python 将多个字符串传递给单个命令行参数

如何使用 argparse 将列表作为命令行参数传递?

为啥在将命令行图像文件中的参数作为参数传递时出现错误

将 0 作为命令行参数传递的问题