【问题标题】:shell tilde expansion does not work when passed as an option作为选项传递时,shell 波浪号扩展不起作用
【发布时间】:2013-03-07 19:10:41
【问题描述】:

我发现波浪号扩展不适用于以下情况:

$ set -x

$ ./print_arg.pl destdir=~/test
+ ./print_arg.pl 'destdir=/root/test'
destdir=/root/test

$ ./print_arg.pl dest-dir=~/test
+ ./print_arg.pl 'dest-dir=~/test'
dest-dir=~/test

$ ./print_arg.pl -destdir=~/test
+ ./print_arg.pl '-destdir=~/test'
dest-dir=~/test

print_arg.pl 的内容是

#!/usr/bin/perl
print $ARGV[0],"\n";

根据Order of Shell processing,Shell 将在“波浪号扩展”之前拆分单词。我注意到分词实际上是不同的。结果不同的原因是什么?

【问题讨论】:

    标签: shell tilde-expansion


    【解决方案1】:

    波浪号扩展也发生在 shell 变量赋值中,destdir=~/test 类似于。 dest-dir=~/test-destdir=~/test 不这样做,因为 - 不是变量名中的有效字符。尽管 shell 没有将 destdir=~/test 评估为变量赋值(如果使用了 set -k,它会评估),但解析器似乎仍在处理它并在 RHS 上执行波浪号扩展。

    来自http://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html#Tilde-Expansion

    每个变量赋值都会检查紧跟在“:”或第一个“=”之后的未加引号的波浪号前缀。在这些情况下,也执行波浪号扩展。因此,可以在分配给 PATH、MAILPATH 和 CDPATH 时使用带波浪号的文件名,并且 shell 分配扩展值。

    请注意,使用-k 选项集,正确的变量赋值会被处理并从传递给print_arg.pl 的参数列表中删除:

    ~ $ set -kx
    ~ $ ./print_arg.pl destdir=~/bin foo
    + destdir=/Users/clint/bin
    + ./print_arg.pl foo
    foo
    ~ $ ./print_arg.pl dest-dir=~/bin foo
    + ./print_arg.pl 'dest-dir=~/bin' foo
    dest-dir=~/bin
    

    【讨论】:

    • 我还注意到这句话“解析器标记为变量赋值的词(命令名之前的那些)和重定向被保存以供以后处理。”因此,命令后的“destdir=~/test”可能不会被标记为可变分配。那怎么解释呢?
    • 由于set -k shell 选项,它可能是一个变量赋值。我的猜测是解析器不会检查是否设置了该选项,并标记任何可能是有效分配的东西。根据set -k,解析完成后(包括波浪号扩展),负责评估已解析命令的代码可以检查是否应评估命令后的赋值。有人可能会争辩说,在第一次识别变量赋值时忽略 set -kbash 中的一个错误。
    • 我明白了。感谢您的精彩解释。
    • 这也会影响mycmd --longopt=~/some/path 等模式。要使用波浪号扩展,如果您的命令的长选项格式支持它,您通常可以省略“=”:mycmd --longopt ~/some/path。否则,您必须在子shell中手动展开它:mycmd --longopt=$(expr ~/some/path)
    猜你喜欢
    • 2012-06-20
    • 1970-01-01
    • 2012-01-16
    • 2017-06-15
    • 2021-02-03
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    相关资源
    最近更新 更多