Bo2SS

Bo2SS

7 シェルプログラミングの基礎

高級言語、スクリプト言語、インタプリタ言語:xxx.sh、一般的に bash に基づく

コース内容#

最初のシェルスクリプト#

#!/bin/bash
#コメント
echo "Hello"
  • 最初の行 #! はインタプリタを指定し、最初の行でのみ有効
  • コメント:"#"

変数#

a=123
a=hello
a=`pwd`
PATH=${PATH}:path  # 変数の後に文字列を付けることができ、文字列を直接結合できる
# 【注意】":a"には特別な意味があり、現在のパスを指す
  • 変数の型を定義する必要はない【弱い型の言語】
    • 例えば a=123 は文字列にも整数にもなり得る
  • "" には特別な意味がある
    • img
    • a を二重引用符で囲むことができる、例えば a=$a:"a" または a=$a"" とすると、a=123になる

特殊変数#

位置変数

  • image-20201218170251055

結果:

  • image-20201215174953312
  • $n:n が 9 より大きい場合、大括弧で囲む必要がある

  • $@ と $* の違いは:渡された引数がそれぞれ二重引用符で囲まれ、かつ $ 変数も二重引用符で囲まれている場合、"$@" はすべての引数を分ける【一般的な場合】が、"$*" はすべての引数を一つの全体として扱う

  • $#:$0 はカウントしない

状態変数

  • $?:【前の】コマンドの実行結果、0—— 成功、非 0—— 失敗
    • 画像
    • スクリプトがコマンドの成功を自動的に判断するのに便利
  • $$、$!:現在のプロセス、最後に実行されたバックグラウンドプロセスの PID、一般的に自動化テストや複数スクリプトのインタラクションシーンで使用される

入力と出力#

  • 入力:read
    • 画像
    • -p:フレンドリーなプロンプトを表示、bash で使用する必要がある
    • -s:サイレントモード
    • -t:入力待機時間、タイムアウト終了(単位:s)
  • 出力:echo
    • -e:エスケープを有効にする
  • 出力:printf
    • C 言語の printf に非常に似ている!
    • 画像
    • [PS] ! と \n を一緒に使うと特別な意味があるため、分ける必要がある
      • bash では分ける必要がある
      • zsh では分けることができるか、\ でエスケープすることができる
      • 一般的に特殊記号—— 菜鳥教程に注意が必要!

関数#

  • 画像
  • 引数はない

  • 定義:書き方は多く、function、()、{} の組み合わせ、3 番目の方法は C 言語の書き方に似ている

  • 呼び出し:関数名 引数...

    • 画像
    • function を加えることで読みやすくなる
  • ❗【注意】シェルの関数 return の返り値には制限があり、範囲は 0-255、オーバーフローすると循環計算される

フロー制御#

do——done、if——then——fi、case——esac

【重要】TEST 式⭐#

  • 型を判断できる:文字列、整数、ファイル
  • ❗ 【注意】条件が真のとき、0 を返し、そうでない場合は非 0 を返す
    • Linux のコマンドの返り値も同様で、0 が成功を示す
  • [PS]
    • STRING1 = STRING2 は == でも可能【後者を推奨、二重括弧 [[]] がサポートされている】
    • -G FILE:ファイルが存在し、かつ有効なグループ ID に所有されている
      • グループが解散された場合、そのグループが管理するファイルのグループ ID は無効になる
    • 詳細は man マニュアルを参照:man test

分岐構造#

if

  • 画像
  • if は二重括弧 [[]] の書き方を使用し、より高度で TEST 式との互換性が良い

case

  • 画像
  • セミコロン;;は必ず必要!break に相当し、break を加えた場合も必要

  • デフォルトの状況は *) を使用できる

  • case はあまり使用されず、一般的にメニューを作成するために使用され、if よりも美しい

ループ構造#

for

  • seq を利用してシーケンスを生成

  • 画像
  • ls のマッチングルールを利用

  • 画像
  • for の 2 つの形式

  • 画像
  • 二重小括弧 (()) の中の内容は C 言語の演算ルールに従う限り、変数の前に $ を付ける必要はなく、i++ と書くことができ、通常は ++ を使用できない

while

  • 画像
  • 同様に test 式が適用される

  • num 変数を初期化しないと

    • 最初の echo $num 時、$num は空値であり、空行として表示される
    • 後の + 1 に遭遇したとき、システムはそれを整数型として判断し、整数として扱う

until

  • 画像
  • while との唯一の違いは:until は停止条件を書き、while はループ条件を書く

配列#

  • 画像
  • 配列の代入【方法①】と呼び出し

  • 画像
  • 【一般的な配列操作】は配列要素のインデックスを出力することもできる、後で見て

  • 画像
  • 配列を宣言する:declare -a num、読みやすくするため、宣言しなくても可能【弱い型の言語】

  • 代入【方法②、③】

    • num[2]=10 num[5]=7 num[100]=3.2.4
    • num=(1 a b 10)
  • 配列要素は必ずしも連続して代入する必要はなく、任意の型を持つことができる

    • 【一般的な配列操作】加!:すべての配列要素に対応するインデックスを出力し、連続していないことがわかる

【その他の配列操作】

  • 画像
  • +=:追加

  • unset:配列または要素を削除する【インデックスで削除】

  • [PS] 代入方法③は複数の空白も 1 つの区切り文字として扱う

応用

  • 画像
  • ファイル名リストを保存するために使用できる

  • 【注意】代入方法③で配列に代入する際は空白を区切り文字として使用するため、ファイル名に空白が含まれている場合は特別な処理が必要

  • 【PS】素数フィルタ、線形フィルタ

授業の練習#

1~100 の偶数の合計#

  • 画像
  • $[ ] は整数演算に使用できる

  • seq は効率がやや低い

力任せに素数を求める#

  • 画像
  • 関数の return 値

    • $? を通じて得られ、関数を呼び出した後に echo $? を実行すればよいが、return 値には範囲制限がある 0~255!
    • コマンド置換符 `` を使用して取得する
  • ループ変数 i の衝突問題に注意:ローカル変数を定義する

  • 🆒プログラムのデバッグ

    • 習慣:適度な echo 出力
    • グローバルデバッグ:bash -x *.sh
    • ローカルデバッグ:set -x [デバッグコード領域] set +x

素数フィルタ#

  • img
  • 方法一は素数を操作するのに便利で、出力時に判断を減らすことができる

  • 方法二は合成数を操作することもできる

【力任せ法、素数フィルタの 2 つの方法の効果比較】2~10000 の素数の合計を求める

img

  • 9.prime.sh 力任せ法 —— 10.prime.sh 素数フィルタ

追加の知識点#

  • .sh スクリプトは直接 bash または source で実行でき、./ を使用するには実行権限が必要
  • set -x はシェルデバッグを有効にする
  • シェルコマンド置換:コマンドの出力結果を変数に代入する——C 言語中文網
    • $() はネストをサポートし、バッククオート `` はサポートしない
    • $() は Bash でのみ有効【zsh、sh もサポートしているようだ】、バッククオート `` は多くのシェルで使用可能
  • 二重小括弧 (()) の中の内容
    • C 言語の演算ルールに従う限り
    • 変数の前に $ を付ける必要はない
    • i++ と書くことができ、通常は ++ を使用できない
  • ⭐シェルでは、変数がまだ定義されていない場合、その値は空であり、echo 出力は空行として表示される
  • ⭐空白の問題【厳密】
    • 代入文:= の左右には空白を含めてはいけない
    • TEST 式関連:[[]] の両端には空白が必要
  • 変数名 i について、$i と_i を結合したい場合、$i_i と書くと変数 i_i を探しに行くため、${i}_i を使用する必要がある

ヒント#

  • シェルスクリプトを書く際
    • 性能をあまり考慮せず、単純に数学計算の効率は低い
    • 問題を迅速に解決するために、すべてのタスクのフローを計画するために使用する
    • 操作の前に【バックアップ】操作を加えることを忘れない
    • 一般的にはシステムに作業をさせることが多く、特定のプログラムに作業をさせるのは難しい
      • プログラムは一般的に独自のパラメータ設定を持っているが、普遍性はない
  • API は一般的にサービスを指す
  • シェルスタイルガイド——Google オープンソースプロジェクトスタイルガイド —— シェルプログラミング規範
  • シェルスクリプトの複数行コメントと単行コメントの方法—— ブログ
:<<!
[コメントするコード]
!
  • let—— 菜鳥教程を理解すると便利な構文

コースの速記#

  • 画像
  • 画像
  • 画像
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。