世界を動かす技術を、日本語で。

シェルコロンは何もしないが、使ってみよう

2026年7月25日原文(refp.se)

概要

  • シェルスクリプトで頻繁に使われる コロン(:) コマンドの奥深さを解説
  • パラメータ展開 との組み合わせによる省略記法やエラー処理の効率化
  • nullコマンド としての使い道や歴史的背景
  • 実用例とよくある疑問への回答
  • 実際の現場での :(コロン) の活用例も紹介

シェルスクリプトにおけるコロン(:)の魔法

  • :(コロン) はシェルの nullコマンド、何もしないが引数の評価だけ行う
  • 1971年のThompson shell から存在する歴史あるコマンド
  • シェルスクリプト内で 省略記法ダミーコマンド として活躍
  • パラメータ展開 と組み合わせてエラー処理やデフォルト値設定が簡潔に
  • 例:必須引数のチェック
    • 従来:
      if [ -z "$1" ]; then
        echo "missing argument, aborting." 1>&2
        exit 1
      fi
      
    • コロン活用:
      : "${1:?missing argument, aborting.}"
      
  • 変数名を使うことで、エラー時に 変数名も表示 され診断が容易

パラメータ展開と :? の関係

  • ${name:?診断メッセージ}という書き方で、 変数未設定や空の場合にエラー出力&終了
  • 変数が設定されていれば その値を返却
  • :(nullコマンド) と組み合わせることで、評価結果をコマンドとして実行せずに 評価と副作用だけを利用

nullコマンド(:)の多彩な使い道

  • デフォルト値の設定
    • : "${DATA_DIR:=/var/data}"
  • ファイルの中身を空にする
    • : > error.log
    • : > error.log > access.log
  • ファイルの読み書き権限チェック
    • ( : < dataset.json ) && echo YES
    • ( : >> result.json ) && echo YES
  • trapで何もしないコマンド指定
    • trap : INT
  • 変数の存在チェック
    • : "$DEPLOY_ENV" "$HOST"
  • if文で何もしない分岐
    • if some-command; then :; else echo "command failed"; fi

よくある質問(FAQ)

  • なぜnullコマンドが必要?
    • パラメータ展開だけだと、展開結果がコマンドとして実行されてしまう
    • 例:${HELLO:=123}zsh: command not found: 123
    • : ${HELLO:=123} なら副作用(変数設定)だけが残る
  • VAR=${VAR:-default-value}との違いは?
    • : "${DATA_DIR:=/var/data}"なら変数名の記述が一度だけで済み、 タイポ防止
  • 可読性が落ちるのでは?
    • nullコマンドは「コマンドが必須だが何もしない」場面で使うもの
    • if文のelse節やtrapなど、 「何もしない」ことを明示したい時に有用

現場でのコロン活用例

  • Gitのエディタ指定 で何も編集しない場合に利用
    • git -c sequence.editor=: rebase --interactive
  • コマンドが必須な場面や、自動化したいときに活躍

まとめ:コロン(:)の省力&省略マジック

  • nullコマンドパラメータ展開 を組み合わせることで、シェルスクリプトの記述が 短く・安全・明快
  • 「何もしない」ことを明示的に記述 できる点が最大の魅力
  • 省略や自動化を重視するシェルスクリプト書きには 必須テクニック

コロン(:) はシンプルながら、知れば知るほど奥が深い。 スクリプトの効率化・安全化のために、ぜひ積極的に活用してみてください。

Hackerたちの意見

これらのほとんどはあまり好きじゃないけど、いくつかは役に立ちそうだね。: "${1:?missing argument, aborting!}" これは使わないかな。スクリプトの残りの部分で$1に名前を付けたいから、代入すると思う。でも、必要な環境変数が欠けてるときに明確なエラーを出すのにはいい方法かも。他の多くのもの(ファイルを切り詰めるとか)は、専用のコマンドで書いた方が分かりやすいと思うけど、シェルの外の依存関係を避けるために極端なことをするなら役に立つかもね。

よう、作者だよ。君の言う通りだし、100%同意するよ。最初の例を更新して、適切な環境変数を使った自動診断のスニペットを追加したよ。フィードバックありがとう、めっちゃ感謝してる!

同意する。作者も言ってるけど、> なぜnullコマンドを使うのか、VAR=${VAR:-default-value}ができるのに?って指摘してるし、タイプミスが一つ減るけど、名前が同じであることが前提だよね。例えば、TARGETFILE="${1:?need input file}"やOPTIONALVAL="${2:-defaultvalue}"が好きだな。

:?みたいな「ショートカット」が、無関係な二つのこと(変数の条件チェックとその値の展開)を結びつけるのが本当にイライラする。どちらか一方だけを表現するのが、両方を表現するよりも難しくなって、こういう使い方をするときに変なことになるんだよね。

コロンコマンドの個人的なお気に入りの使い方は、数年前に書いたこれだよ: https://johannes.truschnigg.info/writing/2021-12_colodebug/

それは面白いね。今日は「:」の使い方をたくさん学んだよ。でも、唯一知ってたのは… if some-command; then : # command required else echo "command failed" fi これを使ってたけど、if ! some-command; then echo "command failed" fiを知ってからはそうじゃなくなった。これはPOSIX標準に載ってるから、bash特有のものじゃないよ: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V... > パイプラインが「!」の予約語で始まらない場合、終了ステータスはパイプライン内の最後のコマンドの終了ステータスになる。そうでない場合、終了ステータスは最後のコマンドの終了ステータスの論理NOTになる。

https://github.com/anordal/shellharden/blob/master/how_to_do...

Gitでインタラクティブリベースを自動スクワッシュと組み合わせてtodoリストを編集せずにやりたいとき、コロンをEDITORとして使ってるよ。そのためのエイリアス[1]を作って、クイックインタラクティブリベースって呼んでる: riq = -c sequence.editor=: rebase --interactive [1]: https://github.com/fphilipe/dotfiles/blob/94f2ff70bade070694...

うわ、いいね — 絶対自分でも使うわ(もしくはそのバリエーション)!

いいドットファイルだね。

完全に読みやすいif文を、99.9%の人が調べなきゃいけないようなものに変える理由は何?簡潔さが必ずしも良いわけじゃないよ。これを一行にすることもできるし: [ -z "$1" ] && { echo "missing argument, aborting." 1>&2; exit 1 }

exit 1の後と}の前にセミコロンを忘れてると思うよ。}はコマンドの最初で開く{を閉じるだけだから(POSIXのルール;今はbashがコマンド引数の時にそれを認識するかどうかは覚えてないけど)。

Hacker Newsで議論の続きを見る