【问题标题】:Detecting semicolon as command line argument in linux在linux中检测分号作为命令行参数
【发布时间】:2018-11-15 17:24:47
【问题描述】:

我正在尝试运行一个 C++ 应用程序,其中我将一些命令行参数传递给它,如下所示:

./startServer -ip 10.78.242.4 tcpip{ldap=no;port=2435}

应用程序崩溃,因为它无法获取正确的端口。在网上搜索,我发现“;”被视为命令结束字符(Semicolon on command line in linux),因此之后的所有内容都将被忽略。我也明白把它放在引号里会很好。但是,我不想强​​制将参数放在用户的引号中的这种限制。所以,我想知道有没有一种方法可以处理“;” argv 数组的字符?

【问题讨论】:

  • 为什么需要分号作为分隔符?在linux的命令行中使用没有特定含义的东西不是更简单吗?
  • 将其屏蔽为 \;也不是一个选择吗?问题似乎是,分号甚至没有传递给您的程序,因此您可以在 argv 数组中处理它。如果你屏蔽它,那么它将被传递,你可以处理它。否则壳会“吃掉”它
  • 我也可以这样做,但只是想知道我们是否可以检测到“;”在上面的命令中。
  • 您不能为一个应用程序执行此操作。也许你可以用stty 改变它,但是一行可以包含任意数量的命令来启动不同的进程(它们都得到不同的参数)。
  • “把它放在引号内就可以了。但是,我不想强​​加这个限制” 为什么不呢,这是一个相当标准和被接受的复杂的事情论据?

标签: c++ command-line command-line-arguments


【解决方案1】:

分号分隔两个命令,因此您的命令行相当于

./startServer -ip 10.78.242.4 tcpip{ldap=no
port=2435}

您的应用程序永远不会知道任何关于分号或第二个命令的信息,这些将完全由 shell 处理。您需要用反斜杠转义冒号或将其括在引号中。其他可能导致类似问题的字符包括:$,\-#`'":*?()&|

复杂的字符串更容易从文件或标准输入中传递。

【讨论】:

  • 有没有办法访问第二行“port=2435}”?它们实际上存储在哪里?我在 argv 数组中找不到它。
  • 不,第二行与您的进程无关,shell 将尝试将其作为第二条命令运行,将变量“port”设置为“2345}”,您无法访问变量要么因为它只是一个shell变量而不是环境变量,而且无论如何只会在你的进程退出后设置。
  • 我明白了。我什至跑了 ./startServer -ip 10.78.242.4 'tcpip{ldap=no;port=2435}' ;ls 并在我的进程退出后运行了“ls”命令。如果有人运行一些有害命令(如 rm)怎么办?有没有办法防止这种情况发生?
  • 是的,永远,永远,永远,永远,永远,永远,永远,永远,永远将不受信任的输入传递给命令行shell而不对其进行清理,例如legalhackers.com/advisories/…
  • 但是当我无法访问“;”之后的命令行参数时,如何清理此处的参数列表?
【解决方案2】:

需要不仅引用;,而且在一般情况下还引用{}

./startServer -ip 10.78.242.4 'tcpip{ldap=no;port=2435}'

如果您的用户需要输入那个复杂的最后一个参数,那么他们也可以被要求引用它。

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    相关资源
    最近更新 更多