Linux ターミナルで実行するコマンドはすべて、すべてのシステムで同じように動作しますよね。間違っている。 Linux コマンドは多くの場合移植性が高いですが、例外も存在します。
個々のコマンドは、GNU の find や BSD の同等のものなど、異なるバージョンを持つことができます。プログラムは、Solaris、IBM AIX、macOS などの Unix のバージョン間や、Alpine Linux の BusyBox などのディストリビューション間でも異なる場合があります。
ステータス
プラットフォームの不一致が多い低レベルのツール
stat ユーティリティは、低レベルの ls に少し似た、ファイルに関する情報を表示します。
ただし、デフォルトの使用法であっても、システムによって大きく異なる結果が生じる可能性があります。
しかし、これはほんの始まりにすぎません。 GNU stat の -f、-c、および -t オプションはすべて、BSD バリアントではサポートされていないか、動作が大きく異なります。たとえば、GNU バージョンのブロック サイズを表示するには、次のコマンドを実行できます。
stat -c %s filename
ただし、BSD stat では、別のオプションと別のフォーマット文字列を使用する必要があります。
stat -f %b filename
すべての GNU ツールに見られる重要な違いもあります。それは、ユビキタスな –help や –version を含む長いオプションのサポートです。これらのオプションは、マニュアル ページにアクセスせずにコマンドについて学ぶために不可欠ですが、BSD の同等のものにはこれらのオプションが欠けていることがよくあります。
探す
このツールはすでに複雑ですが、GNU バージョンにはいくつかの便利な機能があります
この人気のあるプログラムのバージョンは大きく異なり、用語についてさえ合意できません。 BSD の find では「プライマリ」について説明していますが、GNU バージョンでは代わりに「テスト」と「アクション」について言及しています。
膨大な数のオプションがあるため、find のバージョンが異なればサポートされる動作も異なるのは当然のことです。重要な例は、GNU の -printf オプションです。これを使用すると、find の出力を調整できます。
find . -printf "%f\n"
BSD バージョンは -printf オプションをまったくサポートしていないため、その出力を stat にパイプして、その違いも考慮することをお勧めします。
ただし、一部の非互換性はそれほど重要ではありません。たとえば、GNU バージョンの find は BSD の -d オプションをサポートしており、これにより find は深さ優先のトラバーサルを実行します。ただし、その際に丁寧な警告メッセージが出力されます。
GNU バージョンの find では、パス引数を省略することもできます。その場合、デフォルトで現在のディレクトリが使用されます。この動作は POSIX 標準では定義されていません (BSD find は使用法を出力し、エラーを返します) が、確かに便利です。
-
オペレーティング·システム
-
Ubuntu Linux 22.04 LTS
-
CPU
-
第13世代インテル Core i7-1360P
-
GPU
-
インテル Iris Xe グラフィックス
-
ラム
-
16GB DDR5
-
ストレージ
-
512GB SSD
-
重さ
-
2.71ポンド
Dell XPS 13 Plus with Linux は、強力なハードウェアと優れた画面を軽量で見栄えの良いシャーシに組み合わせ、素晴らしい Linux ラップトップを作成します。
トップ
これはまったく別のツールのように感じます
もちろん、システム上で実行されているプロセスのリストは、環境によって大きく異なるはずです。しかし、トップがレポートするデータとそれを表示する形式も根本的に異なる可能性があります。
まず、画面上部の BSD の概要情報はより詳細であり、ネットワークやディスクの統計情報などの追加の詳細が含まれています。
GNU バージョンにはメモリの割合が含まれていますが、BSD では絶対値が表示されます。デフォルトの列、特に順序には他にも多くの違いがあります。
top は対話型セッションでのみ使用するため、スクリプト内で使用する可能性のある他のコマンドほど違いは重要ではありません。
セド
BSD はいくつかの厄介な構文を強制します
ストリーム エディター sed は、正規表現を使用して入力を変換できる柔軟なツールです。最も便利な機能の 1 つは、ファイルをその場で編集できる -i オプションです。
sed -i 's/foo/bar/g' filename
しかし、BSD システムでは、sed は同じコマンドに対して非常にわかりにくいエラー メッセージを表示します。
これは、BSD の -i オプションの扱いが微妙に異なり、バックアップ ファイルを保存するための拡張子を宣言する引数が必要であるためです。
sed -i .bak 's/foo/bar/g' filename
空の拡張機能を使用してこの動作を完全にバイパスすることもできますが、元のエラーを回避するには、常に BSD sed に引数を指定する必要があります。
sed -i '' 's/foo/bar/g' filename
grep
以前よりは良くなりましたが、BSD ユーザーはまだ見逃しています
grep は幅広い用途に使用できるため、Linux ツールキットには必須です。ただし、これは歴史的に、基盤となる正規表現エンジンの違いに起因する移植性の問題の原因となってきました。 GNU システムではデフォルトは BRE (基本) ですが、macOS では以前は厳密な POSIX 構文が好まれていました。
ありがたいことに、現在ではこれらの違いはそれほど顕著ではなくなり、macOS の最新バージョンでは、grep はそれ自体を「BSD grep、GNU 互換」として宣伝しています。
ただし、Perl 互換正規表現 (PCRE) のサポートという大きな相違点が 1 つ残っています。 -P オプションを使用すると、GNU grep では、Perl の正規表現パーサーによって導入されたより柔軟な構文を使用できるようになります。
grep -P '\d+' numbers.txt
拡張文字クラス、非貪欲一致、および名前付きサブパターンにより、PCRE は大きな利点を提供しますが、それらに依存することには注意し、それらを使用できるかどうかを確認してください。
CP
最も基本的なコマンドでも信頼性が低い場合があります
cp のような単純なコマンドには一貫性があることが期待されるかもしれません。残念ながら、それは間違いです。 Ubuntu、Red Hat、または Debian では、コピー先よりも新しい場合にのみ -u オプションを使用してソース ファイルをコピーできます。
cp -u ./original ./target
残念ながら、この便利なオプションは、macOS にバンドルされているバージョンを含む他のバージョンにはありません。
GNU バージョンの cp は、複数のファイルを 1 つのディレクトリにコピーする代替方法もサポートしています。すべてのバージョンでサポートされる標準的なアプローチは、すべてのファイルにパラメータとして名前を付け、最後のパラメータにディレクトリを指定することです。
cp file1.c file2.c file3.c src
ただし、順序を入れ替える -t オプションをサポートしているのは GNU バージョンのみです。
cp -t src file1.c file2.c file3.c
後者の形式は、入力するときに便利ですが、パイプラインで cp を使用する場合に最大限に活用できます。
find . -name '*.c' | xargs cp -t src
互換性が重要な場合は、コアの POSIX 動作に固執してください
どちらの共通ツール セットも他より優れているというわけではありませんが、BSD と GNU には大きな違いがあります。一般に、BSD ツールは POSIX 標準に近づく傾向がありますが、長いオプションや明確なヘルプなどの GNU 拡張機能には通常価値があります。
どちらを使用する場合でも、特に新しい環境に慣れる場合には、違いを理解し、違いを見つける方法を学びましょう。