如何“查看”bash命令行参数扩展?

时间:2010-08-02 16:28:51

标签: perl bash

我希望Perl脚本接受文件名的通配符(foo - * .ba?)(然后为整个目录子树处理)。

当然,我可以告诉我的脚本用户引用参数('foo - * .ba?'),但这不是很优雅 - 通配符方法是一种用户友好的替代方法来传递正则表达式(也被接受,当然,必须引用)。麻烦的是,shell(在我的情况下是bash)将命令行扩展到与当前目录中的通配符模式匹配的文件,所以我的可怜脚本使用bash找到的任何内容获得@ARGV预设(通常没有,或者一堆) of foo-lotsof.baz等。)。

在任何地方都有bash未展开命令行的副本吗?

5 个答案:

答案 0 :(得分:4)

请不要尝试来解决此问题。更改参数的解释方式由用户在选择引用时完成。即使你可以(而且我知道bash中有钩子,我对此没有任何了解可能会使它成为可能)你不会以这种方式提供更好的用户体验,你会提供更糟糕的。

答案 1 :(得分:4)

根据bash手册页,您可以禁用字符扩展* ,?和[使用-f开关。请参阅路径名扩展。

$ bash -f -c 'ls *'
ls: *: No such file or directory

但是你必须要求你的用户改变他们开始bash的方式,或者你必须尝试控制它。它只是改变了问题。

你的程序应该处理shell行为,而不是相反。

编辑:作为最后的评论,我想指出,使用单引号是unix shell中的常见做法,以防止扩展。你不应该害怕用你自己的剧本做同样的事情。

答案 2 :(得分:3)

我担心没有简单的办法解决这个问题。 bash在执行命令之前扩展通配符。这就是为什么你必须引用find -name '*.txt'的参数 - 如果你没有bash将尝试扩展通配符而你得不到你想要的结果

答案 3 :(得分:3)

对于提出这个问题的人来说,只有一个额外的答案是找不到任何帮助: 考虑我的防止通配符扩展的解决方案(通配),here

this related answer概述了它的关键。

答案 4 :(得分:2)

Bash扩展通配符然后将它们传递给程序。这是bash的功能,它就是bash的工作原理,所以我认为你无法找到解决方法。 (有趣的是,Windows的命令行shell不会扩展通配符,所以你必须做一些令人痛苦的解决方法才能让Perl脚本按预期工作。)

引用文件名是标准解决方案,Linux命令行用户应该非常熟悉它。

其他程序(例如find(1))具有需要引用带有通配符的参数的相同问题。

(即使你可以找到一些方法从你的Perl脚本中查询bash的命令行历史记录,以便在用户输入命令时找到命令,你仍然会遇到从其他shell运行脚本的问题,其他脚本,等)