イベント案内ツールを正しく動かす

LinuxBeginner
オンラインで実践に進む

はじめに

OPEN CIRCLE は地域のアートイベントの午後を準備しています。歓迎ツールキットは Chloé Martín、林雨、佐藤葵、João Silva を含む全プログラムを表示します。正常なサンプルは動きますが、新しいエクスポートは動きません。

元ファイルを保ち、別の配布物を修復します。基本的な端末操作ができれば十分です。権限、スクリプトの先頭行、文字形式の違いを学びます。リーダーは用意済みで、Python や汎用変換器は書きません。

ブラウザーの Terminal を使います。全翻訳でサンプルデータと端末出力は元の言語のままです。

元ファイルを変えずに起動スクリプトを修復する

このステップでは、正常なツールキットとエクスポートを比較し、直接実行できる配布用の起動スクリプトを作ります。Terminal を使用します。

最初に実際の表示を読む

cd は作業ディレクトリを変更します。./ はそのディレクトリを基準にファイルを実行する指定です。スラッシュがあると、シェルはコマンド名を検索せず指定パスを使います。まず付属の正常なサンプルを実行します。

cd /home/labex/project/event
./sample/start.sh
OPEN CIRCLE | Afternoon

14:00 — Welcome / Chloé Martín
14:30 — 纸艺工坊 / 林雨
15:15 — 音の庭 / 佐藤葵
16:00 — Café & questions / João Silva

空の区切り行も含め、すべての行を読みます。これは画像や成功ラベルではなく、付属リーダーが実際にデコードした文字です。cat は文字を表示します。変換方法を選ぶ前にエクスポートの記録を読みます。

cat source/export-receipt.txt

記録には start.sh が CRLF 改行の UTF-8、programme.txt が BOM 付き UTF-16-LE とあります。他のファイルはすでに LF 改行の UTF-8 です。拡張子だけではエンコーディングを判断できません。

権限とインタープリターの入口を分ける

ls -l は権限を表示し、x は実行権限を示します。スクリプトの先頭行である shebang は #! で始まり、インタープリターを指定します。直接実行には有効な入口と実行権限の両方が必要です。エクスポートしたものを試します。ここでは意図的に失敗を確認します。

ls -l source/start.sh
./source/start.sh

permission denied が想定されます。文字を変更しても権限は付与されません。一方 bash file は Bash にファイルを読ませるため、直接実行と shebang を経由しません。このスクリプトにはコマンドの後にコメントがあり、末尾の CR はコメント内に入ります。試してみます。

bash source/start.sh

Cannot read programme.txt と UTF-8 のデコードエラーが想定されます。リーダーには到達しましたが、データを解読できない別の問題です。明示的な Bash 呼び出しは調査の証拠になりますが、直接実行の成功を証明しません。

cp -a はファイルのモードを保ってディレクトリ内容をコピーします。/. は隠しファイルを含む内容を示します。source/ と sample/ を変えずに配布用コピーを作ります。mkdir -p はディレクトリと不足する親を作成し、既存の場合も成功します。chmod u+x は所有者(u)に実行権限を追加し、他の権限は変えません。

mkdir -p delivery
cp -a source/. delivery/
chmod u+x delivery/start.sh
./delivery/start.sh

直接実行はまだ失敗し、例えば bad interpreter: /bin/bash^M: no such file or directory と表示されます。シェルによっては cannot execute: required file not found です。スクリプトは存在しており、原因はインタープリターのパス末尾の CR バイトです。chmod を繰り返しても解決しません。

バイトを観察し、スクリプトの改行だけ直す

LF は 0a、CRLF は 0d 0a です。file はバイトの特徴から形式を説明します。od -An -tx1 -N16 はアドレスを省略して先頭16バイトを16進表示します。記録とバイトを組み合わせて判断してください。file は万能な判別器ではありません。

file source/start.sh source/programme.txt
od -An -tx1 -N16 source/start.sh

shebang は 0d 0a で終わっています。改行と文字エンコーディングは別の属性です。スクリプトはすでに UTF-8 です。Linux アプリケーションは CRLF テキストを読めますが、ここでの問題は直接実行するスクリプトのインタープリターパスです。

sed 's/\r$//' は行末の CR だけを削除します。単一引用符は式をそのまま保ち、$ は行末を表します。> は標準出力を別のファイルに書き、再試行時に置き換えます。入力先と同じファイルへ出力してはいけません。sed が読む前にシェルが空にします。&& は直前が成功した場合だけ次を実行します。続く mv で完成した一時ファイルを改名します。

sed 's/\r$//' source/start.sh > delivery/start.tmp && mv delivery/start.tmp delivery/start.sh
chmod u+x delivery/start.sh
od -An -tx1 -N16 delivery/start.sh
./delivery/start.sh

shebang は 0a で終わるようになりました。最後のコマンドは明示的 Bash と同じ Cannot read programme.txt に到達します。データの境界まで進んだだけで、全体の完了ではありません。間違えたら source/start.sh から変換し直し、実行権限を戻します。元ファイルは編集しません。

プログラムを変換し、独立した配布物を使う

このステップでは宣言済みの UTF-16 ソースをデコードし、すべての文字を保持して別のディレクトリから実行します。Terminal の /home/labex/project/event で続けます。

ソースのエンコーディング証拠を使う

文字エンコーディングは文字をバイトに対応させます。UTF-8 と UTF-16 は同じ名前を異なるバイトで表現します。UTF-16 先頭の BOM はバイト順を示し、ff fe はリトルエンディアン、fe ff はビッグエンディアンです。どちらも UTF-16 です。ここで BOM は有用な証拠であり、常に有害な接頭辞ではありません。

od -An -tx1 -N16 source/programme.txt

先頭の ff fe は記録の UTF-16-LE と一致します。リーダーの公開仕様は BOM なし UTF-8 です。テキストの CRLF は受け入れますが、この UTF-16 のバイトを UTF-8 としてはデコードできません。CR の削除や拡張子変更では解決しません。

iconv -f UTF-16 -t UTF-8 は BOM 付き UTF-16 をデコードし、UTF-8 にエンコードします。-f はソース、-t は出力形式です。UTF-16 は BOM からバイト順を選びます。一時ファイルへ保存し、成功時だけ正式ファイルにします。

iconv -f UTF-16 -t UTF-8 source/programme.txt > delivery/programme.tmp && mv delivery/programme.tmp delivery/programme.txt
file delivery/programme.txt
od -An -tx1 -N16 delivery/programme.txt
cat delivery/programme.txt

先頭はタイトルの UTF-8 バイトとなり、ff fe、fe ff、UTF-8 BOM の ef bb bf ではなくなります。サンプルと全員の名前を比較します。非 ASCII 文字を削除すれば、デコードできてもイベントの内容を失います。

iconv がエラーを出すと、出力は途中までの可能性があります。&& により不完全なファイルへの置換を防ぎます。宣言されたソース形式を確認し、未変更のソースから再実行してください。-c や //IGNORE で文字を黙って捨ててはいけません。本課題は正常で形式が明示されたデータを扱い、破損したエクスポートの推測や修復は扱いません。

すでに正常なファイルを保つ

about.sh と door-sign.txt は正常で、変換不要です。cmp はバイトを比較し、同じなら何も表示せず成功します。次の2つの比較は無出力になるはずです。

cmp source/about.sh delivery/about.sh
cmp source/door-sign.txt delivery/door-sign.txt
./delivery/about.sh
cat delivery/door-sign.txt

コミュニティアートの説明と Bienvenue · 欢迎 · ようこそ が表示されます。変換は証拠と入力仕様に応じて行い、全ファイルに必要な処理ではありません。

配布して実際に実行する

起動スクリプトは自身の位置から reader.py を探し、リーダーも同様に programme.txt を探します。無関係なディレクトリへ移動し、絶対パスで起動します。使える配布物は作者の現在地や明示的 bash による回避に依存してはいけません。

cd /tmp
/home/labex/project/event/delivery/start.sh

先ほどの午後の全4項目が、元の順序と空の区切り行を保って表示されます。実際の配布ファイルを使いました。Chloé Martín、林雨、佐藤葵、João Silva を確認してください。終了状態ゼロだけでは文字の保存を証明できません。

プロジェクトに戻ります。

cd /home/labex/project/event

再試行では source/ から対象ファイルを再生成します。変換済み UTF-8 を iconv -f UTF-16 に渡すと、ソース形式の誤指定になります。正常なファイルを保ち、変更後は直接起動し直してください。他のアプリが別の形式や BOM を受け入れる場合もあります。ここでの条件はこのツールキットの公開仕様です。

まとめ

直接実行の権限、shebang の改行、データのエンコーディングを区別しました。全員の名前、順序、正常ファイルを保って UTF-8 プログラムを配布し実行しました。独立した夜のチャレンジでは別のソース証拠に同じ方法を使います。