使用Ruby'捕捉ANSI彩色输出;s Open3/Process.spawn()
我正在使用使用Ruby'捕捉ANSI彩色输出;s Open3/Process.spawn(),ruby,ansi-escape,Ruby,Ansi Escape,我正在使用sass lintNPM包对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, outp
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
(或节点)检测到它没有在TTY中运行,因此输出纯文本。是否有一些Process.spawn()
选项可以传递到Open3.capture2e()
,或者其他一些方法,通过这些方法我可以让它认为它正在TTY中运行
(注意:我确实看过,但是macOS附带的脚本的BSD版本似乎不支持--return
或-c
选项,我正在macOS上运行。)
更新:我根据尝试了脚本-q/dev/null
和PTY.spawn()
,但没有成功
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
子流程似乎永远不会完成;如果在另一个终端中Ips
,则显示为可中断睡眠状态。终止子进程不会释放父进程
块形式也是如此
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
您是否考虑过使用Ruby的优秀库而不是Open3
伪终端,per,似乎模拟了一个实际的TTY,因此脚本不会知道它不在终端中,除非它检查像$TERM
这样的东西,但是这也可以相对容易地被欺骗
根据,使用pty
而不是Open3
的缺点是STDERR
没有自己的流
或者,根据,也可以从您链接的线程中,script-q/dev/null$命令
在Mac OS X上执行此操作
在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 >
$touch常规\u文件
$touch可执行文件
$mkdir目录
$chmod+x可执行文件
$irb
2.4.1:001>要求“Open3”
=>正确
2.4.1:002>输出,状态=Open3.capture2e(“ls-G”)
=>[“目录\n可执行的\n常规\n文件”,#]
2.4.1:003>输出,状态=Open3.capture2e(“脚本-q/dev/null ls-G”)
=>[“^D\b\b\e[1m\e[36M目录\e[39;49m\e[0m\e[31mexecutable\U文件\e[39;49m\e[0m常规\r\n”,#]
2.4.1 :004 >
尝试了这两种方法,但都没有成功。:(请参阅更新。但我可能没有正确调用PTY.spawn()
/Process.wait2()
。@DavidMoles-Hmm,不确定脚本-q/dev/null…
不起作用,但让我看看是否能找出你的PTY.spawn()有什么问题)
ing.@DavidMoles我试着运行以下命令:lines=[];PTY.spawn(“ls-G&&sleep 5”){reader,writer,pid{reader。如果将script-q…
命令行导入cat,那么每一行代码都可以从命令行运行?