サンプルコードで身につける: コマンド行の読み方: $ とコマンドとオプションと引数
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1用語早見表: コマンド行の部品
コマンド行を作っている部品を1つずつ並べた表です。「近いもの」は Node のコマンド行で同じ位置にあるものを指していて、オプションの意味まで同じだということではありません。記号($( ) や * など)の読み方は3本目に、コマンドの一覧は2本目にあります。
用語 | 一言で手元では: 実際のコマンド行での姿近いもの: Node のコマンド行で近いものコマンド行 | 道具の名前と、道具への指示を並べた1行手元では: $ java -cp out app.Main近いもの: $ node dist/main.jsコマンド | 道具の名前。行の最初の語手元では: java、javac、jar、javap、mvn、ant近いもの: node、npm、tscオプション | 道具への指示。- や -- で始まる手元では: javap -p の -p、jar --create の --create近いもの: tsc --project tsconfig.json の --project値を取るオプション | 直後の語を値として受け取る手元では: -cp out、-d out、--file app.jar近いもの: tsc --project tsconfig.json(--project の値がファイル名)引数 | 道具が扱う対象。オプション以外の語手元では: java app.Main の app.Main近いもの: node dist/main.js の dist/main.jsプログラムへの引数 | 道具ではなく、道具が動かすプログラムが受け取る語。java では、クラス名やJAR 名より後ろに書く手元では: java -jar demo.jar --server.port=8084の --server.port=8084近いもの: 対応を確かめていないサブコマンド | 道具の中の、どの仕事をするかを選ぶ語(呼び名は道具ごとに違う。jar では操作、Maven ではフェーズやゴール)手元では: docker history の history、jar tf の tmvn package の package近いもの: npm run build の run(npm の文書は run を command と呼ぶ)短い形と長い形 | 同じ指示の2通りの書き方手元では: -cp と --class-pathjar tf と jar --list --file近いもの: 対応を確かめていない続け書き | 1文字のオプションを続けて書いた形手元では: jar tf app.jar(t と f の2つ)curl -si(-s と -i の2つ)近いもの: 対応を確かめていない出力 | コマンドが表示した行。$ が付かない手元では: Hello, world! sum=5近いもの: 同じ終了コード | コマンドが終わるときに返す数0 が成功、0 以外が失敗手元では: ログの [exit 0] や [exit 1](実験用のスクリプトが書き足した行)近いもの: 同じ(シェルの決まり)
2このコースに出るコマンドの早見表
コースの図・サンプル・実物に出てくるコマンドを、 のもの、、別に入れる道具、OS の一般的な道具、比較用の Node と Rust の道具に分けた表です。JDK の一部なのは最初の組だけです。実測に使った JDK 25 だけのには、、、、、 が入っていませんでした。
コマンド | 何の道具か# JDK に入っているものjava | Java のプログラムを起動する(JVM を立ち上げる)javac | .java から .class を作るコンパイラjar | .class をまとめて JAR を作る。JAR の中を見るjavap | .class の中身を、人が読める形で表示するjarsigner | JAR に署名を付ける、署名を確かめる(このコースでは名前だけ出る。jshell、jlink、keytool なども、bin の一覧の中に名前だけ出る)# ビルドツール(JDK には入っていない)mvn | Maven を実行する./mvnw | Maven のラッパー決まった版の Maven を取ってきて実行するスクリプトant | Ant を実行する./gradlew | Gradle のラッパー($ gradle ... と打つ行は、このコースには出ない)# 別に入れる道具(JDK のものではない)curl | URL を指定して、サーバとデータをやり取りする-i は応答のヘッダも表示、-s は進み具合などを出さない-si は、その2つの続け書きwget | curl と同じく、URL からデータを取ってくる道具(名前だけ出る)unzip | zip の中身を一覧する、取り出す(JAR は zip 形式なので、JAR にも使える)-l は一覧、-v は詳しい一覧、-p は中身を画面に出すtree | フォルダの中身を、木の形で一覧するtree -a は、隠しファイル(. で始まる名前)も出すxxd | ファイルの中身を16進数で表示するstrace | プログラムが OS に頼んだ処理を記録する(Linux)docker | Docker を操作するdocker history はイメージの履歴、docker images は一覧native-image | GraalVM に入っているコマンドJava のアプリを実行ファイルに前もってコンパイルする(後のレッスンで扱う)# OS の一般的な道具(JDK でも Spring でもない)ls | フォルダの中身を一覧するls -l は大きさなども出す、ls -a は隠しファイルも出すこのコースでは: できたファイルを確かめるcd | 今いるフォルダを移るfind | フォルダの階層から、ファイルを探して一覧する-type f はファイルだけ、-name は名前で絞るこのコースでは: ソースや .class の一覧を出すgrep | 指定した文字を含む行だけを出す-v は含まない行を出す、-c は行数を出すsort | 行を並べ替える(一覧の順をそろえる)wc | 数える。-l は行数(一覧の件数を数える)head | 先頭の行だけ出す。head -1 は1行だけcat | ファイルの中身を表示するecho | 後ろに書いた文字を表示するawk | 行を空白で区切り、指定した列だけ出すなどの加工このコースでは: ls -l から大きさと名前の列を出すdiff | 2つのファイルの違う行を表示するmkdir | フォルダを作る。-p は途中のフォルダも作るcp | ファイルをコピーするrm | ファイルを消すtouch | ファイルの更新時刻を今にするこのコースでは: ソースを変えたことにするsleep | 指定した秒数だけ待つdu | フォルダやファイルの大きさを出すdu -sh は合計を読みやすい単位で、du -sk は KB 単位で(-s が合計だけ、-h が読みやすい単位、-k が KB 単位。du -h だけなら、中のフォルダごとに出す)ps | いま動いているプロセスの一覧を表示する-e は全部のプロセス、-o は表示する項目の指定/usr/bin/time | コマンドにかかった時間などを報告するuname | OS などシステムの情報を表示するmake | ソースからファイルを作る手順を実行する道具(Ant の説明で、似たものとして名前が出る)# 比較のために出る、Node と Rust の道具node | Node.js を起動するnode -r 名前 は、先に読み込むモジュールの指定--print-bytecode は、V8 のデバッグ用の指定npm | Node のパッケージの道具npm install と npm ci は依存を入れるnpm run は scripts に書いた手順を実行するnest | NestJS の道具。nest new は雛形を作るnest build はビルドするtsc | TypeScript のコンパイラcargo | Rust のビルドの道具cargo build --release の形で出るrustc | Rust のコンパイラ(版の表示に名前が出る)
3シェルの記号の早見表: $( )、*、引用符、~、;、$?
コマンド行に混ざる記号のうち、Java の道具ではなくシェル(コマンドを打ち込む画面)が読むものを並べました(読み方は GNU Bash のマニュアル 5.3 版で確かめたものです)。 "*" の * だけはで、シェルではなく が読みます。末尾は実物で、強調した行が終了コードの表示です。
記号 | 意味手元では: コースに出る形$(行頭) | プロンプト。ここからがコマンド。打たない./ | その場所にあるファイルを実行する(/ を含まない名前は、決まった場所の一覧から探す)手元では: ./mvnw、./gradlew| | 左のコマンドの出力を、右のコマンドの入力にする手元では: jar tf app.jar | wc -l&& | 左が成功(終了コード 0)したら、右を実行する手元では: ls -l app.jar && jar tf app.jar; | 左が終わったら、続けて右を実行する手元では: sleep 1; touch ...; ant$( ... ) | かっこの中のコマンドを実行し、その出力をその場に埋め込む手元では: javac -d out $(find src -name "*.java")find が見つけた .java の名前が、javac の引数として並ぶ*(引用符なし) | 名前が合うファイルの一覧に置き換わる手元では: ls -l *.jar(.jar で終わるファイル全部)' ' | 中の文字を、そのまま1語として道具に渡す" " | 同じ。ただし中の $ などはシェルが読む手元では: find src -name "*.java"(* をシェルに置き換えさせず、find に渡す)\ | 次の1文字を、シェルに読ませずそのまま渡す手元では: awk "{print \$5, \$9}"~ | 自分のホームフォルダ手元では: ~/.m2/repository$HOME | ホームフォルダの場所が入った変数(~ と同じ場所)手元では: $HOME/.m2/repository/...$? | 直前のコマンドの終了コード手元では: echo "mvn exit $?"` ` | $( ) の古い書き方。このコースでは、補足の文の中でコマンド名を囲む印としてだけ出る手元では: (after the first, cold `mvn package` ...)# シェルではなく java が読む *-cp "lib/*" | lib の中の .jar 全部、というjava のクラスパスの書き方(java のマニュアル)引用符で囲んであるので、シェルは * を置き換えず、そのまま java に渡る手元では: java -cp "app.jar:lib/*" com.example.app.Mainjava -cp 'out:lib/*' demo.XmlMain# 実物: 終了コードが見える2つの例$ mvn -B -o -ntp -q package; echo "mvn exit $?"mvn exit 0$ java NopeError: Could not find or load main class NopeCaused by: java.lang.ClassNotFoundException: Nope[exit 1]
4どこまでが java への指示で、どこからがアプリへの引数か
java のコマンド行は、名( のときは 名)を境に、前が java への指示、後ろが動かすプログラムへの引数です。 は、-- で始まる引数を設定値として読みます。-Dserver.port=8085 と --server.port=8084 はどちらもポートの設定ですが、前者は java に、後者はアプリに渡していて、両方書いたときは引数の 8084 で待ち受けました(Spring Boot 4.1.1)。
# 書式(java のマニュアル)# java [オプション] クラス名 [引数 ...]# java [オプション] -jar JARファイル [引数 ...]$ java -cp out -Dwho=Java app.Mainjava への指示: -cp out、-Dwho=Javaアプリへの引数: 無し$ java -jar demo.jar --server.port=8084java への指示: -jar demo.jarアプリへの引数: --server.port=8084(Spring Boot が設定値 server.port として読む)$ java -Dserver.port=8085 -jar demo.jarjava への指示: -Dserver.port=8085、-jar demo.jar(-D はシステムプロパティ。java が受け取る)アプリへの引数: 無し$ java ... l17.plain.PlainApp --debugアプリへの引数: --debug(Spring Boot が読む。java の指示ではない)$ java -Djarmode=tools -jar demo.jar list-layersjava への指示: -Djarmode=tools、-jar demo.jarアプリへの引数: list-layers(JAR に付いている道具に、層の一覧を頼む)$ java -Xshare:off -Xlog:class+load -cp out com.example.demo.Hellojava への指示: -Xshare:off、-Xlog:class+load、-cp outアプリへの引数: 無し# コースに出る、アプリへの引数(どれも Spring Boot が読む)# --server.port=8084# --debug# --spring.threads.virtual.enabled=true# --spring.jpa.show-sql=true# --spring.jpa.open-in-view=false# --spring.aop.proxy-target-class=false# --logging.level.org.springframework.boot=DEBUG# --app.greeting=...、--app.max-retry-count=2
5混同しやすいもの: 同じ文字のオプションは、道具ごとに意味が違う
コースに出るオプションのうち、同じ文字で意味が違うものを並べました。この表の例では、-v は だけが版の表示で、-p は5つとも別の意味で、大文字と小文字も別のオプションです。-cp は java、、 のどれでも「クラスを探す場所」で、これは同じ意味の例です。
オプション(道具) | 意味例: コースに出る形-v(mvn、./mvnw) | 版を表示する(長い形は --version)例: ./mvnw -v-v(ant) | 詳しく表示する(長い形は -verbose)例: ant -v-v(javap) | そのクラスの詳しい情報を表示する例: javap -v Hello.class-v(unzip) | 詳しい形式で一覧する(zip を指定しないと、unzip 自身の版の情報を出す)例: unzip -v の後ろに JAR のファイル名-v(grep) | 指定した文字を含まない行を出す例: jar tf ... | grep -v BOOT-INF/lib/.-p(javap) | private なものも含めて全部表示する例: javap -p -cp out lib.util.Greeter-p(ant) | 手順(target)の一覧を表示して終わる例: ant -p-p(unzip) | 取り出した中身を、画面(標準出力)に出す例: unzip -p app.jar META-INF/MANIFEST.MF-p(java) | モジュールを探す場所(--module-path)例: java -p ... --add-modules spring.core,org.slf4j ...-p(mkdir) | 途中のフォルダも作る例: mkdir -p flat-l(unzip) | 中のファイルを一覧する例: unzip -l の後ろに JAR のファイル名-l(ls) | 大きさなども付けて一覧する例: ls -l app.jar-l(wc) | 行数を数える例: find out -type f | wc -l-c(javap) | メソッドごとの命令列を表示する例: javap -c -cp out app.Main-c(grep) | 合った行の数を出す例: jar tf ... | grep -c BOOT-INF/lib/.*jar-C(jar) | 指定したフォルダに移ってから、ファイルを入れる例: jar --create --file app.jar -C out .-d(javac) | .class の出力先のフォルダ例: javac -d out src/app/Main.java-D(java) | システムプロパティ(名前と値の組)を設定する例: java -cp out -Dwho=Java app.Main-D(mvn) | Maven に設定値(プロパティ)を渡す例: mvn install -DskipTests(Maven 公式の例)-i(curl) | 応答のヘッダも表示する例: curl -i http://localhost:8080/hello-o(mvn) | オフラインで動かす-o(ps) | 表示する項目を指定する例: ps -eo pid,rss,etime,args-cp(java、javac、javap) | クラスを探す場所(3つとも同じ)例: java -cp out app.Main