我想从一个bash中执行许多Rakefile命令。
我已经在我的Rakefile中尝试了以下几种方法
task :hello do
%{echo "World!"}
end但是在执行rake hello时没有输出?如何从Rakefile执行bash命令?
注意到:这不是重复,因为它专门询问如何从Rakefile执行bash命令。
发布于 2013-01-16 14:19:58
我认为rake希望这种情况发生的方式是:方法示例:
task :test do
sh "ls"
end内置的rake函数sh负责命令的返回值(如果命令的返回值大于0,则任务失败),此外,它还输出命令输出。
发布于 2012-03-20 22:35:44
在ruby中有几种执行shell命令的方法。一个简单的方法(可能也是最常见的)是使用backticks:
task :hello do
`echo "World!"`
endBackticks在shell命令的标准输出变成返回值时有很好的效果。因此,例如,您可以通过
shell_dir_listing = `ls`但是,还有许多其他方法来调用shell命令,它们都有优缺点,工作方式也不同。这篇文章详细解释了各种选择,但这里有一个简短的总结可能性:
发布于 2015-12-30 05:21:52
考虑到大家似乎更喜欢rake的#sh方法,但是OP显式地请求bash,这个答案可能有一些用处。
这是相关的,因为Rake#sh使用Kernel#system调用来运行shell命令。Ruby将其硬编码为/bin/sh,而忽略了环境中用户配置的shell或$SHELL。
下面是一个从/bin/sh调用bash的解决方法,允许您仍然使用sh方法:
task :hello_world do
sh <<-EOS.strip_heredoc, {verbose: false}
/bin/bash -xeu <<'BASH'
echo "Hello, world!"
BASH
EOS
end
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
end
end#strip_heredoc是从rails借来的:
您可能通过需要active_support来获得它,或者在rails项目中它是自动加载的,但是我在rails之外使用它,所以我不得不自己开发它。
有两种遗传,一种是带有标记EOS的外部遗传,另一种是带有标记BASH的内部遗传。
它的工作方式是在BASH的stdin之间添加bash标记之间的内部黑道文件。注意,它是在/bin/sh上下文中运行的,所以它是一个posix,而不是红宝石。通常,这要求结束标记位于第1列中,但由于缩进,这里的情况并非如此。
但是,因为它是包装在ruby中的,所以strip_heredoc方法应用于其中,在/bin/sh看到它之前,将其内部的左侧全部放置在第1列中。
/bin/sh通常也会在本地文档中展开变量,这可能会干扰脚本。开始标记' bash‘周围的单引号告诉/bin/sh在将它传递给bash之前不要扩展它的任何内容。
然而,在将字符串传递给bash之前,/bin/sh仍然将转义方法应用于字符串。这意味着反斜杠转义必须加倍才能通过/bin/sh进行bash,即\变成\\。
bash选项-xeu是可选的。
-eu参数告诉bash在严格模式下运行,这将在任何失败或对未定义变量的引用时停止执行。这将返回一个错误到rake,这将停止rake任务。通常,这就是你想要的。如果您想要正常的bash行为,可以删除这些参数。
bash和{verbose: false}参数的{verbose: false}参数对#sh的作用是一致的,因此rake只打印实际执行的bash命令。如果bash脚本不打算全部运行,例如,如果它有一个测试,允许它在脚本的早期优雅地退出,这是非常有用的。
如果不希望rake任务失败,请注意不要设置除0之外的退出代码。通常,这意味着您不希望在没有显式设置退出代码(即|| exit )的情况下使用任何|| exit 0结构。
https://stackoverflow.com/questions/9796028
复制相似问题