コマンドラインで改行を出力する方法:echoとprintfの正しい使い方
意外に思われるかもしれませんが、コンピュータに人間が読める形式の出力をさせるのは、決して簡単なことではありません。標準ストリーム、特に標準出力(stdout)の導入により、プログラム同士がプレーンテキストのストリームでやり取りできるようになりました。しかし、そのstdoutを人間にとって読みやすい形に整えて表示するのは、また別の話です。ビデオディスプレイにおけるASCII文字の活用から、echoやprintfといった現代のシェルコマンドに至るまで、コンピューティングの歴史を通じてこの問題の解決が試みられてきました。
こうした進歩の道のりは決して平坦なものではありませんでした。ターミナルへ出力を表示する作業には、プログラマーが注意すべき数々の癖があり、エスケープシーケンスを展開して改行を表示するという一見単純なタスクも、実はそう簡単ではありません。プレースホルダー\nの展開方法は複数存在し、それぞれに独自の歴史と課題を抱えています。
echoを使う方法
Multics時代から登場し、現代のUnix系システムで広く普及しているechoは、ターミナルに「Hello world!」と表示させるためのおなじみのツールです。ところが残念ながら、OSによって実装が異なるため、扱いには注意が必要です。一部のシステムではエスケープシーケンスが自動的に展開されますが、他のシステムでは-eオプションを指定しなければなりません。
echo "the study of European nerves is \neurology"
# the study of European nerves is \neurology
echo -e "the study of European nerves is \neurology"
# the study of European nerves is
# eurologyこのような実装の不一致があるため、echoは移植性に欠けるコマンドと見なされています。さらに、ユーザー入力と組み合わせて使う場合、コマンド置換を悪用したシェルインジェクション攻撃によって、比較的容易に不正操作されるリスクもあります。
現代のシステムでは、依然としてechoを使用している多くの既存プログラムとの互換性を保つために残されているだけです。POSIX仕様では、新しく書くプログラムにはprintfの使用が推奨されています。
printfを使う方法
4th Edition Unix以来、移植性のあるprintfコマンドは、事実上「より優れた新しいecho」としての地位を確立しています。フォーマット指定子を使うことで、入力を人間が読みやすい形に整形できます。バックスラッシュのエスケープシーケンスを解釈するには%bを使用します。文字列\nにより、出力は確実に改行で終わります。
printf "%b\n" "Many females in Oble are \noblewomen"
# Many females in Oble are
# oblewomenprintfにはechoをはるかに凌ぐ強力な機能を持たせる追加オプションが多数ありますが、このユーティリティも万能ではありません。フォーマット文字列攻撃に対して脆弱になる可能性があるため、プログラマーはユーザー入力を慎重に取り扱うことが重要です。
変数に改行を格納する
コンパイラ間の移植性を向上させることを目的として、1983年にANSI C規格が策定されました。$'...'によるANSI-Cクォートを使用すると、エスケープシーケンスが規格に従って出力時に置き換えられます。
これにより、改行を含む文字列を変数に格納し、それを改行として解釈した状態で表示することが可能になります。具体的には、変数を設定した後、$を使ってprintfで呼び出します。
puns=$'\number\nnarrow\nnether\nice'
printf "%b\n" "These words started with n but don't make $puns"
# These words started with n but don't make
# umber
# arrow
# ether
# ice展開された変数はシングルクォートで囲まれており、その内容がそのままprintfに渡されます。ここでも、入力を適切に処理することが重要です。
おまけ:シェルパラメータ展開
Bashと波括弧に関する記事で、シェルパラメータ展開の魔法について紹介しました。${parameter@operator}という展開構文を使えば、エスケープシーケンスを解釈することもできます。printfの%s指定子で文字列として出力し、E演算子を組み合わせると、変数内のエスケープシーケンスが適切に展開されます。
printf "%s\n" ${puns@E}
# umber
# arrow
# ether
# ice人間の言葉で語り続ける挑戦
文字列補間は今なお、プログラマーにとって厄介な問題であり続けています。言語やシェルの間で特定のプレースホルダーの意味を統一することに加えて、正しいエスケープシーケンスを適切に使いこなすには、細部への鋭い注意力が求められます。
不適切な文字列補間は、奇妙な見た目の出力を生むだけでなく、インジェクション攻撃などのセキュリティ脆弱性を招く原因にもなります。次世代のターミナルで絵文字を使った会話が当たり前になる日が来るまでの間、人間向けの出力を表示する際には、十分に注意を払うことが賢明でしょう。
-
コマンドラインでUbuntuを更新する方法 – aptコマンドの基本を徹底解説
Linuxのコマンドライン操作に慣れた上級者にとって、システムをコマンドラインから更新するスキルは必須です。常に最新の状態を保つことで、システムの安全性とセキュリティが確保され、最新機能もすぐに利用できるようになります。この記事では、Ubuntuデスクトップやサーバーをターミナル、またはSSH接続経由でアップデートする方法をわかりやすく解説します。 なぜコマンドラインで更新すべきなのか GUIツールではなく、あえてコマンドラインを使ってUbuntuを更新する理由は何でしょうか? 最大のメリットは、「ソフトウェアの更新」などのGUIツールよりも処理が速く、更新の進行状況をリアルタイムで確認でき
-
コマンドラインからUbuntuをアップグレードする方法|do-release-upgrade徹底解説
Ubuntuの「アップデートマネージャー」を使えば、新しいメジャーリリースへのアップグレードは比較的簡単に行えます。GUIのウィザードが手順を順番に案内してくれるため、初心者でも迷わず操作できるでしょう。 しかし、GUIユーティリティを使えない場面もあります。たとえばサーバー環境ではグラフィカルインターフェースにアクセスできないため、コマンドラインでアップグレード作業を行うしかありません。 とはいえ、これだけがコマンドラインを使う理由ではありません。CLIでは処理の進行状況がより詳細に表示されるのが特徴です。多くのコマンドラインツールは実行中に大量のテキストを出力するため、アップグレードの詳細