コース一覧
LinuC レベル1 102試験対策(LPIC-1対応)
testと条件式

LinuC レベル1 102試験対策(LPIC-1対応)

LinuC レベル1/LPIC-1の102範囲を、シェル、ユーザーとセキュリティ、ネットワーク、システム管理の実機演習と章末問題で固めます。Linuxを安全に運用するための知識とコマンド操作を体系的に身につける25レッスンのコースです。

1
102 シェルとスクリプト
01. シェル環境18分
02. testと条件式18分
03. スクリプトの制御18分
04. cronとat15分
05. systemdタイマー18分
06. 過去問 シェル15分
2
102 ユーザーとセキュリティ
01. passwdとshadow18分
02. ユーザー管理コマンド18分
03. suとsudo18分
04. 特殊パーミッション18分
05. ホストのセキュリティ18分
06. SSHとGPG18分
07. 過去問 ユーザーとセキュリティ15分
3
102 ネットワーク
01. TCP/IPとウェルノウンポート18分
02. アドレス設定18分
03. ルーティング18分
04. 名前解決の設定18分
05. 疎通トラブルシュート18分
06. 過去問 ネットワーク15分
4
102 システム管理
01. 時刻とNTP15分
02. ロケールと文字コード18分
03. ログ管理18分
04. サービス管理の試験形式18分
05. メールと印刷のきほん15分
06. 過去問 システム管理15分

testと条件式

角括弧の内側に空白が無いだけで「コマンドが見つかりません」と言われます。[ が記号ではなくコマンドだからです。ここを飲み込むと、条件式の問題はほとんど落とさなくなります。

[ はコマンドなので、内側に空白が要る

[ は /usr/bin/[ という実行ファイルとして実在します。だから次の2つはまったく同じ意味です。

ターミナル

test -f /etc/hostname
[ -f /etc/hostname ]

コマンドである以上、コマンド名と引数は空白で区切ります。閉じる ] も [ に渡す最後の引数なので、その前にも空白が要ります。

ターミナル

[ -f /etc/hostname ]     # 正しい
[-f /etc/hostname]       # 誤り。[-f というコマンドを探しに行って失敗する
[ -f /etc/hostname]      # 誤り。] が閉じられていないと怒られる

選択肢を見比べるときは、まず空白の有無を確かめてください。

[[ ]] は bash の拡張構文です。内部で単語分割やパス名展開が起きないため未定義変数に強く、&& || をそのまま書け、=~ で正規表現も使えます。ただし POSIX sh では動かないので、移植性を問われる場面では [ ] を選びます。

-e はディレクトリでも真、-f は通常ファイルだけ

演算子真になる条件
-e file存在する。種類は問わない
-f file存在して、かつ通常ファイル
-d file存在して、かつディレクトリ
-L fileシンボリックリンクである
-r -w -x読み取り、書き込み、実行の権限がある
-s file存在して、かつサイズが 0 より大きい
f1 -nt f2 / f1 -ot f2f1 のほうが新しい / 古い

ディレクトリに対して -e は真ですが -f は偽です。空のファイルに対して -f は真ですが -s は偽です。この2組が引っかけの材料になります。

数値はアルファベット、文字列は記号

種類演算子
数値の比較-eq 等しい / -ne 等しくない / -lt より小さい / -le 以下 / -gt より大きい / -ge 以上
文字列の比較= 等しい / != 等しくない
文字列の長さ-z 長さが 0 / -n 長さが 0 より大きい

数値に = や < を使ってはいけません。[ 10 = 10.0 ] は文字列比較なので偽ですし、[ 5 < 10 ] の < はリダイレクトと解釈されます。逆に文字列へ -eq を使うと数値として解釈できずエラーになります。

変数が空のときに [ $VAR = abc ] と書くと、展開の結果が [ = abc ] となって構文エラーです。[ "$VAR" = abc ] とダブルクォートで囲みます。

真は 0、偽は 0 以外

シェルでは真が 0、偽が 0 以外です。C 言語などとは逆なので混乱しやすいところです。直前のコマンドの終了ステータスは $? で取れます。

ターミナル

[ -d /etc ]
echo $?      # ディレクトリなら 0 が出る

if は、条件に書いたコマンドの終了ステータスが 0 かどうかだけを見ています。だから if grep -q root /etc/passwd; then のように、[ ] 以外のコマンドも条件に書けます。

ターミナル

mode=start
if [ "$mode" = start ]; then
  echo starting
elif [ "$mode" = stop ]; then
  echo stopping
else
  echo usage
fi

then を同じ行に書くなら直前にセミコロンが要ります。閉じるのは fi です。論理の組み合わせは [ ... ] && [ ... ] のように2つ並べてつなぐ書き方が安全で、1つの角括弧の中で使う -a と -o は POSIX で非推奨です。否定は感嘆符です。

試験で狙われるところ

[ の直後と ] の直前の空白。数値は -eq -lt、文字列は = != という取り違え。真が 0 で偽が 0 以外という向き。-e はディレクトリでも真で -f は通常ファイルだけ。そして [[ ]] は bash 専用で /bin/sh のスクリプトでは使えないこと。この5点です。

ヒント

ヒアドキュメントは cat <<'EOF' > /root/check.sh で始め、最後の行に EOF だけを書いて閉じます。EOF をシングルクォートで囲むと $1 が展開されずそのまま書き込まれます

判定は [ -e "$1" ] です。[ の直後と ] の直前に空白が要ります。-f でも通りますが -e のほうが素直です

1行で書くなら if [ -e "$1" ]; then echo EXISTS; else echo MISSING; fi です。then の前の ; を忘れないでください

  • 1. cat <<'EOF' > /root/check.sh の形でスクリプトを書き出す
  • 2. 1行目にシバン #!/bin/bash を書く
  • 3. if [ -e "$1" ]; then echo EXISTS; else echo MISSING; fi の形で判定を書く
  • 4. chmod +x /root/check.sh で実行権限を付ける
  • 5. bash /root/check.sh /etc/hostname を実行して EXISTS が出ることを確かめる
  • 6. bash /root/check.sh /nonexistent を実行して MISSING が出ることを確かめる

Linux は使うときに起動します(初回は約102MB通信します)

4 項目で採点します