2010-06-03 59 views
3

使用ruby文件(或任何rake工具)我需要确定执行我的脚本的用户是否能够执行某些shell命令。尤其是g ++等。希望系统独立,所以如果有一些g ++ .bat,g ++。exe或者g ++(etc),它应该说是,只要它在用户系统上的路径和可执行文件上。通过ruby文件确认可执行文件(script,bat,cmd,exe)的存在

例如:如果用户有一个不扩展的可执行版本的文件和一个.cmd版本的文件,它应该在linux系统上为“no”扩展版本说“yes”,在.cmd里为“yes”在Windows系统上的版本。由于用户shell只能执行该版本的文件。

这样做的目的是允许脚本自行配置(尽可能)。

关于我如何去做这件事的任何建议?

回答

4

一个快速和肮脏的方式是简单地尝试通过system要执行的命令g ++以及检查返回代码,例如:

def gpp_exists 
    return system("g++ --version") 
end 

你不得不做一些技巧以避免在控制台上得到不需要的输出(例如,根据正确的操作系统语法重定向标准输出/标准错误),但它不会太糟糕。

+0

嗯,我考虑过了,但被'system“推迟了g ++”'返回false。没有考虑'--version',这是一个好主意,而且更具体地说,比我的方法更好。 – 2010-06-03 22:09:08

+1

+1。通常,检查你是否可以运行一些可执行文件的最好方法是运行该死的可执行文件。毕竟,即使* if *你检查它是否存在*和*它是可执行的*并且*它在路径中,为什么它不起作用还有很多原因:权限,资源限制,错误的库版本,由于文件系统错误而损坏的可执行文件,没有足够的内存... – 2010-06-03 22:22:58

+0

在Rake中有一个和上面的系统非常相似的命令sh。这就是我已经尝试过的,因为它可以传递给结果和状态,但是我的两个问题是,首先你认为 - 在那里,我应该没有通过任何我会假设它退出;第二我似乎无法想到一种(通用)方法来防止输出到用于执行脚本的shell。 – srcspider 2010-06-04 04:00:48

2

那么,File包含exists?executable?ENV['PATH']获取可执行文件所在的目录(至少在* nix - 有人可以确认Windows?)。将这两者结合一点魔力,你应该有一个解决方案。

编辑:

irb(main):001:0> ENV['PATH'].split(':').collect {|d| Dir.entries d if Dir.exists? d}.flatten.include? 'adduser' 
=> true 
irb(main):002:0> ENV['PATH'].split(':').collect {|d| Dir.entries d if Dir.exists? d}.flatten.include? 'foo' 
=> false 
+0

只有1.9说(但不是一个问题)。问题是扫描路径并不能真正说明脚本之间的区别。例如,我可以执行“g ++ --version”,但将g ++作为输入将会产生错误。现在我可以测试一个部分匹配,但这可能会导致问题,我不觉得它值得这个怪癖。 – srcspider 2010-06-04 03:56:26

+0

对不起,你是什么意思的“脚本之间的差异”? 'ENV ['PATH']。split(':')。collect {| d |如果Dir.exists存在Dir.entries? d} .flatten.include? 'g ++''在我的机器上返回true。 – 2010-06-05 01:13:00

+0

我在Windows XP上测试过它,但它没有工作。在文件中有以下行:puts ENV ['PATH']。split(':')。collect {| d |如果Dir.exists存在Dir.entries? d} .flatten.include? “海湾合作委员会”。返回false。从命令行gcc --version是:gcc(TDM-2 mingw)4.4.1和ruby --version是:ruby 1.9.1p376。 – srcspider 2010-06-08 07:53:08

1

我需要类似的东西(它可以在路径中执行)并使用系统命令,但检查返回的错误代码。根据本公司标准的结果在UNIX(127 =找不到文件)stackoverflow standard unix return codes

def checkinstalled(program) 
     stdop=system(program) 
     result=$? 
     exit_code=result.exitstatus 
     return !exit_code.eql?(127) 
    end 

不能用于Windows然而