解释Ruby的Kernel :: system方法的其他参数

时间:2013-08-01 22:39:40

标签: ruby

为什么第一个摘录成功而第二个摘录失败?

system 'emacs', '--batch', '--quick', '--eval="(require \'package)"'

system 'emacs --batch --quick --eval="(require \'package)"'

(如果重要的话,我正在使用Ruby版本1.8.7和Emacs版本22.1.1在Mac OS X Mountain Lion上执行代码。)

1 个答案:

答案 0 :(得分:1)

首先,这两个system来电是不同的,你可能没想到。一个简单的例子可能会比一堆词和挥手更好地解释差异。从一个简单的shell脚本开始:

#!/bin/sh
echo $1

我称之为pancakes.sh,因为我比foo更喜欢煎饼。然后我们可以进入irb,看看发生了什么:

>> system('./pancakes.sh --where-is="house?"')
--where-is=house?
>> system('./pancakes.sh', '--where-is="house?"')
--where-is="house?"

你看到了显着的差异吗? system的单个参数形式将整个字符串交给/bin/sh进行处理,而/bin/sh将以自己的方式处理双引号,因此被调用的程序将永远不会看到它们。 system的多参数形式不会调用/bin/sh来处理命令行,因此参数将按原样传递,双引号保持不变。

返回system来电。第一个将这个确切的参数发送给emacs(请注意Ruby将负责将\'转换为'}:

--eval="(require 'package)"

emacs将尝试评估"(require 'package)";对我来说,看起来更像是一个字符串而不是一个elisp片段,并且评估一个字符串文字并没有做任何事情。您的第二个将发送给emacs

--eval=(require 'package)

emacs会抱怨它

  

无法打开加载文件:package

请注意,我的elisp知识被埋没了大约20年的生锈和遗忘,因此一些emacs细节可能有点偏离。