我在.bashrc中定义了以下awk函数:
? () { awk "BEGIN{ pi=3.14159265359; printf \"%5.5f\n\", $* }" ; }
当我在包含单字母目录的目录中执行此函数时,这会给我一个错误。
> ls
B
> ? "1+2"
B: command not found # B refers to the one-letter dir?
如果在不包含任何单字母目录的其他目录中执行,该函数可以正常工作。
我也做了一些进一步的测试。当我在包含单字母文件的目录中执行此函数时,这也给了我错误:
> ? "1+2"
-bash: ./B: Permission denied # B now refers to a file
有谁能告诉我这里出了什么问题?
答案 0 :(得分:4)
你错了。 ?
具有shell解释为的特殊含义,意味着匹配单个字符。这就是扩展导致单个字符文件名的原因,即在shell查找函数或命令之前发生全局扩展。如果有这样的文件具有单个字符名称,它将扩展为文字字符串?
来自man bash
Pathname Expansion
分词后,除非设置了
-f
选项,否则bash会扫描 字符*
,?
和[
的每个单词。如果其中一个字符 出现,然后该单词被视为一个模式,并替换为与模式匹配的按字母顺序排列的文件名列表特殊模式字符具有以下含义:
?
匹配任何单个字符。
建议使用awk
导入shell变量选项-v
来导入args而不是使用双引号来避免必须处理特殊情况。还要考虑使用比任何shell元字符更好的函数名称
awkf () { awk -v argv="$*" 'BEGIN{ pi=3.14159265359; printf "%5.5f\n", argv }' ; }
但对于像表达式中使用字符串1+2
这样的简单计算器的用例,可以正确使用双引号
awkf () { awk "BEGIN{ pi=3.14159265359; printf \"%5.5f\n\", "$*" }" ; }