簡體   English   中英

Elixir - 從命令行運行時,記錄器 output 是彩色的,從 iex 運行時不是這樣

[英]Elixir - Logger output is colorful when run from command line, not so when run from iex

在我的 Elixir 混合應用程序中運行測試時,我有一些實例包括對Logger.debug()的一些調用以監視行為。 我發現,當我從命令行調用mix test時,Logger output 是淺藍色的,如果我在.debug()調用中添加自定義顏色,output 會相應地着色 -

test "some behavior" do
  Logger.debug("foo", ansi_color: :yellow)
  assert true
end

正如預期的那樣,以黃色寫入日志行。

但是,我注意到,如果我從iex session 中運行測試,則不會應用 colors,只是以默認字體顏色(在我的情況下為灰色)寫入終端 -

iex(1)> Mix.shell().cmd(
          "mix test --color",
          env: [{"MIX_ENV", "test"}]
        )

為什么從 bash 命令行運行測試會導致彩色 output,而從 iex 中運行它們會導致我的默認字體顏色?

對於上下文 - 我在 Mac (Mojave) 上運行此程序,來自 bash 命令行(如前所述),Elixir 版本 1.8.1。

Admittedly, this is a fairly trivial matter in itself - but I'm trying to get a better understanding of the Elixir shell and Mix's various interactions with the shell and system, and cracking this might help me to get a better understanding of what's going on一般在引擎蓋下。 這不是我所期望的,我想知道為什么。

解釋在thisthis article中,但TL; DR如下:

您需要通過以下方式在iex中啟用 colors:

iex> Application.put_env(:elixir, :ansi_enabled, true)

但這只是 session scope。 如果要使其永久化,則需要在當前目錄或主目錄中創建.iex.exs文件:

timestamp = fn ->
  {_date, {hour, minute, _second}} = :calendar.local_time
  [hour, minute]
  |> Enum.map(&(String.pad_leading(Integer.to_string(&1), 2, "0")))
  |> Enum.join(":")
end

IEx.configure(
  colors: [
    syntax_colors: [
      number: :light_yellow,
      atom: :light_cyan,
      string: :light_black,
      boolean: :red,
      nil: [:magenta, :bright],
    ],
    ls_directory: :cyan,
    ls_device: :yellow,
    doc_code: :green,
    doc_inline_code: :magenta,
    doc_headings: [:cyan, :underline],
    doc_title: [:cyan, :bright, :underline],
  ],
)

IEx.configure(
  default_prompt:
    "#{IO.ANSI.green}%prefix#{IO.ANSI.reset} " <>
    "[#{IO.ANSI.magenta}#{timestamp.()}#{IO.ANSI.reset} " <>
    ":: #{IO.ANSI.cyan}%counter#{IO.ANSI.reset}] >"
)

就這樣

推理很簡單 - 當標准輸出在連接到標准輸出的“真實”終端和 pipe 或文件時運行時,標准輸出具有不同的特性。 運行時可以看到相同的行為:

mix test | cat

因為這將附加 pipe,而不是“真正的”終端(實際上它是終端仿真器,但這不在問題的 scope 范圍內)。 這意味着 Elixir 不能假設生成的 stream 將支持 ANSI 轉義碼。 當您使用 pipe 命令來分隔工具或文件以進行進一步處理時,這一點很重要,因為這些工具中的許多工具不理解 ANSI 轉義碼並會導致錯誤的結果。

IEx中運行mix test並保留所有當前配置的最佳方法是簡單地執行以下操作:

Mix.Task.rerun(:test)

這將重用當前配置。 當然,它會在當前環境下運行,但也可以通過運行MIX_ENV=test iex -S mix來訪問 shell 中的整個測試環境。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM