这是Ruby解析器的错误吗?

时间:2016-01-18 08:51:26

标签: ruby bash

我已经减少了我面对MWE的问题。任何人都可以确认这是一个错误还是我遗漏了一些不成熟的东西?

平台

  • Ruby 1.9.3p484(2013-11-22修订版43786)[x86_64-linux]
  • GNU bash,版本4.3.11(1)-release(x86_64-pc-linux-gnu)
  • Ubuntu 14.04.2 x86_64

第1步:创建一个名为demo.rb

的Ruby脚本
puts "[Line 1]"
puts "* [Line 2] *"

第2步:创建名为driver

的驱动程序脚本,如下所示
#!/bin/bash

ret=`ruby ./demo.rb `
echo $ret

第3步:将上面的文件移到空文件夹中。

第4步:从driver运行bash。如您所见,它会在每个puts调用时列出父目录的内容。

$ ./driver
[Line 1] demo.rb driver [Line 2] demo.rb driver

第5步:如果直接从demo.rb执行bash,则会产生:

$ ruby demo.rb 
[Line 1]
* [Line 2] *

现在,从*第二行puts字符串的两端删除星号(demo.rb):

puts "[Line 1]"
puts " [Line 2] "

如果我重复步骤4,

$ ./driver 
[Line 1] [Line 2]

如果我重复步骤5,

$ ruby demo.rb 
[Line 1]
 [Line 2] 

我无法理解以下内容:

  1. 为什么输出首次包含目录列表?
  2. 为什么删除星号会在第二次尝试中抑制目录列表?
  3. 如果我分别重复步骤4和步骤5,为什么第二次尝试的输出会有所不同?

2 个答案:

答案 0 :(得分:7)

1& 2:与Ruby无关,与Bash有关。 *glob,在bash命令中显示时会扩展到文件名列表。试试这个:

$ echo *
$ a="*"; echo $a
$ a="DIR: * ; DIR AGAIN: *"; echo $a

3:因为echo打印由空格分隔的参数;和换行符被视为空格。看看这个:

$ a=`cat /etc/services`
$ echo $a
$ echo "$a"

echo $a会将所有线条合并成一条线。如果使用双引号,则可以保护$a的内容作为一个参数进行处理,并保留换行符。 (相同的逻辑适用于echo "$ret"

答案 1 :(得分:2)

看起来像我的标准全球扩展行为。

在shell脚本中执行echo $ret时,字符串中的*会扩展为目录的内容。

如果您在echo "$ret"周围加上引号,那么您只会在输出中看到文字*。您还会看到变量中的空格被保留(回答您问题中的第三点)。

这是你应该总是引用变量的原因之一!