我使用sass-lint NPM包在Rake任务中对.scss文件进行样式检查,因此:
sass_lint_cmd = "sass-lint --config #{ui_library_path}/scss/.sass-lint.yml '#{ui_library_path}/scss/*.scss' -v -q --max-warnings=0"
output, status = Open3.capture2e(sass_lint_cmd)
raise IOError, output unless status == 0这基本上是起作用的,因为在发生任何linter警告或错误时,Rake任务中止,sass-lint输出(包括错误)被转储到控制台。
但是,当直接运行时,sass-lint会产生漂亮的彩色输出。当被capture2e捕获时,颜色就会丢失。
我假设问题是sass-lint (或Node)检测到它没有在TTY中运行,所以输出纯文本。是否有一些Process.spawn()选项可以传递给Open3.capture2e(),或者其他一些方法,可以让它认为它在运行在TTY中?
(注意:我确实看过Trick an application into thinking its stdout is a terminal, not a pipe,但是macOS附带的script的BSD版本似乎既不支持--return也不支持-c选项,而且我运行在macOS上。)
更新:--我尝试了script -q /dev/null和PTY.spawn(),就像Piccolo's answer一样,但没有成功。
script -q /dev/null …从命令行工作,但在Open3.capture2e()中不工作(它运行,但产生单色输出和虚假的Bundler::GemNotFound堆栈跟踪)。
对于PTY.spawn(),用以下代码替换上面的代码:
r, _w, pid = PTY.spawn(scss_lint_command)
_, proc_status = Process.wait2(pid)
output, status = [r, proc_status.exitstatus]
(warn(output); raise) unless status == 0子进程似乎从未完成;如果我在另一个终端中ps,则显示为处于可中断的睡眠状态。杀死子进程并不能释放父进程。
同样的情况发生在块表单中。
output, status = nil
PTY.spawn(scss_lint_command) do |r, _w, pid|
_, proc_status = Process.wait2(pid)
output, status = [r, proc_status.exitstatus]
end
(warn(output); raise) unless status == 0发布于 2018-07-25 22:02:11
你有没有考虑过使用Ruby的优秀pty库而不是Open3
按照the thread you linked的说法,伪终端似乎模拟了一个实际的TTY,所以脚本不会知道它不在终端中,除非它检查了$TERM之类的东西,但这也可以相对容易地被欺骗。
根据this flowchart的说法,使用pty而不是Open3的缺点是STDERR没有自己的流。
或者,根据this answer,也是从您链接的线程中,script -q /dev/null $COMMAND似乎在Mac上完成了这个任务。
在Mac上,ls -G对ls的输出进行着色,作为一个简短的测试,我将ls -G插入cat中,如下所示:
script -q /dev/null ls -G | cat它以颜色显示,而简单地运行
ls -G | cat却没有。
此方法在irb中也有效,同样使用ls -G。
$ touch regular_file
$ touch executable_file
$ mkdir directory
$ chmod +x executable_file
$ irb
2.4.1 :001 > require 'Open3'
=> true
2.4.1 :002 > output, status = Open3.capture2e("ls -G")
=> ["directory\nexecutable_file\nregular_file\n", #<Process::Status: pid 39299 exit 0>]
2.4.1 :003 > output, status = Open3.capture2e("script -q /dev/null ls -G")
=> ["^D\b\b\e[1m\e[36mdirectory\e[39;49m\e[0m \e[31mexecutable_file\e[39;49m\e[0m regular_file\r\n", #<Process::Status: pid 39301 exit 0>]
2.4.1 :004 >https://stackoverflow.com/questions/51527732
复制相似问题