Linux基礎知識:lsコマンドのカラー引数の挙動差

--color=autoと--color=alwaysの挙動差

公開日: 2022-02-26
更新日: 2024-02-26

  Table of Contents

記事の目的

任意のディレクトリに属するファイルやサブディレクトリを確認する際に使用するlsコマンドについて、 --color=auto--color=alwaysをoptionに指定すると、ファイルやディレクトリごとに色分けしてターミナルに出力してくれますが、 このautoalwaysの挙動差はなんなのかを調べたいと思います.

ls --color=xxxの仕組み

まず、マニュアルから確認します.

1
2
3
4
5
6
7
8
9
10
11
12
% man ls
DESCRIPTION
    --color[=WHEN]
              colorize  the  output;  WHEN  can  be  'always'  (default  if omitted), 'auto', or
              'never'; more info below
...
()
...
Using color to distinguish file types is disabled both by default and with --color=never.
       With  --color=auto, ls emits color codes only when standard output is connected to a ter‐
       minal.  The LS_COLORS environment variable can change the settings.   Use  the  dircolors
       command to set it.

このマニュアルを読む感じわかることは以下です:

  • Ubuntu 20.04 LTSでは、デフォルトでは--colorはdisabledされている
  • --colorを指定するとデフォルトの挙動は--color=always
  • --color=autoは標準出力先がTerminalの場合、カラー出力をしてくれるがそれ以外はしてくれない
  • --color=alwaysは標準出力先がTerminal以外の場合でも、カラー出力をしてくれる

「標準出力先がTerminalの場合」とはなにを指しているのか?

Terminal上への出力:挙動差なし

このGithub Pagesブログのワークスペースディレクトリを例にまずコマンドの挙動を確認してみます:

このようにTerminal上でファイル要素を確認する場合は挙動差はありません.


パイプを用いて、出力結果を表示: 挙動差あり


リダイレクトを用いて、出力結果をテキストへWRITE:挙動差あり

次に、リダイレクトを用いて、lsの出力結果をテキストへ吐き、そのテキストを確認してみます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
% ls --color=always -C > test.txt && nano test.txt
404.html      feed.xml      ^[[0m^[[01;34m_includes^[[0m/  offline.html       README.md
about.html    ^[[01;34mfonts^[[0m/        index.html  package.json       search.json
archive.html  Gemfile       ^[[01;34mjs^[[0m/         package-lock.json  ^[[01;34m_site^[[0m/
_config.yml   Gemfile.lock  ^[[01;34m_layouts^[[0m/   ^[[01;34m_posts^[[0m/            sw.js
^[[01;34mcss^[[0m/          Gruntfile.js  ^[[01;34mless^[[0m/       ^[[01;34mpwa^[[0m/               test.txt
^[[01;34m_doc^[[0m/         ^[[01;34mimg^[[0m/          LICENSE     Rakefile

% ls --color=auto -C > test.txt && nano test.txt 
404.html      feed.xml      _includes/  offline.html       README.md
about.html    fonts/        index.html  package.json       search.json
archive.html  Gemfile       js/         package-lock.json  _site/
_config.yml   Gemfile.lock  _layouts/   _posts/            sw.js
css/          Gruntfile.js  less/       pwa/               test.txt
_doc/         img/          LICENSE     Rakefile
  • ls --color=alwaysの場合は、テキストへ出力された結果に文字列だけでなく、カラーコードも合わせて出力されています
  • ls --color=autoの場合は、文字列のみ

--color=alwaysを使用する場面の紹介

  • Shellはzsh
  • OSはDebian系(Ubuntu 20.04 LTS)

という前提条件のもと, 以下のような挙動をするlsを定義したいと思います

  • cdコマンド実行時にファイル, lsを同時に実行する
  • 出力結果は、ファイルやディレクトリの種類に応じて色分けされた形にしたい(--color=always--color=autoと同じ)
  • 出力行数が多いときは…で省略する

zshrcの設定例の紹介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
## ファイル数が多い時には省略表示
ls_abbrev() {
    local cmd_ls='ls'                  # コマンドを格納するlocal変数を定義
    local -a opt_ls                    # optionを格納するlocal変数の箱をarray型で定義
    opt_ls=('-CF' '--color=always')   # option local変数を代入

    local ls_result
    ## CLICOLOR_FORCE=1でcolor出力を渡す
    ls_result=$(CLICOLOR_FORCE=1 COLUMNS=$COLUMNS command $cmd_ls ${opt_ls[@]} | sed $'/^\e\[[0-9;]*m$/d')

    local ls_lines=$(echo "$ls_result" | wc -l | tr -d ' ') #出力結果の行数をカウント

    if [ $ls_lines -gt 10 ]; then                           #出力行数が11以上か未満で省略を切り分ける
        echo "$ls_result" | head -n 5
        echo '...'
        echo "$ls_result" | tail -n 5
        echo "$(command ls -1 -A | wc -l | tr -d ' ') files exist"
    else
        echo "$ls_result"
    fi
}

autoload -Uz add-zsh-hook               # hook関数の呼び出しをOKにする
add-zsh-hook chpwd ls_abbrev            # chpwd(カレントディレクトリが変更したとき)をトリガーに ls_abbrevを実行する

挙動確認

1
2
3
% mkdir test && cd test
% touch foo_{01..40}.txt && mkdir hoo_{01..40}
% cd ./

現在の設定(2024.02.26追記)

現在は.zshrcに以下のような alias設定 だけで済ませています

1
alias ls='ls -F --color=auto --group-directories-first'

なお, 一時的にフックしないでデフォルトのlsを実行したい場合は

1
% \ls

と入力することで一時的に alias を解除した実行が可能となります(=次のコマンドからはalias設定が再び有効になる). 恒久的にalias解除したい場合はunaliasコマンドを用いますが, 使う場面はあんまりありません.

References



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)