如何在bash中将星号字符'*'作为参数传递给我的C程序?

37

假设我有一个C程序,并从bash中运行它:

$ ./a.out 123 *

这个程序会输出所有命令行参数,但它会显示如下信息:

Argument 1: 123
Argument 2: a.out

我该如何在我的程序中修复这个问题?


1
可能是 https://dev59.com/fXE85IYBdhLWcg3wikS- 的重复问题。 - polygenelubricants
我对这个问题有些犹豫,@polygene。它确实很相似,但另一个问题只是想了解为什么 * 不起作用。而这个问题想知道是否有一种方法可以在 C 代码本身中修复它。经过长时间的煎熬和咬牙切齿,我的观点是这些问题足够不同,值得保持原样。 - paxdiablo
5个回答

44

Shell会用目录中每个文件的名称替换星号。

要传递一个字面上的星号,您应该能够对其进行转义:

$ ./a.out 123 \*

我明白那样做可以行得通,但我想知道是否有什么方法可以在不改变参数传递方式的情况下在我的C程序中实现。 - Yz Chong
@Yz:我不是Bash专家,我的猜测是“不容易”。 - James McNellis
8
我是一名Bash专家,我的答案是“不!” :-) 我会给反斜杠的解决方案点一个赞——在我看来,这是首选,因为引号会防止变量扩展。反斜杠转义单个字符不会产生这种副作用。 - paxdiablo
2
您可以运行 bash -f 来完全禁用通配符/文件名扩展,尽管我不太确定这是否是 OP 想要的。 - clstrfsck
3
詹姆斯说得对。在C语言中无法处理这个问题,因为shell会在调用程序之前替换*。C程序无法确定是传递了通配符还是手动输入的文件列表(在这种情况下)。为了将纯粹的*传递给C程序,您需要进行转义(即告诉shell不要像通常那样展开它),使用\\* - bta

30

另一个选项是使用set -f来关闭扩展。比较一下:

echo *

相对比

set -f
echo *

您可以使用set +f重新开启它:

set -f
echo *
set +f
echo *

22

你可以在 shell 中引用它

./a.out 123 '*'

你的程序中无法做任何事情,因为星号扩展是由Shell完成的(与Windows相比,Windows中它是由程序完成的)。


6
没错。在调用可执行文件之前,Shell会扩展元字符,因此你的程序不知道用户键入了星号。这是很好的标准Unix行为,你不需要“修复”它。如果你不希望Shell扩展元字符,可以使用\进行转义,或将参数放在单引号内。 - leonbloy

6
另一个选择是在脚本的第一行写上#!/bin/bash -f,这将允许您接受字面字符串作为参数(包括星号),从而使您能够以所需的输入运行./a.out 123 *,但请注意bash -f会完全禁用扩展,这可能会对您的脚本产生不利影响,具体取决于您所做的事情。

5

这与你的程序无关。

* 是 Bash 中的通配符,表示“当前目录中的所有文件”。如果您想将星号作为参数传递给您的程序,可以像其他程序一样进行转义或加引号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接