時にはコンピュータ(プログラミング)に関する話題を書こうと思います.最近ハマった事例について,後に続くみなさんのためにも記しておきます.

シェルスクリプトで文字を表示する時,よく用いられるのが echo コマンドです.この echo コマンド,処理系によって挙動が異なっており,エスケープシーケンスを解釈する/しない,させる/させないでだいぶ混乱します (私は混乱しました) .まず, echo コマンドは,シェルビルトインコマンド (sh, bash, zsh などに組み込まれている内部コマンド) と,外部コマンド (/bin/echo) の2種類があります.内部コマンドか外部コマンドか,また,処理系が Linux, BSD系 (macOS), AIX の3つの場合で,echo コマンドの実行結果に違いが出てくるそうです.

自分の手元で実験可能な範囲で試してみたところ,下の表のようになりました.

処理系コマンド実装先オプション対応エスケープシーケンスを解釈するかecho -e “ABC\nDEF”の実行結果
Ubuntu の sh内部コマンド -n に対応解釈する-e ABC
DEF
Ubuntu の bash内部コマンド -e, -n に対応-eオプション指定時に解釈ABC
DEF
Ubuntu外部コマンド-e, -n に対応 -eオプション指定時に解釈 ABC
DEF
BSD の sh (ksh)内部コマンド-e, -n に対応解釈するABC
DEF
BSD の bash内部コマンド-e, -n に対応 -eオプション指定時に解釈 ABC
DEF
BSD外部コマンド-n に対応解釈しない -e “ABC\nDEF”

ちと困りました.私はシェルスクリプトを作成する際,自分の持っている環境すべて (ローカルマシン,レンタルサーバ,AWS) で動かせるようにしたいと思って作ります.そのため,もっとも基本的なBourne Shell (/bin/sh) で動くように作るのですが,出力に差ができてしまっています.

解決するアプローチは2つあります.ひとつはデファクトスタンダードとして,大部分のUNIX処理系にインストールされていると期待できる bash でシェルスクリプトを実行することです.ただ,OpenBSDではデフォルトでは bash が入っていません.もうひとつのアプローチは,「echo オプション 効かない」などで検索してみると出てきますが,echo の代わりに printf を用いるものです.

printf "ABC\nDEF\n"

printf コマンドは,C言語の printf 関数と同じ要領で引数を指定できます.echo コマンドと異なり,出力の最後は改行されませんので,改行したい場合には改行のエスケープシーケンスを入れておきます.

コメントを残す

メールアドレスが公開されることはありません。