こんにちは、教育系エンジニアのひらまつ(@hiramatsuu)です。
書籍「ゼロからわかる Linuxコマンド200本ノック(技術評論社)」の著者。Udemy受講者8万人。
プログラミング教育をメインに活動するエンジニアとして、動画教材の作成・技術書の執筆・学習アプリの開発などを行なっています(詳しくはこちら)。
昨今では、猫も杓子もChatGPTというような雰囲気です。なので私も、ChatGPTでものづくりをしてみました。
私は教育をメインに活動しているエンジニアですから、ChatGPTでプログラミング教材を作成してみよう!ということで、ChatGPTを使ってLinuxコマンド100本ノックを作成してみました。
本記事では、作成したLinuxコマンド100本ノックを公開するだけでなく、ChatGPTをどのように活用したかをシェアできればと思います。Linuxコマンドについて学習したい方はもちろんですが、ChatGPTをまだ使ったことがない!という方が、使用を開始するきっかけになればと思います。
100本ノック作成の背景
そもそもなぜ、ChatGPTでLinuxコマンド100本ノックを作成しようかと思ったかというと、拙著「ゼロからわかる Linuxコマンド200本ノック―基礎知識と頻出コマンドを無理なく記憶に焼きつけよう!」を執筆したことが理由の一つです。
本書は、Udemyでベストセラーになった私の講座「もう絶対に忘れない Linux コマンド【Linux 100本ノック+名前の由来+丁寧な解説で、長期記憶に焼き付けろ!】」を元にして執筆した書籍です。もとの講座の良さはそのままに、さらにわかりやすく、身につけやすいように再構成しています。
本書の特徴としては、主に以下の3つかなと思います。
- コマンドやオプションの「由来」をできる限り解説
- 「暗記がいらなくなるレベル」の理解を目指した、とことん丁寧な解説
- 「200問」の演習問題で記憶にこびりつく
👇本書についてより詳しくはこちら
書籍紹介ページを見る
本書の200本ノックはすべて、私が自分で考えて作ったものです。1冊の内容を200問ぴったりの演習問題にするのは、大変な苦労を強いられました。本書執筆の苦労について詳しくは、こちらの記事を参照していただきたいのですが、何が言いたいかと言うと、もっと楽にn本ノックを作ることは出来ないのか?と、本書執筆の苦労を経て思ったわけです。
100本ノックや200本ノックのような「n本ノック」という学習方法は、きわめて効果的な学習方法です。なので、ChatGPTを使って、n本ノックをもっと楽に作成できるようになれば、ソフトウェア開発のあらゆるテーマをより効率的に学べるようになるはずです。
※n本ノックがなぜ効果的なのかは、拙著の「はじめに」に詳しく書いたので、ぜひ購入して読んでみてください。Amazonの商品ページから、Kindleのプレビューでも読むことができます。
そこで、試してみようと思ったのが、ChatGPTを使ったアプローチです。具体的には、以下のような手順で進めていきました。
作成手順
※前提として、私はChatGPTの素人なので、以下の手順には「もっといい方法あるだろ!」というツッコミがあることが予想されます。あらかじめご了承ください。
生成AIをうまく活用する最大のポイントは、高速にフィードバックループを回すことでしょう。AIのアウトプットが自分のイメージと違ったら、期待通りになるように、与える文を微調整し、再度生成させ、またアウトプットを元に与える文を微調整して、、、という流れで、少しずつ自分の期待通りのアウトプットに近づけていきます。
フィードバックループを高速に回す必要があるので、与える文の改善は、回数制限のないGPT-3.5の方で行い、最終的なアウトプットは、回数制限がある(本記事執筆時点)が精度の高い、GPT-4に出力させました。
結果としては、以下のような文を与えることで、期待通りのアウトプットを得ることができました。
Linuxコマンドの演習問題を10問作成してください。ただし以下の条件すべてを満たすものとします。
・すべての問題の解答は、Bashに入力して実際に動作する
・すべての解答は具体的な1行のコマンドラインになるものとする
・問題文には具体的なファイル名やディレクトリ名を含める
・問題文には具体的なコマンドの名前は含めない
・1~10の10段階の難易度(数字が大きいほど難しい)があるとして、難易度1~3の問題だけを作成する
・出題の範囲は、実務で誰もが使う最頻出のコマンドだけ
・問題文だけを作成する
・出力のフォーマットは「問題番号:問題文」
100問を一度に出力することは、以下のようなことを言われてしまい、叶いませんでした。
また、出力の文字数には制限があるので、問題文は10問ずつ出力されるようにし、10問出力されるごとに以下のように、次の10問を出力するように「問題○〜○を出力」と入力しました。
そして、拙著くらいの難易度の問題になるように、「1~10の10段階の難易度(数字が大きいほど難しい)があるとして、難易度1~3の問題だけを作成する」というように難易度を指定しました。ちなみに、難易度10の問題を作るように指示すると、以下の画像のように言われました。
難易度MAXの問題の出題は倫理上できない、とのことで、ChatGPTが一風変わった倫理観を持っていることが、うかがい知れます。代わりに難易度9の問題を出力してくれましたが、見てみていかがでしょうか。たしかに、以下に掲載している難易度1~3のものよりは難しくなっています。
また「出題の範囲は、実務で誰もが使う最頻出のコマンドだけ」という条件を付与することで、拙著で扱っているコマンドと近いものだけが出題されるように試みました。
実際に上記の文を、GPT−4に与えて作成させた問題が、以下の100問です。
Linuxコマンド100本ノック
ChatGPTの実力がわかりやすいように、問題文には手を加えず、出力されたままのものを掲載しています。拙著では扱っていない機能もいくつかありますが、こちらの記事で紹介したLinux学習のロードマップと合わせて利用すると、よろしいのではないでしょうか。
👇以下問題です。
問題1~10
問題1:現在のディレクトリに存在するファイルとディレクトリを一覧表示してください。
問題2:ファイル「apple.txt」の内容を表示してください。
問題3:ファイル「banana.txt」をディレクトリ「fruits」に移動させてください。
問題4:ディレクトリ「vegetables」を作成してください。
問題5:ファイル「orange.txt」を「grape.txt」という名前に変更してください。
問題6:ファイル「watermelon.txt」と「pineapple.txt」を一度に表示してください。
問題7:ディレクトリ「fruits」内にあるファイルの数を表示してください。
問題8:ファイル「kiwi.txt」の中に「vitamin」が含まれている行だけを表示してください。
問題9:ディレクトリ「fruits」内のファイルをアルファベット順で一覧表示してください。
問題10:現在のディレクトリの使用容量を表示してください。
問題11~20
問題11:ファイル「strawberry.txt」をコピーして、「blueberry.txt」という名前で現在のディレクトリに保存してください。
問題12:現在のディレクトリにある「.txt」ファイルだけを一覧表示してください。
問題13:ファイル「apple.txt」と「banana.txt」の差分を表示してください。
問題14:ディレクトリ「fruits」と「vegetables」の内容を一度に一覧表示してください。
問題15:ファイル「mango.txt」の先頭から5行だけ表示してください。
問題16:ファイル「coconut.txt」の末尾から10行だけ表示してください。
問題17:ファイル「avocado.txt」を圧縮し、「avocado.tar.gz」という名前で保存してください。
問題18:圧縮ファイル「nuts.tar.gz」を解凍して、ディレクトリ「nuts」に保存してください。
問題19:ファイル「grape.txt」の中で、「sugar」という単語が含まれる回数を表示してください。
問題20:現在のディレクトリにあるファイルとディレクトリを隠しファイルを含めて一覧表示してください。
問題21~30
問題21:ディレクトリ「fruits」内のすべての「.txt」ファイルをディレクトリ「text_files」に移動させてください。
問題22:現在のディレクトリから一つ上のディレクトリに移動してください。
問題23:ファイル「carrot.txt」の所有者をユーザー「peter」に変更してください。
問題24:ファイル「onion.txt」のアクセス権を読み取り専用に変更してください。
問題25:ファイル「lettuce.txt」のサイズをバイト単位で表示してください。
問題26:現在のディレクトリにあるすべてのファイルとディレクトリのサイズを人間が読みやすい形式で一覧表示してください。
問題27:ファイル「plum.txt」の内容を、ファイル「apricot.txt」の末尾に追加してください。
問題28:ディレクトリ「berries」を削除してください。ただし、ディレクトリ内にファイルが存在する場合も対応できるようにしてください。
問題29:ファイル「peach.txt」の中で、文字列「sweet」を「delicious」に置き換えた結果を表示してください。
問題30:ファイル「grapefruit.txt」の中から、特定のパターン「vitamin」を含む行だけを別のファイル「vitamin_lines.txt」に保存してください。
問題31~40
問題31:ディレクトリ「nuts」内にあるすべての「.txt」ファイルを、ディレクトリ「seeds」内の「.log」ファイルに変更して移動させてください。
問題32:現在のディレクトリの絶対パスを表示してください。
問題33:現在のディレクトリ内にある「.log」ファイルを削除してください。
問題34:ファイル「cherry.txt」のアクセス権を、所有者は読み書き、グループは読み取り専用、その他のユーザーはアクセス禁止に設定してください。
問題35:ファイル「radish.txt」の内容を逆順に表示してください。
問題36:現在のディレクトリ内のファイルとディレクトリを、作成日時の新しい順に一覧表示してください。
問題37:ディレクトリ「vegetables」内のすべての「.txt」ファイルを検索し、それらのファイル名を表示してください。
問題38:ファイル「papaya.txt」を空のファイルにしてください。
問題39:現在のディレクトリのツリー構造を表示してください。ただし、隠しファイルやディレクトリも含めて表示してください。
問題40:ファイル「pear.txt」と「melon.txt」を連結し、「fruit_salad.txt」という名前で保存してください。
問題41~50
問題41:ファイル「kiwi.txt」と「fig.txt」を一度にダウンロードして、それぞれ「kiwi_backup.txt」と「fig_backup.txt」という名前で保存してください。
問題42:ファイル「olive.txt」の中で、空白行を除いて行数を表示してください。
問題43:ディレクトリ「fruits」内にあるすべてのファイルを、ディレクトリ「fruits_backup」にコピーしてください。
問題44:ファイル「raspberry.txt」をリモートサーバー「example.com」のホームディレクトリにアップロードしてください。ただし、ユーザー名は「john」、パスワードは「1234」です。
問題45:現在のディレクトリ内にあるすべての「.txt」ファイルを、一つの「all_fruits.txt」というファイルにマージしてください。
問題46:ファイル「cucumber.txt」の中で、「green」を含む行を削除した結果を表示してください。
問題47:ファイル「tomato.txt」を、ファイル「red_tomato.txt」と「green_tomato.txt」に分割してください。ただし、それぞれ100行ごとに分割するものとします。
問題48:ファイル「lettuce.txt」と「cabbage.txt」を一度に圧縮し、「greens.tar.gz」という名前で保存してください。
問題49:現在のディレクトリ内にある「.txt」ファイルのみを選択し、それらをディレクトリ「text_files」に移動させてから、「text_files」ディレクトリを圧縮して「text_files.tar.gz」という名前で保存してください。
問題50:ファイル「lemon.txt」から「orange.txt」までのファイルを一覧表示し、それらの合計サイズを表示してください。
問題51~60
問題51:ディレクトリ「fruits」内にある「apple.txt」ファイルのシンボリックリンクを、現在のディレクトリに「apple_link.txt」という名前で作成してください。
問題52:ファイル「grape.txt」の内容を、端末上に直接表示せずに、ページ送りで閲覧できるようにしてください。
問題53:ファイル「spinach.txt」の中で、単語「iron」が出現する行番号を表示してください。
問題54:ファイル「potato.txt」の中で、最も長い行を表示してください。
問題55:ディレクトリ「seeds」内にあるファイルのうち、「sunflower」を含むものだけを一覧表示してください。
問題56:ファイル「broccoli.txt」の中で、各単語が何回出現するかカウントし、出現回数の多い順に表示してください。
問題57:現在のディレクトリにあるすべてのファイルとディレクトリを、名前の長さ順に一覧表示してください。
問題58:ファイル「zucchini.txt」の内容を、行番号を付けて表示してください。
問題59:現在のディレクトリにある「.txt」ファイルを、最終更新日時の古い順に一覧表示してください。
問題60:ファイル「avocado.txt」の中で、「fat」を含む行だけを表示し、それらの行番号も同時に表示してください。
問題61~70
問題61:ディレクトリ「nuts」内にあるすべてのファイルを、現在のディレクトリにコピーし、それぞれのファイル名の末尾に「_backup」を追加してください。
問題62:ファイル「pepper.txt」の中で、英数字以外の文字をすべて削除した結果を表示してください。
問題63:現在のディレクトリにあるすべての「.txt」ファイルを、ディレクトリ「docs」に移動させてください。ただし、「docs」ディレクトリが存在しない場合は、作成してから移動させてください。
問題64:ファイル「walnut.txt」の内容を、大文字を小文字に、小文字を大文字に変換して表示してください。
問題65:ファイル「rice.txt」の中で、「carbohydrate」という単語が含まれる行を抽出し、それらの行を別のファイル「carbohydrate_lines.txt」に保存してください。
問題66:現在のディレクトリにある「.log」ファイルを一括で削除し、削除したファイルのリストを表示してください。
問題67:ディレクトリ「fruits」内にあるすべてのファイルとディレクトリを、サイズの大きい順に一覧表示してください。
問題68:ファイル「eggplant.txt」の中で、空白行を削除した結果を別のファイル「eggplant_no_empty_lines.txt」に保存してください。
問題69:現在のディレクトリにあるファイルとディレクトリを、作成日時の新しい順に10件だけ表示してください。
問題70:ファイル「mushroom.txt」の中で、各行の先頭にある空白を削除した結果を表示してください。
問題71~80
問題71:ファイル「pineapple.txt」の中で、「juicy」という単語が出現する前のすべての行を表示してください。
問題72:ディレクトリ「vegetables」内にあるファイルのうち、最も古い更新日時を持つファイルを表示してください。
問題73:ファイル「dates.txt」の中で、数字を含む行だけを抽出し、それらの行を別のファイル「numbered_lines.txt」に保存してください。
問題74:現在のディレクトリにあるすべての「.txt」ファイルの中で、「tasty」という単語が含まれるファイルを一覧表示してください。
問題75:ディレクトリ「fruits」内にあるファイルを、現在のディレクトリにコピーしてから、それぞれのファイル名の先頭に「fruit_」を追加してください。
問題76:ファイル「lettuce.txt」の中で、最後の5行を別のファイル「last_five_lines.txt」に保存してください。
問題77:現在のディレクトリにあるすべての「.txt」ファイルの中で、「vitamin」を含むファイルを一覧表示し、それぞれのファイルサイズも表示してください。
問題78:ファイル「potato.txt」の中で、重複する行を削除した結果を別のファイル「unique_potato.txt」に保存してください。
問題79:現在のディレクトリにあるすべてのファイルとディレクトリを、ファイル名のアルファベット順に一覧表示してください。
問題80:ファイル「orange.txt」の中で、各行の最後にある空白を削除した結果を表示してください。
問題81~90
問題81:ファイル「blueberry.txt」の中で、単語「tart」が出現する回数を表示してください。
問題82:ファイル「kiwi.txt」を読み取り専用に設定し、その後、その設定が適用されたことを確認してください。
問題83:ディレクトリ「plants」内にあるすべてのファイルを、現在のディレクトリにコピーしてから、それぞれのファイル名の末尾に「_2023」を追加してください。
問題84:現在のディレクトリ内にある「.csv」ファイルを削除してください。
問題85:ファイル「lime.txt」の中で、各行の文字数を表示してください。
問題86:ディレクトリ「flowers」内のすべてのファイルとディレクトリを、名前のアルファベット逆順に一覧表示してください。
問題87:現在のディレクトリにあるファイルとディレクトリを、所有者名でソートして一覧表示してください。
問題88:ファイル「banana.txt」の中で、行末に「sweet」という単語がある行だけを抽出し、それらの行を別のファイル「sweet_lines.txt」に保存してください。
問題89:ファイル「peach.txt」の中で、「peach」をすべて「apricot」に置換した結果を表示してください。
問題90:現在のディレクトリにあるファイルとディレクトリを、サイズの小さい順に一覧表示してください。ただし、サイズを人間が読みやすい形式で表示するものとします。
問題91~100
問題91:ファイル「strawberry.txt」の中で、文字列「delicious」が出現する前の10行だけを抽出し、それらの行を別のファイル「delicious_context.txt」に保存してください。
問題92:現在のディレクトリ内にあるすべての「.png」ファイルを、ディレクトリ「images」に移動させてください。
問題93:ファイル「apple.txt」の中で、単語「crisp」が出現する後のすべての行を表示してください。
問題94:ディレクトリ「legumes」内にあるファイルのうち、最も新しい更新日時を持つファイルを表示してください。
問題95:現在のディレクトリ内にあるすべての「.txt」ファイルを、最終更新日時の新しい順に一覧表示してください。
問題96:ファイル「grapefruit.txt」の中で、「bitter」という単語が含まれる行を抽出し、それらの行を別のファイル「bitter_lines.txt」に保存してください。
問題97:ディレクトリ「trees」内のすべてのファイルとディレクトリを、作成日時の古い順に一覧表示してください。
問題98:ファイル「pear.txt」の中で、「juicy」をすべて「tasty」に置換した結果を別のファイル「tasty_pear.txt」に保存してください。
問題99:現在のディレクトリにあるファイルとディレクトリを、拡張子でソートして一覧表示してください。
問題100:ファイル「mango.txt」の中で、空白文字(スペース、タブ、改行)をすべて削除した結果を表示してください。
100本ノックの解答について
解答や解説もChatGPTを使用すればOKです。以下の画像のように問題を入力にするだけで、解答を出してくれます。
これだけでは解説が不十分だと思ったら、よりわかりやくなるように、与える文を改善すればOKです。もしChatGPTを使ったことがないという場合は、この機会にぜひ使ってみてください。
考察
ChatGPTが作った100本ノックに対する、いくつかの個人的な感想を挙げておきます。
- 問題は重複していないが、問われていることは重複している。例えば、「コマンド+パス名展開」みたいな問題が多いなど。さまざまな文脈で触れることができるという点では良いが、問題数あたりの学びを最大化する、という目標だと少し期待とずれそう。
- 問題文が解答を1つに定めるのに不十分なこともある。例えば、「問題87:現在のディレクトリにあるファイルとディレクトリを、所有者名でソートして一覧表示してください。」など、ソートが昇順か降順かが明記されていない。とはいえ、想起練習のための演習問題としてはきちんと機能するものばかりだし、人間が最終チェックすればなんの問題もない。
- sedやawkを使う問題など、拙著のレベルより高い問題もちらほらある。テーマをもっと絞って作成してもらった方が、期待通りの問題セットになりそう。本の目次を与えて、章ごとに問題を作成させるなど。
というわけで
いくつか小さな問題点もあるものの、与える文を改善すればより良くできそうですし、現時点でも十分役立つ100本ノックが作成できたのではないでしょうか。私の今後の仕事においても、ChatGPTなどのAIの助けを借りることが、必須になってくると思わされました。
いずれにしても、効率的な学習をするためには、演習問題を解くことは必須なので、ChatGPTなどうまく活用して、演習問題による想起練習中心の学習を進めていただければと思います。
拙著「ゼロからわかる Linuxコマンド200本ノック―基礎知識と頻出コマンドを無理なく記憶に焼きつけよう!」の200本ノックでは、単純なコマンドの問題だけでなく、用語の意味を問うノックや、機能のメリットを問うノックもあるため、単なるコマンドの暗記で終わらず、応用力もしっかりと身につけることができます。よかったらぜひ、書籍紹介だけでも見てみてください。
👇本書についてより詳しくはこちら