→ もくじ
bashlib1
- shorthand library for bash -
→ bash をコーディングするときの注意点
bash シェルをスクリプトとして使うときに、必要となる機能を提供するライブラリです。
事前の状況チェックや、事後のエラーチェックが不要になり、コードがシンプルになります。
短いオプションや特殊記号を減らして、読めるだけでなく検索できるようになります。
エラーが発生したら停止して、その場所を表示します。(フェイル・セーフ)
許可したフォルダーの外のファイルを消そうとしたらエラーにします。(フール・プルーフ)
構造化例外処理ができるため、エラーのテストやエラー復帰ができます。
ステップ実行ができるため、不具合を早く修正できます。
#!/bin/bash -eE
function Main_func()
{
echo "Hello, world!"
Pause_func
}
#// bashlib include
sample.sh
bash シェルの画面
$ ./sample.sh
Hello, world!
続行するには Enter キーを押してください...
ダウンロード
→ bashlib-1.0.0.tar.bz2
for bash ver3以上 (Linux, MacOS X)
ライセンス
→ BSDライセンス - Wikipedia (Web)
bashlib is provided under 3-clause BSD license.
Copyright (C) 2011 Sofrware Design Gallery "Sage Plaisir 21" All Rights Reserved.
参考
無料でお使いいただけますが、無保証です。
再頒布や加工もファイルに書かれた下記を削除しなければ自由にできます。
bashlib を参考にして作成したスクリプトやライブラリの著作権は、あなたにあります。
ソフトウェアデザイン館 Sage Plaisir 21 http://www.sage-p.com/
サポート先
2011/10/9
$
bashlib がベースとするシェルスクリプトの説明です
bashlib のマニュアル(本書)です
bashlib ヘルプ
画面で見るマニュアル
シェルスクリプト(bash)
インストール
→ インストール
→ アンインストール
とりあえず動かしてみたいときは、
version 1
bashlib include
→ シェル・スクリプトを読むには
Main_func
Pause_func
bashlib の menu
を開いてください。
この文書(HTML5)を見るときは、Chrome または Mac OS X の Safari をお使いください。
UNIX & Linux
ファイルやシェルの基本的なコマンドの説明です。
この文書は Snap Note を使って作られています。
上記リンク先は、
Internet Explorer 版の文書
でのみ参照できます。
もくじ
bashlib1
はじめに (scriptlib フォルダー)
開発方針
シェル・スクリプトを読むには
bash を使ってコーディングするときの注意
Mac OS X のテキストエディットを使って編集する
メニュー、ショートハンド・プロンプト (menu, setup)
メニューを開くには
ショートハンド・プロンプトの活用
bashlib の menu
SearchFile コマンド
NewSh コマンド
NewMenu コマンド
Extract コマンド
chmod_x コマンド
ユーザーインターフェース
EchoOn_func
EchoOff_func
echo_line_func
echo_e_func
ColorText_func
Pause_func
Input_func
SetAutoInputFromMainArg_func
InputPath_func
InputCommand_func
InputOption_func
ファイル操作
AppKeyClass.newWritable_method
CheckWritable_func
mkdir_func
mkdir_for_it_func
rm_func
sudo_func
chown_it_and_parent_func
chmod_x_func
MakeSymbolicLink_func
readlink_func
Extract_func
ListUpIn_func
ExpandWildcard_func
ReplaceTextFile_func
ReplaceTextFileLineRange_func
GetAbsPath_func
GetParentAbsPath_func
SearchParent_func
その他
プロセス制御、関数呼び出し
GetLongOptions_func
CheckArgCount_func
CheckMinArgCount_func
CheckMaxArgCount_func
CheckOutParamIsConflictToLocal_func
CheckEvalParamIsConflictToLocal_func
local_func
SetOutput_func
SetOutputAsArray_func
GetUsableCommands_func
GetUsableApplicationsForMac_func
IsMac_func
IsInstalled_func
AppKeyClass.enableInstall_method
InstallIfNot_func
Uninstall_func
その他
テスト支援
Assert_func
EchoTestStart_func
その他
文字列
LF, Tab
AddIfNotExist_func
IsNumeric_func
StringClass.length_method
StringClass.substring_method
StringClass.trim_method
StringClass.right_method
StringClass.cutLastOf_method
LeftOfStr_func
LeftOfLastStr_func
RightOfStr_func
RightOfLastStr_func
StringClass.indexOf_method
StringClass.lastIndexOf_method
StringClass.replace_method
StringClass.toLowerCase_method
StringClass.toUpperCase_method
StringEscapeUtilsClass.escapeGrep_method
StringEscapeUtilsClass.escapeSed_method
StringEscapeUtilsClass.escapeBashReplace_method
StringEscapeUtilsClass.escapeBashDoubleQuot_method
StringEscapeUtilsClass.escapeBashParam_method
MultiLine_func
その他
配列
ArrayClass.getLength_method
ArrayClass.get_method
ArrayClass.set_method
ArrayClass.remove_method
ArrayClass.clear_method
ArrayClass.fromLines_method
ArrayClass.fromCSV_method
IsSameArrayOutOfOrder_func
その他
連想配列、オブジェクト
bashlib を使ったオブジェクト指向記述法 - bashool
bashlib を使った多態性(ポリモアフィズム)
declare_AssociativeArrayClass
Attr_func
SetAttr_func
AssociativeArrayClass.getLength_method
AssociativeArrayClass.getKeys_method
AssociativeArrayClass.getItems_method
AssociativeArrayClass.destroy_method
CopyArray_func
CopyArrayAttr_func
SetAttr_as_ArrayName_func
SetAttr_as_AssociativeArrayName_func
bashlib_inc.sh (bashlib のベース・システム)
Main_func
g_StartInPath
g_Arguments
エラー処理
CheckPipeStatus_func
done_func
Error_func
g_Err_Desc
g_ExitStatus
TryStart_func, TryEnd1_func, TryEnd2_func
ErrClass.raiseOverwrite_method
ErrClass.clear_method
その他
困ったときは? (デバッグ)
de, debugger
ec
es
はじめに (scriptlib フォルダー)
bashlib を使うと、ファイル操作やプログラムの起動などを行う、スクリプトの
作成(プログラミング)が簡単になり、いろいろなことが自動化できます。
そして、作成したスクリプトを、
スクリプトの発動が素早くできるようになります。
ショートハンド・プロンプト
の形式にすれば、
複雑な処理を自動化
シェル・スクリプト
パソコン
解凍(コピー)するだけで、
+
scriptlib
インストール
bashlib で作られたスクリプトのインストールは、スクリプト・ファイル
と一緒に scriptlib フォルダーをコピーするだけです。 このとき、bashlib
パッケージをインストールしたり、パスを通したりする必要はありません。
bashlib パッケージのインストールは、ダウンロードした圧縮ファイルを解凍
アンインストール
bashlib の圧縮ファイルを解凍してできたフォルダーを削除してください。
scriptlib フォルダーを別の場所にコピーしていたら、それも削除してください。
するだけです(下記を参照)。とりあえず動かしてみたいときは、インストール
bashlib の menu を開いてください。
Mac OS X (Snow Leopard) から圧縮ファイルを解凍する
Ubuntu (lucid) のデスクトップから圧縮ファイルを解凍する
シェルから圧縮ファイルを解凍する
→ Mac OS X のテキストエディットを使って編集するには
cd <bashlib フォルダーを格納するフォルダー>
tar xvf bashlib-1.0.0.tar.bz2
ダウンロードした bashlib-1.0.0.tar.bz2 圧縮ファイルをダブルクリックすると、
解凍されて、bashlib フォルダーができます。
参考
ダウンロードした bashlib-1.0.0.tar.bz2 圧縮ファイルを右クリックして、
[ ここに展開する ] を選ぶと、bashlib フォルダーができます。
関連
後、
開発方針
・100ページの説明をするより、1つでも典型的でシンプルな動くサンプルを提供すること
・結果が同じであれば、エラーにしないこと。 例:ファイルが無いパスを指定して削除したとき
・文書の大項目はユースケースであること。 レアケースである細かい仕様を主役にしないこと
・文書はユーザーが行う操作の順に書くこと。 「ただし、~してあること」を無くすこと
・ユーザーから見ると意味が異なる、ボトムアップから定義された用語は使わないこと
・メインのコードの前提条件と、何を行っているのかについて、コメントを母国語で書くこと
・エラーが発生して復帰するまでは、次のエラーが発生しても、最初のエラーを表示すること
・シンボルの大文字と小文字のコーディング・ルールは Java に標準化すること。
・ユーザーの体験が、シンプル&ビジュアルであり、代償によって自由を奪わないこと。
シェル・スクリプトを読むには
参考
→ bash の特殊記号一覧
bashlib が提供する関数の末尾は、_func または _method に統一されています。
これにより、関数であるかコマンド(実行ファイル)であるかを識別できます。
関数の内容を知りたいときは、bashlib のドキュメントを検索するか、scriptlib フォルダー
の中を検索してください。 なお、
一部、デバッグ専用の関数は、その内容を理解している本人しか見ないコードであることと、
キーボードをタイプする量を減らすために、_func を付けていません。
関数のヘルプやソースコードを見る、またはコマンドのヘルプを見る
bash の特殊記号の意味を知る
Main_func 関数から読む。bashlib の起動順序を知る
bashlib を使ったシェル・スクリプト・ファイルを実行すると、その最後にある
bashlib のインクルード
を実行すると、
Main_func 関数
が呼ばれます。 Main_func 関数
が呼ばれたら、bashlib が提供する関数を使うことができます。
参考
→ bash における関数の記述方法
→ デバッグ
動かしてみて、デバッグ用関数を使って、状況を知る
参考
他の人からシェル・スクリプトを入手したときに、その内容をソースコードから理解する
ときのコツを紹介します。
末尾が _method の関数の場合、*Class.*_method というオブジェクト指向を意識した
関数名になります。 ピリオドが含まれていますが、bash では特別な文法的意味はなく、
英文字と同じく関数名の一部です。
_func や _method が付いていない実行ファイルの仕様は、which や man を使って
調べてください。
からファイルの検索が
menu の SearchFile コマンド
できます。
スクリプトが bashlib を使っていれば、デバッグ用関数を使って内部の状況を知ること
ができます
bash を使ってコーディングするときの注意
bashlib は、エラーが発生すると即時に中断(フェールセーフ)するため、終了ステータス
を毎回チェックする必要がありません。
しかし、一部のケースで、エラーを無視して続きを実行してしまうことがあります。
(これは、終了ステータスを毎回チェックするコーディングに戻しても発生します。)
この問題を避けるため、いくつかのコーディングの注意点があります。
ループの終わりの done_func $?
bashlib は、エラーが発生したとき、trap した関数の中から break ジャンプをしていま
す。(関数名が見つからないなど、終了ステータスが 0 のままエラーが発生する場合に
も構造化例外処理に対応できるようにするため。)
正常時の break と区別するため、ループの終わりの done の直後に done_func を呼び
出すようにしてください。 そうしないと、エラーが発生しても、続きを実行してしまい
ます。
while true; do
CheckWritable_func "$PWD/out/a.txt"
break
done ; done_func $?
done_func $?
→ done_func
参考
呼び出し(echo 出力の取得)は、必ず変数に代入する
local var=`FuncA_func`
local var ; var=`FuncA_func`
local 変数の宣言と関数を使った代入を同時に行うと、右辺からエラーが発生しても、
続きを実行してしまいます。 宣言と代入を別の文に分けてください。
(これは、代入文が、local コマンドの引数になっているためと思われます。)
var ; var
パイプの終了ステータスをチェックする
パイプを使うと、パイプの左(最も右以外)で終了ステータスが 0 以外でも(エラーが
発生しても)、続きを実行してしまいます。 これを避けるため、パイプを使った文の
直後に、CheckPipeStatus_func を呼び出す必要があります。
make V=1 2>&1 | tee make.log
CheckPipeStatus_func "${PIPESTATUS[@]}"
CheckPipeStatus_func "${PIPESTATUS[@]}"
→ CheckPipeStatus_func
参考
if [ "`gcc -dumpversion`" != "4.4.3" ];then
条件文の中から、関数呼び出しを行うと、関数内からエラーが発生しても、続きを実行
してしまいます。 一時的な変数に代入してから、条件文に渡してください。
(これは、条件文の前の [ が test コマンドの別名であるため、条件文の中は test コマ
ンドの引数になっているためと思われます。)
関数やコマンド(A_func とする)の引数の中に、関数(B_func とする)の呼び出しを
記述すると、B_func の中で発生したエラーを無視して、続きを実行してしまいます。
B_func の echo 出力を、一時的な変数に代入してから、引数に渡してください。
A_func "`B_func`"
local a1
a1=`B_func`
A_func "$a1"
終了ステータスの取得は、|| を使う
bashlib を使った場合、終了ステータスが 0 以外になると(エラーが発生すると)、
フェールセーフのため、続きを実行しません。 まれに、エラーが発生しても、
続きのコードから終了ステータスの値を使った処理をしたいことがありますが、
そのときは、|| を使います。
local status=0
command || status=$?
local status=0
ls --unknown_option > /dev/null 2>&1 || status=$?
echo "$status"
サンプル
→ TryStart_func, TryEnd1_func, TryEnd2_func
関連
NG
OK
→ echo による返り値
参考
OK
NG
OK
NG
local a1
a1=`B_func`
if [ "$a1" != "4.4.3" ];then
a1=`B_func`
a1=`B_func`
local 変数の初期値に呼び出しがあるときは、宣言と代入を別の文に分ける
条件文の中から呼び出しをしない
… command からエラーが発生しても続きを実行する
構造化例外処理
→ 呼び出し(echo 出力の取得)は、必ず変数に代入する
→ local 変数の初期値に呼び出しがあるときは、宣言と代入を別の文に分ける
→ 条件文の中から呼び出しをしない
→ ループの終わりの done_func $?
→ パイプの終了ステータスをチェックする
→ 終了ステータスの取得は、|| を使う
Mac OS X のテキストエディットを使って編集する
Mac OS X のテキストエディットを使って、シェルスクリプト(テキストファイル)を
開こうとしたときに、「日本語には対応していません」というエラーが出るときは、
文字コードが自動判定になっているために、UTF-8 の文字コードを認識できない可能性が
あります。
[ テキストエディット | 環境設定 | 開く/保存 ] の [ ファイルを開くとき ] [ ファイルを
保存するとき ] を UTF-8 に設定してください。
メニュー、ショートハンド・プロンプト (menu, setup)
メニューを開くと、ショートハンド・プロンプト(CUI)が表示され、そこにコマンドを入力すると、
用意されたスクリプトを素早く起動することができます。 ドキュメントにコマンド名が書かれて
いれば、専門家でなくてもコンピューターに処理させたい作業を実行することができるように
なります。
→ InputCommand_func
ショートハンド・プロンプトを起動する関数(開発者向け)
$ ./menu
-------------------------------------------------
1. 作業Aを行う [CommandA]
2. 作業Bを行う [CommandB]
3. 作業Cを行う [CommandC]
99. 終了
番号またはコマンド >2
-------------------------------------------------
ログ・ファイルのパス >~/log.txt
~/log.txt を出力しました。
→ bashlib_menu
bashlib が提供するツールのメニュー
→ メニューを開くには
~/log.txt
2
上記の黄色い部分が、ユーザーが入力する部分です。
プロンプト(InputCommand_func)には、シェルのコマンドも入力できます。
→ ショートハンド・プロンプトの活用
./menu
メニューを開くには
メニューを開くには、menu シェル・スクリプト・ファイルを実行します。
場合によっては、setup など別のファイル名になっている可能性もあります。
ただ、必ずしもシェルから起動する必要はありません。
→ メニューから選び、対話的に入力する
つづき
→ シェルから専用コマンドを実行する
関連
シェルからメニューを開く
cd bashlib
./menu
Mac OS X (Snow Leopard) からメニュー(シェル・スクリプト)を開く
Mac OS X で bash シェルを開くには、Finder [ 移動 | アプリケーション | ユーティリティ
| ターミナル ] を Dock にドラッグ&ドロップして、できたアイコンをクリックします。
Ubuntu (lucid) のデスクトップからメニュー(シェル・スクリプト)を開く
Ubuntu でシェルを開くには、[ アプリケーション | アクセサリ | 端末 ] を選びます。
Ubuntu (lucid) のデスクトップからシェル(端末)を開く
Mac OS X (Snow Leopard) からシェル(端末)を開く
menu ファイル(シェル・スクリプト・ファイル)をダブルクリックして、
「端末内で実行する」を選んでください。
menu ファイル(シェル・スクリプト・ファイル)をダブルクリックしてください。
→ Ubuntu のデスクトップからシェル(端末)を開く (下記)
→ Mac OS X からシェル(端末)を開く (下記)
→ InputCommand_func
参考
入力できる専用コマンドは、多くの場合、アプリケーションのマニュアルに書かれています。
自分がしたいことをマニュアルの目次から見つけたら、その本文から専用コマンドを探して
ください。
画面で見るマニュアルを見ているのなら、専用コマンドをコピー&ペーストできます。
ペーストするときは、右クリックして [ 貼り付け ] をクリックしてください。
よく使うコマンドは、付箋紙や Snap Note のノート・バーなどに一時的に貼り付けておくと
便利に使えます。
テンポラリ・フォルダーを開く
OpenTemp
画面で見るマニュアル
vbslib を使ったスクリプトを実行すると、その実行のために内部的に必要になる
ファイルが、テンポラリ・フォルダーに作られることがあります。
menu
ここを選択して、右クリックして [ コピー ] をクリック、
ショートハンド・プロンプトに貼り付け。
ショートハンド・プロンプトに入ります
1. 作業Aを行う [CommandA]
2. 作業Bを行う [CommandB]
3. 作業Cを行う [CommandC]
99. 終了
番号またはコマンド >2
-------------------------------------------------
ログ・ファイルのパス >~/log.txt
~/log.txt を出力しました。
~/log.txt
2
OS によっては、ファイルをプロンプトにドラッグ&ドロップすることで、パスを入力できます。
上記の黄色い部分が、ユーザーが入力する部分です。
コマンド名は、大文字と小文字を区別しません。 つまり、コマンド名の大文字の文字が小文字
になっていたとしても起動できます。
コマンドを入力した後、パラメーターやファイルへのパスの入力を求められることがあります。
使い勝手の悪い専門的なプログラムは、それを支援するスクリプトを作成して、アプリケー
ション・プロンプトの形にして、画面で見るマニュアル を用意すると、使いやすくなります。
画面で見るマニュアルから、専用コマンドをコピー&ペーストしたり、ショートカットから
起動することで、次々と魔術(スクリプト)を繰り出す速記原典(ショートハンド)のように、
次々と処理を発動させることができるようになります。
使いやすさは、CUI や GUI に関わらず、電子マニュアルの構成によって、大きく左右され
ます。 検索可能なユースケース・ベースのハイパーテキストでできたマニュアルを、Snap
Note などで作成するとよいでしょう。
画面で見るマニュアル とのコラボレーション
既存のプログラムを使いやすくする
テンポラリ・フォルダー
ショートハンド・プロンプトの活用
マニュアルを作成するときは、ユーザーがしたいこと(ユースケース)ごとの章と、コマンド
ごとの章(索引)の両方を用意するとよいでしょう。
→ メニューを開くには
参考
メニューから選び、対話的に入力する
メニューに表示されていないコマンドを起動することもできます。
→ メニューから選び、対話的に入力する
→ 画面で見るマニュアル とのコラボレーション
→ シェルからコマンドを実行する
→ 既存のプログラムを使いやすくする
シェルからメニューを表示しないでコマンドを実行する
alias menu='$HOME/bashlib/menu'
起動するコマンドを短縮するには、たとえば、下記のようにエイリアスを作ってください。
~/bashlib/menu SearchFile ~/source "*.txt" ""
menu を起動するコマンドラインに、入力する内容を並べると、メニューを表示しないで、
すぐにコマンドを実行します。
* を含む入力をするときは、" " で囲んでください。
何も入力しない項目には、"" を指定してください。
bashlib の menu
bashlib が提供するサンプル・コマンドを起動するメニューです。
bashlib menu - shorthand prompt
1. ヘルプ(SVG形式)を開く (Google Chrome や Snap Note で見えます) [Help]
2. ファイルを検索する [SearchFile]
3. 新規作成する - bashlib が使えるシェル・スクリプト・ファイル [NewSh]
4. 新規作成する - ショートハンド・プロンプトのメニュー [NewMenu]
5. 圧縮ファイルを解凍する。ファイル名を一覧する [Extract]
6. 拡張子から実行属性を設定/解除する [chmod_x]
7. bashlib の自動テストを実行する [Test]
99. 終了
が表示されます。
ショートハンド・プロンプト
→ メニューを開くには
→ ショートハンド・プロンプトの活用
メニューに表示されていないコマンドを起動することもできます。
メニューを開くと、入力を要求する
サンプル・コマンドのヘルプ
→ SearchFile コマンド
→ NewSh コマンド
→ Extract コマンド
→ chmod_x コマンド
→ NewMenu コマンド
SearchFile
NewMenu
NewSh
Extract
chmod_x
SearchFile コマンド
[ 親: bashlib の menu ]
番号またはコマンド >SearchFile
((( SearchFile_sth_func )))
Enter のみ: /home/user1
検索するフォルダーのパス >~/bashlib
Enter のみ: すべてのファイル
ファイル名のフィルター 例 *.txt >*.txt
Enter のみ: 内容を検索しない
キーワード >
-------------------------------------------------------------------------------
Search in /home/user1/bashlib/*.txt
/home/user1/bashlib/README.txt
/home/user1/bashlib/はじめて使うときは.txt
~/bashlib
*.txt
SearchFile
ファイル名、またはファイルの内容を指定して、ファイルを検索します。
内部で、Linux の find コマンドと grep コマンドを使っています。
テスト
→ T_Menu.sh # [T_SearchFile_func]
NewSh コマンド
[ 親: bashlib の menu ]
bashlib が使えるシェル・スクリプト・ファイルを新規作成します。
テスト
→ T_Menu.sh # [T_NewSh_func]
→ T_UI_Manually.sh # [T_NewShFolder_func]
番号またはコマンド >NewSh
((( NewSh_sth_func )))
Enterのみ:カレントの a.sh
新しいファイルのパス >
/home/user1/a.sh を作成しました。
/home/user1/scriptlib フォルダーを作成しました。
NewSh
scriptlib フォルダー
が参照できる場所でなければ、scriptlib フォルダーも作成して
すぐに実行できる状況にします。
NewMenu コマンド
が起動するシェル・スクリプト・ファイルを
テスト
番号またはコマンド >NewMenu
((( NewMenu_sth_func )))
Enterのみ:カレントの a.sh
新しいファイルのパス >
/home/user1/a.sh を作成しました。
/home/user1/scriptlib フォルダーを作成しました。
NewMenu
scriptlib フォルダー
が参照できる場所でなければ、scriptlib フォルダーも作成して
すぐに実行できる状況にします。
[ 親: bashlib の menu ]
メニュー(ショートハンド・プロンプト)
新規作成します。
→ T_UI_Manually.sh # [T_NewMenuFolder_func]
Extract コマンド
[ 親: bashlib の menu ]
番号またはコマンド >Extract
((( Extract_sth_func )))
圧縮ファイルのパス >~/sample.tar.bz2
Enterのみ: ファイル名を一覧する
[Ctrl]+[C] : 中断
解凍先フォルダーのパス >~/sample
圧縮ファイル(*.tar.bz2, *.tar.gz, *.zip) の中のファイルを一覧して展開します。
テスト
→ T_Menu.sh # [T_Extract_sth_func]
関連
→ Extract_func
Extract
~/sample.tar.bz2
~/sample
chmod_x コマンド
[ 親: bashlib の menu ]
番号またはコマンド >chmod_x
((( chmod_x_sth_func )))
Enterのみ:/home/user1/bashlib/test
処理を行うフォルダーのパス >
Enterのみ:*.sh
実行属性を設定するファイル("."=設定しない, CSV形式)>
Enterのみ:*.txt, *.html, *.svg
実行属性を解除するファイル("."=解除しない, CSV形式)>
複数のファイルの実行属性をまとめて設定または解除します。
chmod_x
テスト
→ T_Menu.sh # [T_chmod_x_func]
関連
→ chmod_x_func
ユーザーインターフェース
EchoOn_func
EchoOff_func
Pause_func
Input_func
実行するコマンドを表示しながら実行します。
EchoOn_func で表示するモードを、元に戻します。
シェルにメッセージを表示して、Enter キーを押すまで待ちます。
シェルにメッセージを表示して、ユーザーに入力を求めます。
echo_line_func
echo_e_func
ColorText_func
SetAutoInputFromMainArg_func
InputPath_func
InputCommand_func
水平線を表示します。
エスケープがあるテキストを表示します。 echo -e と同じです。
テキストに色を付ける。
キーボードを自動入力します。
ショートハンド・プロンプトを開きます。
ユーザーにファイルやフォルダーのパスの入力を求めます。
EchoOn_func
EchoOn_func
実行するコマンドを表示しながら実行します。
呼び出した関数の中のコマンドは表示しません。
EchoOn_func
str="ABC"
str="${str}DEF"
EchoOff_func
サンプル
関連
→ EchoOff_func
→ T_Err_Manually.sh # [T_EchoStep_func]
テスト
EchoOff_func
EchoOff_func
EchoOn_func で表示するモードを、元に戻します。
関連
→ EchoOn_func
→ T_Err_Manually.sh # [T_EchoStep_func]
テスト
echo_line_func
echo_line_func
水平線を表示します。
テスト
→ InputCommand_func
echo_e_func
echo_e_func <Text>
エスケープ(\)があるテキストを表示します。 echo -e と同じです。
【引数】
Text
エスケープがあるテキスト
Linux の echo -e と同じです。
Mac OS X Snow Leopard には、 echo -e が使えませんが echo $'...' が使えます。
echo $'...' は、どちらの OS でも使えますが、Text に変数の参照を含めると eval
を使った複雑な記述が必要になってしまうので、echo_e_func を用意しました。
ColorText_func
を使って色がついたテキストを表示するときに echo_e_func を使います。
テスト
→ T_UI_Manually.sh # [T_ColorText_func]
\n は改行に、\t はタブ文字になります。
ColorText_func
ColorText_func "Pass." "Green" "Bold"
echo_e_func "$g_Ret"
"Red"
"Green"
"Yellow"
"Blue"
"Magenta"
"Cyan"
"White"
"RedBack"
"GreenBack"
"YellowBack"
"BlueBack"
"MagentaBack"
"CyanBack"
"WhiteBack"
"Bold"
+
+
文字の色
背景の色
太字
サンプル
ColorText_func <Text> <Color> ... ; <EscapeText>="$g_Ret"
テキストに色を付けます。
【引数】
Text
色を付けるテキスト
Color ...
色の名前、背景の色、太字かどうかの羅列
テスト
→ T_UI_Manually.sh # [T_ColorText_func]
ColorText_func "ERROR!" "Red" "Bold"
echo_e_func "$g_Ret"
echo_e_func
標準エラー出力にリダイレクトして出力すると、色は付きません。
を付けて、g_Ret を表示すると、色が付きます。
g_Ret
(出力)echo_e_func に渡す色付き文字列
Pass.
ERROR!
Pause_func
Pause_func [--time_out=<Sec>]
シェルにメッセージを表示して、Enter キーを押すまで待ちます。
続行するには Enter キーを押してください . . .
メッセージの内容:
【引数】
Sec
タイムアウトするまでの秒数。 省略時=タイムアウトなし
サンプル
Pause_func
→ T_UI_Manually.sh # [T_Pause_func]
テスト
サンプル
Pause_func --time_out=10
Input_func
Input_func <Prompt> ; <Key>="$g_Ret"
シェルにメッセージを表示して、ユーザーに入力を求めます。
番号を入力してください >
画面の内容:
Input_func "番号を入力してください >" ; num="$g_Ret"
サンプル
【引数】
Prompt
表示する内容
g_Ret
(出力) ユーザが入力した文字列、入力なし=""
→ SetAutoInputFromMainArg_func
関連
キーボードの自動入力
入力を求められている間に、Ctrl+C を押すと、プログラムは中断します。
エラーにもなりません。 構造化例外処理も行われません。
サンプル
Input_func "続けますか[Y/N] >" ; key1="$g_Ret"
if [ "$key1" != "y" -a "$key1" != "Y" ];then echo "中断しました。" ; exit 1 ;fi
Yes か No かの入力
テスト
→ InputCommand_func
SetAutoInputFromMainArg_func
SetAutoInputFromMainArg_func
シェル・スクリプトを起動した時のパラメーターを、キーボードの自動入力に使うようにします。
SetAutoInputFromMainArg_func
Input_func "番号を入力してください >" ; num="$g_Ret"
echo "num=$num"
サンプル
$ ./sample.sh 2
num=2
画面の内容:
テスト
→ T_Menu.sh # [T_InputCommandOpt_func]
InputPath_func
InputPath_func <Prompt> [ <Option> ... ] ; <Path>="$g_Ret"
シェルにメッセージを表示して、ユーザーにファイルやフォルダーのパスの入力を求めます。
【引数】
Prompt
表示する内容
Option
オプション(下記)
(出力) ユーザが入力したパスの絶対パス、入力なし=""
g_Ret
テスト
→ T_UI_Manually.sh # [T_InputPath_func]
相対パスを入力したとき、基準は、
--AllowEnterOnly
--ChkFileExists
--ChkFolderExists
Option 引数
Enter のみの入力を許可する
入力したパスにファイルが無ければ、再度入力する
入力したパスにフォルダーが無ければ、再度入力する
サンプル
InputPath_func "ファイルのパス >" --ChkFileExists ; path="$g_Ret"
g_StartInPath 変数
の値になります。
--ChkNotExists
入力したパスに何かあれば、再度入力する
InputCommand_func
InputCommand_func <self> <Prompt> <Option> <AppKey>
ショートハンド・プロンプトを開いて、コマンドに対応する関数を呼び出します。
【引数】
self
InputCommandOpt クラスのオブジェクトの名前
Option
Main_func の第1引数
プロンプトのガイド文字列
Prompt
if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
declare_AssociativeArrayClass="declare -A"
else
declare_AssociativeArrayClass="declare"
fi
$declare_AssociativeArrayClass g_InputCommandOpt
function Main_func()
{
local AppKey="$2"
local obj="g_InputCommandOpt"
#//=== call InputCommand_func
SetAttr_func $obj Class "InputCommandOpt"
SetAttr_func $obj Lead "bashlib menu - shorthand prompt"
SetAttr_as_AssociativeArrayName_func $obj CommandReplace \
"1" "Help" \
"2" "SearchFile" \
"3" "NewSh" \
"5" "Extract" \
"7" "Test" \
\
"Help" "Help_sth_func" \
"SearchFile" "SearchFile_sth_func" \
"NewSh" "NewSh_sth_func" \
"Extract" "Extract_sth_func" \
"Test" "Test_sth_func" \
SetAttr_as_AssociativeArrayName_func $obj MenuCaption \
"1" "ヘルプ(SVG形式)を開く (Google Chrome や Snap Note で見えます) [Help]" \
"2" "ファイルを検索する [SearchFile]" \
"3" "新規作成する - bashlib が使えるシェル・スクリプト・ファイル [NewSh]" \
"5" "圧縮ファイルを解凍する。ファイル名を一覧する [Extract]" \
"7" "bashlib の自動テストを実行する [Test]" \
InputCommand_func $obj "" "$1" "$AppKey"
}
サンプル
AppKey
Main_func の第2引数
InputCommandOpt クラス
string
.Lead
.CommandReplace
AssociativeArray
AssociativeArray
.MenuCaption
リード文
コマンド名→関数名の連想配列
コマンド名→メニュー項目の表示内容の連想配列
テスト
→ T_UI_Manually.sh # [T_InputCommand_func]
メニュー項目の番号、コマンド名、関数名を入力できます。
シェルのコマンドも入力できます。
→ T_Menu.sh # [T_InputCommandOpt_func]
関連
→ ArrayClass.remove_method
パラメーターをシフトします。
InputOption_func
InputOption_func <in_out_OptionName> [...] [--comment="<CommentCSV>"]
長い名前のオプションの設定値をユーザーに求めるモードに入ります。
【引数】
in_out_OptionName
オプション名と同じ名前の変数名
サンプル
InputOption_func word message --comment="ワーク, メッセージ"
画面の例:
現在の設定:
--work="/home/user1" ワーク
--message="temporary" メッセージ
Enterのみ、または . :設定完了
オプションを入力してください(例:--work="abc"、--flag)>
テスト
→ T_UI_Manually.sh # [T_InputOption_func]
→ T_Menu.sh # [T_InputOptionAuto_func]
CommentCSV
コメント、CSV 形式
--flag のように値を指定しなかったときは、値が 1 になります。
--flag のようなオプションを取り消したいときは、値を "" か "0" にしてください。
ファイル操作
AppKeyClass.newWritable_method
CheckWritable_func
mkdir_func
mkdir_for_it_func
rm_func
sudo_func
MakeSymbolicLink_func
readlink_func
chown_it_and_parent_func
Extract_func
ListUpIn_func
ExpandWildcard_func
ReplaceTextFile_func
ReplaceTextFileLineRange_func
GetAbsPath_func
GetParentAbsPath_func
SearchParent_func
書き込み可能なパスを設定します。
指定したパスが書き込み可能でなければ、エラーにします。
指定したフォルダーを作成します。
指定したファイルを格納するフォルダーを作成します。
指定したファイルまたはフォルダーを削除します。
指定した関数を呼び出し、root ユーザーで実行します。
指定したパスと、その親フォルダーの所有者を変更します。
シンボリック・リンクを作成します。
リンクを含まない絶対パスに変換します。
圧縮ファイルを解凍します。
圧縮ファイルに入っているファイルのパスを一覧表示します。
ワイルドカードを展開して、パスを一覧します。
ファイルの内容を置き換えます。
複数行のテキストを置き換えます。
相対パスを絶対パスにします。
親フォルダーの絶対パスを返します。
親フォルダーの方向にファイルを探します。
AppKeyClass.newWritable_method
重要なファイルを誤って消したり上書きすることを防ぎます。
スクリプトを実行する場合、ヒューマン・エラーによって予想と異なる処理をしてしま
うことがあるため、sudo を使った本人確認によるOSの保護だけでは不十分です。
サンプル
function Main_func()
{
local AppKey="$2" ; AppKeyClass.newWritable_method "$AppKey" "$PWD"
}
function Main_func()
{
local AppKey="$2" ; AppKeyClass.newWritable_method "$AppKey" "sub1" "sub2"
}
サンプル
複数指定
CheckWritable_func 関数
を使って、書き込み可能なパスかどうかをチェックできます。
rm_func 関数
など、bashlib が提供している、ファイルにライトする関数を使うときは、
AppKeyClass.newWritable_method を呼び出す必要があります。
AppKeyClass.newWritable_method <AppKey> <Path> ...
書き込み可能なパスを設定します。
【引数】
AppKey
Main_func 関数の第2引数
Path ...
書き込み可能なパスの羅列。サブ・フォルダーも書き込み可能
テスト
→ T_File.sh # [T_Writable_func]
関連
→ AppKeyClass.enableInstall_method
CheckWritable_func
CheckWritable_func <Path>
指定したパスが書き込み可能でなければ、エラーにします。
【引数】
Path
ファイルまたはフォルダーのパス
サンプル
CheckWritable_func "sub/a.txt"
テスト
→ T_File.sh # [T_Writable_func]
mkdir_func
mkdir_func <FolderPath>
指定したフォルダーを作成します。 すでに存在していてもエラーになりません。
【引数】
FolderPath
作成するフォルダーのパス
サンプル
mkdir_func "sub"
テスト
→ T_File.sh # [T_mkdir_func]
mkdir_for_it_func
mkdir_for_it_func <FilePath>
指定したファイルを格納するフォルダーを作成します。
【引数】
FilePath
ファイル・パス
サンプル
mkdir_for_it_func "sub/a.txt" #// sub フォルダーを作成します。
テスト
→ T_File.sh # [T_mkdir_func]
rm_func
rm_func <Path> ...
指定したファイルまたはフォルダーを削除します。
【引数】
Path ...
ファイルまたはフォルダーのパスの羅列
書き込み禁止であっても、削除します。
空文字を指定したときは、何もしません。
一時的に root ユーザーになって削除する
サンプル
local AppKey="$2" ; AppKeyClass.newWritable_method "$AppKey" "$PWD"
rm_func "a.txt"
sudo_func rm_func "a.txt"
サンプル
→ T_File.sh # [T_rm_func]
テスト
sudo_func
に対応しています。
sudo_func
sudo_func ...
指定した関数を呼び出し、その中で実行するシェル・コマンドを root ユーザーで実行します。
【引数】
...
sudo_func に対応した関数と、パラメーター
呼び出す関数が、g_TemporarySudo 変数(下記)に対応している必要があります。
g_TemporarySudo 変数
サンプル
sudo_func rm_func "a.txt"
sudo_func を経由して呼び出した関数では、g_TemporarySudo="sudo" に、
そうではないときは、g_TemporarySudo="" になります。
function rm_func()
{
local Path="$1"
$g_TemporarySudo rm -r "$Path"
}
関数定義サンプル
テスト
→ T_File_Manually.sh # [T_Sudo_func]
chown_it_and_parent_func
chown_it_and_parent_func [<Option>] <Owner> <Path>
指定したパスと、その親フォルダーの所有者を変更します。
上記サンプルは、chown_it_and_parent_func を呼び出して、ファイルや
フォルダーの作成やすでにあるファイルの修正を行うことができるようにして、
修正が終わったら、所有者を(元の)root に戻しています。
Path にファイルまたはフォルダーが存在するときは、そのファイルまたはフォ
ルダーの所有者を Owner 引数に指定したユーザーに変更します。
存在しないときは、Path の位置に何かを作ることはしません。
Path の親フォルダーが存在しないときは、Owner 引数に指定したユーザーを
所有者としたフォルダーを作成します。
【引数】
Option
-R オプション(サブ・フォルダーにも適用)、または省略
Owner
新しい所有者:所有グループ
Path
ファイルまたはフォルダーのパス
→ chown
参考
サンプル
sudo_func chown_it_and_parent_func $USER:$USER "sub/sub2/file.txt"
echo "text" > "sub/sub2/file.txt"
sudo_func chown_it_and_parent_func root:root "sub/sub2/file.txt"
Owner に指定したユーザーが自分であれば、Path に指定したファイルが存在
していても存在していなくても、Path にファイルの内容をライトできるように
なります。
→ T_File.sh # [T_chown_it_and_parent_func]
テスト
chmod_x_func
chmod_x_func <FolderPath> <SetCsv> <UnsetCsv>
フォルダーの中のファイルの実行属性を設定、および、設定解除します。
【引数】
FolderPath
処理を行うフォルダー
SetCsv
実行属性を設定するファイル名(ワイルドカード)
UnsetCsv
実行属性を設定解除するファイル名(ワイルドカード)
サンプル
chmod_x_func "." "*.sh" "*.txt, *.log, *.html, *.svg"
テスト
→ T_Menu.sh # [T_chmod_x_func]
FolderPath に指定したフォルダーのサブ・フォルダーにあるファイルも処理対象
になります。
→ chmod_x コマンド
関連
MakeSymbolicLink_func
MakeSymbolicLink_func <LinkSrcPath> <Target>
シンボリック・リンクを作成します。
【引数】
Target
リンク先。 相対パスなら基準はLinkSrcPath が入ったフォルダー
LinkSrcPath
シンボリック・リンクのリンク元のパス
→ ln
参考
CheckWritable_func
によるチェックがあります。
サンプル
MakeSymbolicLink_func "library.so" "library.so.1.0.0"
LinkSrcPath にリンク元がすでに存在していても上書きします。
上書きするリンク元がフォルダーをリンクしていても、そのリンク元を上書きします。
ln コマンドと、引数の順番が逆なので注意してください。
ただし、cp の方向や、ls -l で表示されるリンクの方向と同じです。
→ T_File.sh # [T_MakeSymbolicLink_func]
テスト
readlink_func
readlink_func <Path> ; <PhysicalPath>="$g_Ret"
シンボリック・リンクを含むパスから、リンクを含まない絶対パスに変換します。
【引数】
Path
パス
g_Ret
(出力)シンボリック・リンクを含まない Path。物理パスの絶対パス
サンプル
readlink_func "folder_link/file" #// folder_link -> folder
Assert_func '"$g_Ret" == "/home/user1/folder/file"'
→ T_File.sh # [T_MakeSymbolicLink_func]
テスト
Extract_func
Extract_func <PackagePath> <DstFolder> [--transform_from="<From>"]
圧縮ファイルを解凍します。
【引数】
PackagePath
圧縮ファイルのパス(*.tar.bz2, *.tar.gz, *.zip)
DstFolder
解凍してできるフォルダーのパス
→ T_File.sh # [T_Extract_func]
テスト
→ T_File.sh # [T_ExtractGZ_func]
フォルダーを圧縮したファイルを解凍するとき、DstFolder 引数のフォルダーの中にフォルダー
ができるのではなく、DstFolder に圧縮前の内容が解凍されます。
このとき、元のフォルダー名と違う名前に解凍することもできます。
tar cvjf pack.tar.bz2 pack
rm -r pack
Extract_func "pack.tar.bz2" "pack" #// tar xvf pack.tar.bz2 -C "." と同じ
Extract_func "pack.tar.bz2" "pack2" #// 改名することも可能
圧縮したときのフォルダー名を探すために、Extract_func の内部では、ファイルの一覧を
取得しています。 Linux では、ファイルの一覧を取得するのに、解凍するときと同じ時間が、
かかってしまうため、 tar コマンドを使って直接解凍するより Extract_func を実行する
時間は、2倍の時間がかかります。
tar コマンドと同じ時間に短縮するには、--transform_from オプションを使って、圧縮した
ときのフォルダー名を指定してください。 圧縮時にフォルダー名の前に ./ を付けたときは、
--transform_from オプションにも同様に ./ を付けてください。
From
圧縮したときのフォルダーのパス。省略時=自動判定
tar cvjf pack.tar.bz2 pack
rm -r pack
Extract_func "pack.tar.bz2" "pack" --transform_from="pack"
tar cvjf pack.tar.bz2 ./pack
rm -r pack
Extract_func "pack.tar.bz2" "pack" --transform_from="./pack"
ListUpIn_func
ListUpIn_func <PackagePath>
圧縮ファイルの中に入っているファイルのパスを一覧表示します。
【引数】
PackagePath
圧縮ファイルのパス(*.tar.bz2, *.tar.gz, *.zip)
→ T_File.sh # [T_Extract_func]
テスト
サンプル
ListUpIn_func "sample.tar.bz2"
ExpandWildcard_func
→ T_File.sh # [T_ExpandWildcard_func]
ExpandWildcard_func <WildcardPath> <out_FolderAbsPath> <out_StepPaths> [<Options> ...]
ワイルドカードを展開して、パスを一覧します。
【引数】
WildcardPath
out_FolderAbsPath
ワイルドカード (*) を含むパス
(出力) 基準フォルダーの絶対パス
(出力) 相対パスの配列
out_StepPaths
Options ...
オプション(下記)
Options 引数
--File
--Folder
--SubFolder
テスト
ファイルを一覧する
フォルダーを一覧する
--Link
シンボリック・リンクを一覧する
サブ・フォルダーも含めて一覧する
--File、--Folder、--Link は、同時に複数指定できます。
--File、--Folder、--Link の1つも指定しないときは、--File、--Folder、--Link のすべてを
指定したときと同じになります。
サンプル
local folder
local step_paths
local path
ExpandWildcard_func "T_*" folder step_paths --File --SubFolder #//[out] folder, step_paths
for path in "${step_paths[@]}" ;do
echo "$folder/$path"
done ; done_func $?
ReplaceTextFile_func
ReplaceTextFile_func <Path> <FromText> <ToText> [<Option>]
テキスト・ファイルの内容を置き換えます。
【引数】
Path
内容を置き換えるファイルのパス
置き換える前の文字列。sed の正規表現。改行は\n
FromText
サンプル
MultiLine_func "\n" \
"def" \
"ghi"
from="$g_Ret"
MultiLine_func "\n" \
"xx" \
"yy" \
"zz"
to="$g_Ret"
ReplaceTextFile_func "sample.txt" "$from" "$to"
置き換えた後の文字列。改行は\n
ToText
Option
省略時=デフォルト動作。 "-i" FromStr の大文字小文字を区別しない
def
ghi
を
xx
yy
zz
に置き換えます
2行まで
→ T_File.sh # [T_ReplaceTextFile_func]
テスト
ReplaceTextFile_func "sample.txt" "def\nghi" "xx\nyy\nzz"
上記コードは、下記コードと同じです。
Option="-i" は、Mac OS X Snow Leopard では使えません。
→ ReplaceTextFileLineRange_func
行の削除、複数行の置き換え
関連
FromText にマッチする文字列が複数あるときは、そのすべてを置き換えます。
MultiLine_func
参考
→ sed
→ StringEscapeUtilsClass.escapeSed_method
正規表現をエスケープする
サンプル
ReplaceTextFile_func "sample.txt" "value=0" "value=1"
value=0 を value=1 に置き換えます。
複数行を置き換えます。
サンプル
ReplaceTextFile_func "sample.h" '^.*SymbolA.*$' ""
に置き換えます
abc
abc
を
abc
#define SymbolA 1
abc
正規表現を使った行の置き換え
ReplaceTextFileLineRange_func
ReplaceTextFileLineRange_func <Path> <StartOfFromText> <EndOfFromText> <ToText> [<Option>]
テキスト・ファイルの中の複数行のテキストを置き換えます。
【引数】
Path
内容を置き換えるファイルのパス
置き換える前の先頭行の一部にマッチする sed の正規表現
StartOfFromText
置き換えた後の文字列。 ""=行を削除する
ToText
Option
省略時=デフォルト動作。
"-i" = 置き換える前の大文字小文字を区別しない
置き換える前の最終行の(同上)。 ""= 1行のみ置き換える
EndOfFromText
→ T_File.sh # [T_ReplaceTextFileLineRange_func]
テスト
サンプル
MultiLine_func "\n" \
"x" \
"y"
local a1="$g_Ret"
ReplaceTextFileLineRange_func "_tmp.txt" "c" "f" "$a1"
abc
cde
efg
ghi
なら
x
y
ghi
に置き換わります
関連
→ MultiLine_func
複数行の文字列を作ります
置き換えた後の複数行の改行文字は、"\n" を指定してください。
最終行の末尾に改行文字は付けないでください。
置き換える前の複数行を削除するときは、ToText="" を指定してください。
置き換えた後を1行分の空行にするときは、ToText="\n" を指定してください。
Option="-i" は、Mac OS X Snow Leopard では使えません。
に置き換わります
abc
ghi
なら
abc
cde
ghi
efg
サンプル
ReplaceTextFileLineRange_func "_tmp.txt" "e" "" ""
1行ずつ削除する
参考
→ sed
→ StringEscapeUtilsClass.escapeSed_method
正規表現をエスケープする
GetAbsPath_func
GetAbsPath_func <StepPath> [<BasePath>] ; <AbsPath>="$g_Ret"
相対パスを絶対パスにします。
【引数】
StepPath
相対パス
BasePath
基準パス、省略時=カレント・フォルダー
g_Ret
(出力)絶対パス
サンプル
GetAbsPath_func "a.txt"
Assert_func '"$g_Ret" == "/home/user1/a.txt"'
→ T_File.sh # [T_GetAbsPath_func]
テスト
サンプル
GetAbsPath_func "a.txt" "/home/user1/sub"
Assert_func '"$g_Ret" == "/home/user1/sub/a.txt"'
関連
→ readlink_func
リンクを含まない絶対パスに変換します。
GetParentAbsPath_func
GetParentAbsPath_func <Path> ; <ParentPath>="$g_Ret"
親フォルダーの絶対パスを返します。
【引数】
Path
任意のパス
(出力)Path 引数の親フォルダーの絶対パス
g_Ret
サンプル
GetParentAbsPath_func "a.txt"
Assert_func '"$g_Ret" == "$PWD"'
→ T_File.sh # [T_GetParentAbsPath_func]
テスト
関連
→ SearchParent_func
親フォルダーの方向にファイルを探します。
SearchParent_func
SearchParent_func <Path> ; <ParentPath>="$g_Ret"
親フォルダーの方向にファイルを探して見つかった絶対パスを返します。
【引数】
Path
任意のパス
(出力)Path 引数の親フォルダーの絶対パス
g_Ret
サンプル
cd "/home/user1/bashlib/sub/sub"
GetParentAbsPath_func "menu"
Assert_func '"$g_Ret" == "/home/user1/bashlib/menu"'
上記の結果になる状況:
/home/user1/bashlib/sub/sub/menu が無く、
/home/user1/bashlib/sub/menu が無く、
/home/user1/bashlib/menu があるとき
Path="sub/file" のときは、sub フォルダーから親の方向に file を探します。
見つからないときは、g_Ret="" になります。
→ T_File.sh # [T_SearchParent_func]
テスト
関連
→ GetParentAbsPath_func
親フォルダーの絶対パスを返します。
その他
→ AddIfNotExist_func
PATH や INCLUDE を編集する
プロセス制御、関数呼び出し
GetLongOptions_func
CheckArgCount_func
CheckMinArgCount_func
CheckMaxArgCount_func
CheckOutParamIsConflictToLocal_func
CheckEvalParamIsConflictToLocal_func
local_func
SetOutput_func
SetOutputAsArray_func
GetUsableCommands_func
GetUsableApplicationsForMac_func
IsMac_func
IsInstalled_func
InstallIfNot_func
Uninstall_func
長い名前のオプションを連想配列にまとめます。
関数に渡された引数の数が異なるときはエラーにします。
関数に渡された引数の数が少ないときはエラーにします。
関数に渡された引数の数が多いときはエラーにします。
出力変数名がローカル変数名と衝突していたらエラー。
eval する内容がローカル変数名と衝突していたらエラー。
ローカル変数を、まとめて宣言します。
出力変数に値を設定します。
出力変数に配列を設定します。
シェルから使えるコマンドを取得します。
アプリを起動するコマンドを取得します。 Mac OS X 用。
OS が Mac かどうかを返します。
パッケージがインストールされているかどうかを返します。
インストールやアンインストールを許可するかどうか。
インストールされていなければ、インストールします。
アンインストールします。
AppKeyClass.enableInstall_method
GetLongOptions_func
GetLongOptions_func <out_Arguments> <out_OptAssocArray> <AllArguments> ...
長い名前のオプション(GNU形式)を連想配列にまとめます。
【引数】
out_Arguments
(出力) 長い名前のオプション以外の AllArguments
out_OptAssocArray
(出力) 長い名前のオプションの連想配列。 キーは -- をカット
AllArguments, ...
すべての引数(下記)
サンプル
function T_GetLongOptions_func()
{
T_GetLongOptionsSub_func --opt1 arg1 --opt2=a,b --opt3="a b" arg2 arg3
}
function T_GetLongOptionsSub_func()
{
local arguments
$declare_AssociativeArrayClass option
GetLongOptions_func arguments option "$@" #//[out] arguments, option
Assert_func '"${arguments[0]}" == "arg1"'
Assert_func '"${arguments[1]}" == "arg2"'
Assert_func '"${arguments[2]}" == "arg3"'
Assert_func '${#arguments[@]} == 3'
Attr_func option opt1 ; Assert_func '"$g_Ret" == "1"' #// 値の指定が無ければ1
Attr_func option not ; Assert_func '"$g_Ret" == ""' #// オプション指定が無ければ ""
Attr_func option opt2 ; Assert_func '"$g_Ret" == "a,b"'
Attr_func option opt3 ; Assert_func '"$g_Ret" == "a b"'
}
テスト
→ T_Str.sh # [T_GetLongOptions_func]
declare_AssociativeArrayClass
GetLongOptions_func
コマンドラインに指定されたオプションなら "$g_Arguments[@]"
関数に指定されたオプションなら "$@"
AllArguments 引数
--flag
--value="ABC"
out_OptAssocArray 引数に得られる連想配列の要素
連想配列のキーは、"flag"、対応する値は、"1"
(未指定)
連想配列のキーは、"value"、対応する値は、"ABC"
任意のキーに対応する値は、""
Attr_func
Assert_func
--opt1 arg1 --opt2=a,b --opt3="a b" arg2 arg3
opt1
not
opt2
opt3
関連
→ getopts コマンド
短い名前のオプション(POSIX 形式)を取得する
CheckArgCount_func
CheckArgCount_func <Count> <AllArguments>
関数に渡された引数の数が、指定した数と異なるときはエラーにします。
【引数】
Count
要求する引数の数
すべての引数
AllArguments
サンプル
CheckArgCount_func 2 "$@"
テスト
→ T_Str.sh # [T_CheckArgCount_func]
関連
→ CheckMinArgCount_func
→ CheckMaxArgCount_func
CheckMinArgCount_func
CheckMinArgCount_func <MinCount> <AllArguments>
関数に渡された引数の数が、指定した数より少ないときはエラーにします。
【引数】
MinCount
最小の引数の数
すべての引数
AllArguments
サンプル
CheckMinArgCount_func 2 "$@"
テスト
→ T_Str.sh # [T_CheckArgCount_func]
関連
→ CheckArgCount_func
CheckMaxArgCount_func
CheckMaxArgCount_func <MaxCount> <AllArguments>
関数に渡された引数の数が、指定した数より多いときはエラーにします。
【引数】
MaxCount
最大の引数の数
すべての引数
AllArguments
サンプル
CheckMaxArgCount_func 2 "$@"
テスト
→ T_Err.sh # [T_CheckMaxArgCount_func]
→ T_Str.sh # [T_CheckArgCount_func]
関連
→ CheckArgCount_func
CheckOutParamIsConflictToLocal_func
CheckOutParamIsConflictToLocal_func <OutParamName> <LocalNames> ...
出力変数の実体の名前がローカル変数名と衝突していたらエラーにします。
【引数】
OutParamName
出力変数の実体の名前
すべてのローカル変数の名前
LocalNames, ...
function Sample_func()
{
local local_a="aaa"
OutX_func local_a #//[out] local_a
}
function OutX_func()
{
local out_Var="$1"
local local_a
local locals="out_Var local_a locals"
CheckOutParamIsConflictToLocal_func $out_Var $locals
SetOutput_func $out_Var "bbb" #// Sample_func の local_a 変数に格納できない
}
サンプル
CheckOutParamIsConflictToLocal_func
→ local_func
引数とローカル変数を宣言し、出力変数名の衝突をチェックします
関連
→ SetOutput_func
出力変数に設定します
SetOutput_func
テスト
→ T_Err.sh # [T_CheckOutParamIsConflictToLocal_func]
bash では、呼び出し元の関数が使える変数を参照することができます。
呼び出し元の関数のローカル変数も参照することができます。
これを利用すると、引数への出力ができます。
しかし、local を使って宣言したローカル変数と同じ名前の、呼び出し元が使える変数は、
参照することができません。 呼び出し元が指定した出力引数の変数名がローカル変数の名前と
衝突していたら、出力することができません。 CheckOutParamIsConflictToLocal_func は、
それを検出します。
CheckEvalParamIsConflictToLocal_func
CheckEvalParamIsConflictToLocal_func <EvalExpression> <LocalNames> ...
eval に渡す変数名がローカル変数名と衝突していたらエラーにします。
【引数】
EvalExpression
eval に渡す内容
すべてのローカル変数の名前
LocalNames, ...
サンプル
function Sample_func()
{
local local_a="aaa"
EvalX_func 'local_a is $local_a'
}
function EvalX_func()
{
local EvalExpr="$1"
local local_a
local locals="EvalExpr local_a locals"
CheckEvalParamIsConflictToLocal_func $EvalExpr $locals
eval echo "$EvalExpr" #// 衝突しているため Sample_func の "aaa" が参照できない
}
CheckEvalParamIsConflictToLocal_func
eval を内部で呼び出している関数である下記の EvalX_func 関数は、ローカル変数 EvalExpr
と local_a を宣言しており、EvalX_func の内部から Sample_func 関数の local_a 変数を
参照できなくなっているため、Sample_func 関数は、EvalX_func 関数の EvalExpr 引数
(第1引数)に、EvalExpr や local_a という名前の変数名を渡すことはできません。
CheckEvalParamIsConflictToLocal_func 関数は、そのときにエラーにします。
→ CheckOutParamIsConflictToLocal_func
参考
テスト
→ T_Err.sh # [T_CheckEvalParamIsConflictToLocal_func]
→ Watch
local_func
関数の中でのみ使えるローカル変数を、まとめて宣言します。
テスト
→ T_Str.sh # [T_local_func]
… --local の値は、ローカル変数の名前の羅列(CSV形式)
… --arg の値は、引数の名前の羅列(CSV形式)
local a1="$1"
local a2="$2"
local tmp1
local tmp2
上記は下記のコードと同じです。
local_func \
--arg=" a1, a2 " \
--local=" tmp1, tmp2 " \
"$@" ; eval "$g_Ret"
関連
→ CheckOutParamIsConflictToLocal_func
出力引数の名前の衝突チェック
出力引数は、引数の名前の前に (out) を付けてください。
入出力引数は、引数の名前の前に (in_out) を付けてください。
出力引数や入出力引数の名前の衝突があれば、エラーにします。
local_func \
--arg=" (in_out)a1, (out)a2 " \
--local=" tmp1, tmp2 " \
"$@" ; eval "$g_Ret"
変数が多いときは、改行することができます。
これは、" " で囲まれた文字列を途中で改行することができる bash の仕様です。
local_func \
--local=" tmp1, tmp2
tmp3 " \
"$@" ; eval "$g_Ret"
local_func [--arg="<Argument> [, ...]" ] [--local="<Local> [, ...]" ] <AllArguments>
<Code>="$g_Ret"
【引数】
Argument, ...
引数の変数名の羅列
引数の変数の名前の羅列
Local, ...
AllArguments
"$@" を指定してください
g_Ret
(出力)変数宣言を行うソースコード
サンプル
SetOutput_func
SetOutput_func <out_Var> <Value>
指定した変数名の、出力変数に値を設定します。
【引数】
out_Var
(出力)変数 (=変数名を入力)
変数に設定する値
Value
サンプル
function Caller_func()
{
local tmp
Called_func tmp #//[out] tmp : 出力を格納する変数 $不要
echo $tmp #// "output"
}
function Called_func()
{
local out="$1"
CheckEvalParamIsConflictToLocal_func "$out" out
SetOutput_func $out "output" #// 出力を格納
}
参考
$out "output"
$不要
Called_func の中でも、呼び出し元の tmp 変数を参照できることを
利用して、tmp 変数に値を設定しています。
→ 引数に出力する (bash)
CheckEvalParamIsConflictToLocal_func
→ echo 出力を取得する関数の中のグローバル変数の変更
関連
→ SetOutputAsArray_func
出力変数に配列を設定します。
→ CheckOutParamIsConflictToLocal_func
出力引数の名前の衝突チェック
呼び出し側が echo 出力を取得する関数呼び出し(` ` や $( ) )をした場合、
出力することはできません。
テスト
→ T_Err.sh # [T_CheckOutParamIsConflictToLocal_func]
SetOutputAsArray_func
SetOutputAsArray_func <out_Var> <Value> ...
指定した変数名の、出力変数に配列を設定します。
【引数】
out_Var
(出力)変数 (=変数名を入力)
配列である出力変数の全ての要素
Value ...
→ SetOutput_func
参考
サンプル
SetOutputAsArray_func "$out" "A" "B" "C"
out="var" のとき、var=( "A" "B" "C" ) と同じです。
出力変数に値を設定します。
テスト
→ T_Str.sh # [T_SetOutputAsArray_func]
呼び出し側が echo 出力を取得する関数呼び出し(` ` や $( ) )をした場合、
出力することはできません。
GetUsableCommands_func
GetUsableCommands_func <out_FoundCommands> <CommandCandidates>
指定した候補の中から、シェルから使えるコマンドを取得します。
【引数】
out_FoundCommands
(出力) 使えるコマンドの配列
サンプル
→ T_File.sh # [T_GetUsableCommands_func]
テスト
CommandCandidates
使うコマンドの候補の羅列
local apps
local commands
apps=( "ls" "not-found" "cp" )
GetUsableCommands_func commands "${apps[@]}" #//[out] commands
Assert_func '"${#commands[@]}" == "2"'
Assert_func '"${commands[0]}" == "ls "'
Assert_func '"${commands[1]}" == "cp "'
GetUsableApplicationsForMac_func
GetUsableApplicationsForMac_func <out_FoundCommands> <Applications>
インストールされているアプリケーションを起動するコマンドを取得します。 Mac OS X 用。
【引数】
out_FoundCommands
Applications
(出力) インストールされているアプリの起動コマンドの配列
調べるアプリケーション名の羅列
local apps=( "Google Chrome" "Safari" )
GetUsableApplicationsForMac_func cmds "$apps[@]"
Assert_func "${cmds[0]}" == "open -a \"Safari\" "
サンプル
→ MacWiki - コマンド-open (Web)
参考
→ T_File.sh # [T_GetUsableApplicationsForMac_func]
テスト
IsMac_func
if IsMac_func ;then
OS が Mac かどうかを返します。
【引数】
(出力)Mac=1、Mac以外=0
g_Ret
サンプル
IsMac_func ; if [ "$g_Ret" == "1" ];then
echo "Mac"
else
echo "not Mac"
fi
テスト
→ T_File_Manually.sh # [T_Install_func]
Mac なら、InstallIfNot_func が使えないという表示がされます。
IsInstalled_func
IsInstalled_func <PackageSymbol> ; <Is>="$g_Ret"
パッケージがインストールされているかどうかを返します。
【引数】
PackageSymbol
Debian パッケージのシンボル名
→ T_File_Manually.sh # [T_Install_func]
テスト
IsInstalled_func "lha-sjis"
echo "$g_Ret"
サンプル
g_Ret
(出力)インストールされている=1、いない=0
apt-get が使えないとエラーになります。 Mac ではエラーになります。
AppKeyClass.enableInstall_method
AppKeyClass.enableInstall_method <AppKey>
インストールやアンインストールを許可する。
関連
→ InstallIfNot_func
→ Uninstall_func
→ T_File_Manually.sh # [T_Install_func]
テスト
→ AppKeyClass.newWritable_method
【引数】
AppKey
Main_func 関数の第2引数
サンプル
function Main_func()
{
local AppKey="$2" ; AppKeyClass.enableInstall_method "$AppKey"
}
InstallIfNot_func
InstallIfNot_func <PackageSymbol>
もし、パッケージがインストールされていなければ、インストールします。
【引数】
PackageSymbol
Debian パッケージのシンボル名
テスト
function Main_func()
{
local AppKey="$2" ; AppKeyClass.enableInstall_method "$AppKey"
Sub_func
}
function Sub_func()
{
sudo_func InstallIfNot_func "lha-sjis"
}
サンプル
→ T_File_Manually.sh # [T_Install_func]
apt-get が使えないとエラーになります。 Mac ではエラーになります。
AppKeyClass.enableInstall_method
を呼び出してから使えます。
Uninstall_func
Uninstall_func <PackageSymbol>
パッケージをアンインストールします。
【引数】
PackageSymbol
Debian パッケージのシンボル名
テスト
function Main_func()
{
local AppKey="$2" ; AppKeyClass.enableInstall_method "$AppKey"
Sub_func
}
function Sub_func()
{
sudo_func Uninstall_func "lha-sjis"
}
サンプル
→ T_File_Manually.sh # [T_Install_func]
apt-get が使えないとエラーになります。 Mac ではエラーになります。
AppKeyClass.enableInstall_method
を呼び出してから使えます。
その他
SetOutput_func
指定した変数名の出力変数に値を設定します。
AddIfNotExist_func
PATH などの変数に定義されていなければ追加します。
→ 終了ステータスの取得は、|| を使う
テスト支援
Assert_func
EchoTestStart_func
指定した条件を満たさなかったときは、エラーにします。
テスト・シンボルを表示します。
Assert_func
Assert_func <Condition>
指定した条件を満たさなかったときは、エラーにします。
【引数】
Condition
条件式。 ' ' で囲むこと。 if などの [ ] の中
サンプル
var1="abc"
Assert_func '"$var1" == "def"'
<ERROR msg="Assert failed"><Expression><![CDATA[
"$var1" == "def"
]]></Expression><Result><![CDATA[
abc == def
]]></Result></ERROR>
表示例:
注意
条件式に、引数参照に相当する $1, $2, $3, … を指定すると、正しく判定できません。
補足
' ' の中に変数の参照や、関数の呼び出しがある場合、Assert_func 関数の中から
参照や呼び出しが行われます。 Assert_func 関数を呼び出している関数のローカル
変数は、Assert_func 関数の中からも参照することができるため、正常に動作します。
Assert '"$2" == ""'
BAD
サンプル
Assert_func '-e "$path"'
ファイルか何かがあること
EchoTestStart_func
EchoTestStart_func <TestName>
テスト・シンボルを表示します。
【引数】
TestName
テスト・シンボル
サンプル
EchoTestStart_func "${FUNCNAME[0]}"
((( Main_func )))
表示例:
その他
→ CheckArgCount_func
→ CheckOutParamIsConflictToLocal_func
文字列
→ String (Java Platform SE 6) (Web)
参考
LF, Tab
AddIfNotExist_func
IsNumeric_func
StringClass.length_method
StringClass.substring_method
StringClass.trim_method
StringClass.right_method
StringClass.cutLastOf_method
LeftOfStr_func
LeftOfLastStr_func
RightOfStr_func
RightOfLastStr_func
StringClass.indexOf_method
StringClass.lastIndexOf_method
StringClass.replace_method
StringClass.toLowerCase_method
StringClass.toUpperCase_method
StringEscapeUtilsClass.escapeGrep_method
StringEscapeUtilsClass.escapeSed_method
StringEscapeUtilsClass.escapeBashDoubleQuot_method
StringEscapeUtilsClass.escapeBashParam_method
StringEscapeUtilsClass.escapeBashReplace_method
MultiLine_func
改行文字、タブ文字
文字列が含まれていなければ、追加したものを返します。
文字列の中から指定の文字列を後ろから検索します。
数値かどうかを返します。
文字列の長さを返します。
文字列の一部を抽出します。
両端の空白、タブ、改行をカットした文字列を返します。
文字列の末尾から数文字抽出します。
文字列の末尾が指定した文字ならカットします。
指定したキーワードより左側の部分文字列を返します。
最後のキーワードより左側の部分文字列を返します。
指定したキーワードより右側の部分文字列を返します。
最後のキーワードより右側の部分文字列を返します。
文字列の中から指定の文字列を検索します。
指定した文字列を置き換えます。
指定した文字列を小文字にして返します。
指定した文字列を大文字にして返します。
grep 用にエスケープします。
sed 用にエスケープします。
変数置換用にエスケープします。
" " で囲む用にエスケープします。
" " や ' ' で囲まないエスケープをします。
複数の文字列を複数行の文字列にして返します。
LF, Tab
$LF
$Tab
改行文字
タブ文字
var="abc${LF}def${LF}"
WS var
サンプル
AddIfNotExist_func
AddIfNotExist_func <WholeStr> <AddStr> <Separator> ; <NewStr>="$g_Ret"
WholeStr に AddStr が含まれていなければ、先頭に AddStr を追加したものを返します。
【引数】
WholeStr
文字列の列挙
AddStr
追加する文字列
Separator
文字列の列挙を区切る文字列
サンプル
AddIfNotExist_func "A,B,C" "D" "," ; Assert_func '"$g_Ret" == "D,A,B,C"'
AddIfNotExist_func "A,B,C" "A" "," ; Assert_func '"$g_Ret" == "A,B,C"'
(出力)新しい文字列の列挙
g_Ret
AddIfNotExist_func "$PATH" "$HOME/bin" ":" ; PATH="$g_Ret"
→ T_File.sh # [T_AddIfNotExist_func]
テスト
サンプル
コンマで区切られた文字列の列挙に追加する
環境変数 PATH にパスに追加する
IsNumeric_func
IsNumeric_func <Value> ; <Is>="$g_Ret"
指定した値が数値かどうかを返します。
【引数】
Value
文字列または数値
(出力)数値=1、数値以外=0
g_Ret
サンプル
IsNumeric_func $key ; if [ "$g_Ret" == "1" ];then
echo "$key is number"
else
echo "$key is not number"
fi
→ T_Str.sh # [T_IsNumeric_func]
テスト
StringClass.length_method
StringClass.length_method <self> ; <Length>="$g_Ret"
指定した文字列の長さを返します。
【引数】
self
文字列
(出力)文字列の長さ。 日本語の文字も1文字単位
g_Ret
サンプル
StringClass.length_method "ABCD" ; Assert_func "$g_Ret" == "4"
StringClass.length_method "あいう" ; Assert_func "$g_Ret" == "3"
→ T_Str.sh # [T_StringClass_length_func]
テスト
StringClass.substring_method
StringClass.substring_method <self> <StartIndex> <EndIndex> ; <SubString>="$g_Ret"
文字列の一部を抽出します。
【引数】
self
全体の文字列
StartIndex
抽出を開始する文字の位置。先頭=0
EndIndex
抽出を終了する次の文字の位置。省略=最後まで
サンプル
local var="ABCDE"
StringClass.substring_method "$var" 2 ; Assert_func "$g_Ret" = "CDE"
StringClass.substring_method "$var" 2 4 ; Assert_func "$g_Ret" = "CD"
(出力)部分文字列
g_Ret
→ T_Str.sh # [T_StringClass_substring_func]
テスト
StringClass.trim_method
StringClass.trim_method <self> ; <Str>="$g_Ret"
両端の空白、タブ、改行をカットした文字列を返します。
【引数】
self
全体の文字列
g_Ret
(出力)両端の空白、タブ、改行をカットした文字列
サンプル
local var=" ABCDE "
StringClass.trim_method "$var" ; Assert_func "$g_Ret" = "ABCDE"
→ T_Str.sh # [T_StringClass_trim_func]
テスト
StringClass.right_method
StringClass.right_method <String> <Length> ; <PartStr>="$g_Ret"
文字列の末尾から数文字抽出します。
【引数】
String
全体の文字列
Length
抽出する文字数
サンプル
local var="ABCDE"
StringClass.right_method "$var" 3 ; Assert_func "$g_Ret" = "CDE"
(出力)部分文字列
g_Ret
→ T_Str.sh # [T_StringClass_right_func]
テスト
StringClass.cutLastOf_method
StringClass.cutLastOf_method <String> <LastStr> ; <PartStr>="$g_Ret"
文字列の末尾が指定した文字ならカットします。
【引数】
String
全体の文字列
サンプル
local var="folder/"
StringClass.cutLastOf_method "$var" "/" ; Assert_func "$g_Ret" = "folder"
末尾にあればカットする文字列
LastStr
(出力)部分文字列
g_Ret
→ T_Str.sh # [T_StringClass_cutLast_func]
テスト
LeftOfStr_func
LeftOfStr_func <String> <Key> ; <PartStr>="$g_Ret"
指定したキーワードより左側の部分文字列を返します。
【引数】
String
全体の文字列
Key
キーワード
g_Ret
(出力)キーワードより左側の部分文字列
サンプル
LeftOfStr_func "index.html#main" "#" ; Assert_func '"$g_Ret" == "index.html"'
→ T_Str.sh # [T_LeftRightOfStr_func]
テスト
LeftOfLastStr_func
LeftOfLastStr_func <String> <Key> ; <PartStr>="$g_Ret"
指定したキーワードの最後のキーワードより左側の部分文字列を返します。
【引数】
String
全体の文字列
Key
キーワード
g_Ret
(出力)最後のキーワードより左側の部分文字列
サンプル
LeftOfLastStr_func "/folder/sub/index.html" "/" ; Assert_func '"$g_Ret" == "/folder/sub"'
→ T_Str.sh # [T_LeftRightOfStr_func]
テスト
RightOfStr_func
RightOfStr_func <String> <Key> ; <PartStr>="$g_Ret"
指定したキーワードより右側の部分文字列を返します。
【引数】
String
全体の文字列
Key
キーワード
g_Ret
(出力)キーワードより右側の部分文字列
サンプル
RightOfStr_func "folder/sub/index.html" "/" ; Assert_func '"$g_Ret" == "sub/index.html"'
→ T_Str.sh # [T_LeftRightOfStr_func]
テスト
RightOfLastStr_func
RightOfLastStr_func <String> <Key> ; <PartStr>="$g_Ret"
指定したキーワードの最後のキーワードより右側の部分文字列を返します。
【引数】
String
全体の文字列
Key
キーワード
g_Ret
(出力)最後のキーワードより右側の部分文字列
サンプル
RightOfLastStr_func "/folder/sub/index.html" "/" ; Assert_func '"$g_Ret" == "index.html"'
→ T_Str.sh # [T_LeftRightOfStr_func]
テスト
StringClass.indexOf_method
StringClass.indexOf_method <self> <Keyword> <StartIndex> ; <Index>="$g_Ret"
文字列の中から指定の文字列を検索します。
【引数】
self
全体の文字列
Keyword
検索キーワード
StartIndex
検索を開始する文字の位置。省略時=先頭
サンプル
local var="ABCDEABCDE"
StringClass.indexOf_method "$var" "BC" ; Assert_func $g_Ret = 1
StringClass.indexOf_method "$var" "BC" 5 ; Assert_func $g_Ret = 6
StringClass.indexOf_method "$var" "X" ; Assert_func $g_Ret = -1
StringClass.indexOf_method "$var" "X" 5 ; Assert_func $g_Ret = -1
(出力)見つかった位置。先頭=0。見つからなかった=-1
g_Ret
→ T_Str.sh # [T_StringClass_index_func]
テスト
StringClass.lastIndexOf_method
StringClass.indexOf_method <self> <Keyword> <StartIndex> ; <Index>="$g_Ret"
文字列の中から指定の文字列を後ろから検索します。
【引数】
self
全体の文字列
Keyword
検索キーワード
StartIndex
検索を開始する文字の位置。省略時=末尾
サンプル
local var="ABCDEABCDE"
StringClass.lastIndexOf_method "$var" "BC" ; Assert_func '$g_Ret == 6'
StringClass.lastIndexOf_method "$var" "BC" 5 ; Assert_func '$g_Ret == 1'
StringClass.lastIndexOf_method "$var" "X" ; Assert_func '$g_Ret == -1'
StringClass.lastIndexOf_method "$var" "X" 5 ; Assert_func '$g_Ret == -1'
(出力)見つかった位置。先頭=0。見つからなかった=-1
g_Ret
→ T_Str.sh # [T_StringClass_index_func]
テスト
StringClass.replace_method
StringClass.replace_method <self> <From> <To> ; <Str>="$g_Ret"
指定した文字列を置き換えます。
【引数】
self
置き換えられる文字列
置き換える前の部分文字列(正規表現ではない)
From
サンプル
StringClass.replace_method "ABCDE" "C" "xx" ; Assert_func '"$g_Ret" == "ABxxDE"'
g_Ret
(出力)置き換えた後の文字列
置き換えた後の部分文字列
To
From にマッチする部分が無かったときは、g_Ret=$self になります。
→ T_Str.sh # [T_StringClass_replace_func]
テスト
→ T_Speed_Manually.sh # [T_StringReplaceSpeed_func]
StringClass.toLowerCase_method
StringClass.toLowerCase_method <self> ; <LowerStr>="$g_Ret"
指定した文字列を小文字にして返します。
【引数】
self
文字列
(出力)小文字に置き換えた文字列
g_Ret
サンプル
StringClass.toLowerCase_method "ABCDE" ; Assert_func '"$g_Ret" == "abcde"'
→ T_Str.sh # [T_StringClass_toLoHi_func]
テスト
StringClass.toUpperCase_method
StringClass.toUpperCase_method <self> ; <UpperStr>="$g_Ret"
指定した文字列を大文字にして返します。
【引数】
self
文字列
(出力)大文字に置き換えた文字列
g_Ret
サンプル
StringClass.toUpperCase_method "abcde" ; Assert_func '"$g_Ret" == "ABCDE"'
→ T_Str.sh # [T_StringClass_toLoHi_func]
テスト
StringEscapeUtilsClass.escapeGrep_method
StringEscapeUtilsClass.escapeGrep_method <self> ; <EscapedStr>="$g_Ret"
指定した文字列を grep の検索キーワードに使えるようにエスケープします。
【引数】
self
文字列
(出力)エスケープした文字列
g_Ret
サンプル
StringEscapeUtilsClass.escapeGrep_method '[out]' #// $g_Ret == '\[out\]'
grep -r "$g_Ret" *
テスト
→ T_Str.sh # [T_StringEscapeUtilsClass_func]
StringEscapeUtilsClass.escapeSed_method
StringEscapeUtilsClass.escapeSed_method <self> ; <EscapedStr>="$g_Ret"
指定した文字列を sed の置換前に使えるようにエスケープします。
【引数】
self
文字列
(出力)エスケープした文字列
g_Ret
サンプル
StringEscapeUtilsClass.escapeSed_method '[out]' #// $g_Ret == '\[out\]'
sed -e "s/$g_Ret/xxxx/g" a.txt
テスト
→ T_Str.sh # [T_StringEscapeUtilsClass_func]
→ sed
次の関数やコマンドに指定することができます。
→ ReplaceTextFile_func
→ ReplaceTextFileLineRange_func
StringEscapeUtilsClass.escapeBashReplace_method
StringEscapeUtilsClass.escapeBashReplace_method <self> ; <EscapedStr>="$g_Ret"
指定した文字列を変数の内容を置換する前の文字列に使えるようにエスケープします。
【引数】
self
文字列
(出力)エスケープした文字列
g_Ret
サンプル
StringEscapeUtilsClass.escapeBashReplace_method '(out)'
var="${var//$g_Ret/xxxx}" #// $g_Ret == '\(out\)'
テスト
→ T_Str.sh # [T_StringEscapeUtilsClass_func]
StringEscapeUtilsClass.escapeBashDoubleQuot_method
StringEscapeUtilsClass.escapeBashDoubleQuot_method <self> ; <EscapedStr>="$g_Ret"
指定した文字列を " " で囲まれたリテラル文字列に使えるようにエスケープします。
【引数】
self
文字列
(出力)エスケープした文字列
g_Ret
サンプル
#// Search '\*'
StringEscapeUtilsClass.escapeGrep_method '\*' #// $g_Ret == '\\*'
grep -r "$g_Ret" *
StringEscapeUtilsClass.escapeBashDoubleQuot_method "$g_Ret" #// $g_Ret == '\\\\\*'
echo "Write \"$g_Ret\" at grep keyword."
grep -r "\\\\\*" * #// 上の grep と同じ
テスト
→ T_Str.sh # [T_StringEscapeUtilsClass_func]
StringEscapeUtilsClass.escapeBashParam_method
StringEscapeUtilsClass.escapeBashParam_method <self> ; <EscapedStr>="$g_Ret"
指定した文字列を " " や ' ' で囲まないリテラル文字列に使えるようにエスケープします。
【引数】
self
文字列
(出力)エスケープした文字列
g_Ret
サンプル
out="a b.txt"
cp a.txt "$out"
StringEscapeUtilsClass.escapeBashParam_method "$out" #// $g_Ret == 'a\ b.txt'
echo "Write $g_Ret at cp parameter."
cp a.txt a\ b.txt #// 上の cp と同じ
テスト
→ T_Str.sh # [T_StringEscapeUtilsClass_func]
out="a b.txt"
StringEscapeUtilsClass.escapeBashParam_method "$out" #// $g_Ret == 'a\ b.txt'
eval echo '"a"' > "$g_Ret" #// echo "a" > a\ b.txt
サンプル
MultiLine_func
MultiLine_func <LineFeedChar> <Lines> ... ; <String>="$g_Ret"
複数の文字列を複数行の文字列にして返します。
【引数】
LineFeedChar
改行文字
1行の文字列の羅列
Lines ...
サンプル
MultiLine_func "$LF" \
"abc" \
"def" \
"ghi"
Assert_func '"$g_Ret" == "abc${LF}def${LF}ghi"'
(出力)複数行の文字列
g_Ret
最終行の末尾に改行は入りません。
最終行の末尾に改行を入れるときは ` ` の外に "$LF" を記述してください。
サンプル
MultiLine_func "$LF" \
"abc" \
"def" \
"ghi"
Assert_func '"$var$LF" == "abc${LF}def${LF}ghi${LF}"'
最終行の末尾に改行は入りません。
MultiLine_func "\n" \
"abc" \
"def" \
"ghi"
Assert_func '"$g_Ret" == "abc\ndef\nghi"'
サンプル
テスト
→ T_Str.sh # [T_MultiLine_func]
関連
→ ArrayClass.fromLines_method
その他
→ WS
指定した変数の値をダンプします。
→ ArrayClass.fromCSV_method
CSV 形式の文字列を、配列にします。
配列
参考
→ Array (Java Platform SE 6) (Web)
→ ArrayList (Java Platform SE 6) (Web)
ArrayClass.getLength_method
ArrayClass.get_method
ArrayClass.set_method
ArrayClass.remove_method
ArrayClass.clear_method
ArrayClass.fromLines_method
ArrayClass.fromCSV_method
IsSameArrayOutOfOrder_func
配列の要素数を返します。
配列の要素を返します。
配列の要素を設定します。
配列の要素を1つ削除して、後にある要素は前に詰めます。
配列の要素をすべて削除します。
複数行の文字列を1行ずつの配列にします。
CSV 形式の文字列を、配列にします。
配列の要素が同じかどうかを返します。
ArrayClass.getLength_method
ArrayClass.getLength_method <self> ; <Length>="$g_Ret"
配列の要素数を返します。
【引数】
self
配列変数の名前
g_Ret
(出力)配列の要素数
テスト
→ T_Str.sh # [T_ArrayClass_getLength_func]
arr=( "a" "b" "c" )
ArrayClass.getLength_method arr
Assert_func '$g_Ret == 3'
サンプル
${#arr[@]}
補足
bash では、配列の要素数は、下記のように取得できます。
ArrayClass.getLength_method は、配列の名前が変数に入っているときに使うと、
読みやすくなります。
ArrayClass.get_method
ArrayClass.get_method <self> <Index> ; <Element>="$g_Ret"
配列の要素を返します。
【引数】
self
配列変数の名前
Index
配列番号
(出力)配列の要素
g_Ret
arr=( "a b" "c" "d" )
ArrayClass.get_method arr 0
Assert_func '"$g_Ret" == "a b"'
サンプル
テスト
→ T_Str.sh # [T_ArrayClass_get_set_func]
${arr[0]}
補足
bash では、配列の要素は、下記のように取得できます。
ArrayClass.get_method は、配列の名前が変数に入っているときに使うと、
読みやすくなります。
ArrayClass.set_method
ArrayClass.set_method <self> <Index> <Value>
配列の要素を設定します。
【引数】
self
配列変数の名前
Index
配列番号
設定する配列の要素
Value
arr=( "a" "b" "c" )
ArrayClass.set_method arr 1 "xx"
ArrayClass.get_method arr 1
Assert_func '"$g_Ret" == "xx"'
サンプル
テスト
→ T_Str.sh # [T_ArrayClass_get_set_func]
arr[0]="xx"
補足
bash では、配列の要素は、下記のように設定できます。
ArrayClass.set_method は、配列の名前が変数に入っているときに使うと、
読みやすくなります。
bash では、配列番号 0, 1, 2 の要素があるときに、配列番号 4 の要素を
代入すると、配列番号 0, 1, 2, 4 となり、要素数は 4 になりますが、
ArrayClass.set_method では、配列番号 3 に空文字が入り、要素数は 5
になります。
ArrayClass.remove_method
ArrayClass.remove_method <self> <Index>
配列の要素を1つ削除して、後にある要素は前に詰めます。
【引数】
self
配列変数の名前
Index
削除する要素の配列番号(0以上)
unset arr[0]
補足
bash では、配列の要素は、下記のように削除できます。
ただし、後にある要素は前に詰められません。
arr=( "a" "b" "c" )
ArrayClass.remove_method arr 1
Assert_func '"${arr[0]}" == "a"'
Assert_func '"${arr[1]}" == "c"'
サンプル
テスト
→ T_Str.sh # [T_ArrayClass_remove_func]
サンプル
ArrayClass.remove_method g_Arguments 1
コマンドラインの第1パラメーターを削除します。
g_Arguments
ArrayClass.clear_method
ArrayClass.clear_method <self>
配列の要素をすべて削除します。
【引数】
self
配列変数の名前
arr=( "a" "b" "c" )
ArrayClass.clear_method arr
サンプル
テスト
→ T_Str.sh # [T_ArrayClass_clear_func]
ArrayClass.fromLines_method
ArrayClass.fromLines_method <out_Array> <Lines>
複数行の文字列を1行ずつの配列にします。
【引数】
Lines
複数行の文字列。改行は LF(0x0A)
(出力) 配列。 要素は1行
out_Array
関連
→ MultiLine_func
テスト
→ T_Str.sh # [T_ArrayClass_Lines_func]
lines=`ls -1`
ArrayClass.fromLines_method arr "$lines" #//[out] arr
サンプル
ArrayClass.fromCSV_method
ArrayClass.fromCSV_method <out_Array> <CSV>
CSV 形式の文字列を、配列にします。
【引数】
CSV
out_Array
CSV 形式の文字列
(出力) 配列
サンプル
テスト
→ T_Str.sh # [T_ArrayFromCSV_func]
local arr
local csv="ABC, DEF, \"GHI \""
ArrayClass.fromCSV_method arr "$csv" #//[out] arr
Assert_func '"${arr[0]}" == "ABC"'
Assert_func '"${arr[1]}" == "DEF"'
Assert_func '"${arr[2]}" == "GHI "'
IsSameArrayOutOfOrder_func
IsSameArrayOutOfOrder_func <ArrayALength> <ArrayA> <ArrayB> ; <Is>="$g_Ret"
配列の要素が同じかどうかを返します。 要素の順番は違っても同じとします。
【引数】
ArrayA
ArrayALength
配列A
配列Aの要素数
サンプル
テスト
→ T_Str.sh # [T_IsSameArrayOutOfOrder_func]
arr1=( "a" "b" "c" )
arr2=( "b" "c" "a" )
IsSameArrayOutOfOrder_func ${#arr1[@]} "${arr1[@]}" "${arr2[@]}"
if [ "$g_Ret" == "0" ];then Error_func ;fi
ArrayB
g_Ret
配列B
(出力)同じ=1、違う=0
その他
→ CopyArray_func
連想配列、オブジェクト
declare_AssociativeArrayClass
Attr_func
SetAttr_func
AssociativeArrayClass.getLength_method
AssociativeArrayClass.getKeys_method
AssociativeArrayClass.getItems_method
AssociativeArrayClass.destroy_method
CopyArray_func
CopyArrayAttr_func
SetAttr_as_ArrayName_func
SetAttr_as_AssociativeArrayName_func
連想配列の宣言を行います。
連想配列の値を返します。
連想配列の値を、設定します。
連想配列にあるすべてのキーを返します。
連想配列の要素数を返します。
連想配列にあるすべての値を返します。
連想配列を削除します。
配列、または、連想配列をコピーします。
配列型の属性の値を取得します。
配列を生成して連想配列に代入します。
連想配列を生成して別の連想配列に代入します。
bashlib を使ったオブジェクト指向記述法 - bashool
参考
→ bash によるオブジェクト指向 [bashool]
if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
declare_AssociativeArrayClass="declare -A" #// bash ver4
else
declare_AssociativeArrayClass="declare" #// bash ver3
fi
#// global variables as associative arrray
$declare_AssociativeArrayClass g_ObjectA
$declare_AssociativeArrayClass g_ObjectB
g_Objects=( "g_ObjectA" "g_ObjectB" )
function InitObjs_func()
{
local obj
obj=g_ObjectA #// obj=&g_ObjectA
SetAttr_func $obj "Attr1" "Value1" #// obj->Attr1 = "Value1"
SetAttr_func $obj "Attr2" "Value2" #// obj->Attr2 = "Value2"
obj=g_ObjectB #// obj=&g_ObjectB
SetAttr_func $obj "Attr1" "Value1"
SetAttr_func $obj "Attr2" "Value4"
}
function Main_func()
{
InitObjs_func
for obj in ${g_Objects[@]};do
Attr_func $obj "Attr2" #// obj->Attr2
echo "$g_Ret"
done ; done_func $?
}
オブジェクトへのポインター
declare を関数内で実行するとローカル、関数の外で実行するとグローバルになります。
関数の引数には指定できません。 なので、オブジェクトはグローバルにせざるを得ない
でしょう。
→ オブジェクトへのポインター
属性(メンバー変数)
メソッド(メンバー関数)
→ 多態性(ポリモアフィズム)
bashlib を使った多態性(ポリモアフィズム)
if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
declare_AssociativeArrayClass="declare -A" #// bash ver4
else
declare_AssociativeArrayClass="declare" #// bash ver3
fi
#// global variables as associative arrray
$declare_AssociativeArrayClass g_ObjectA
$declare_AssociativeArrayClass g_ObjectB
g_Objects=( "g_ObjectA" "g_ObjectB" )
function InitObjs_func()
{
local obj
obj=g_ObjectA
SetAttr_func $obj "Class" "AClass"
SetAttr_func $obj "Attr1" "Value1"
SetAttr_func $obj "doA_method" "AClass.doA_method"
obj=g_ObjectB
SetAttr_func $obj "Class" "BClass"
SetAttr_func $obj "Attr1" "Value1"
SetAttr_func $obj "doA_method" "BClass.doA_method"
}
function Main_func()
{
local obj
InitObjs_func
for obj in ${g_Objects[@]};do
Attr_func $obj "doA_method" ; $g_Ret $obj
done
}
function AClass.doA_method()
{
local self="$1"
echo "AClass.doA_method( $self )"
}
function BClass.doA_method()
{
local self="$1"
echo "BClass.doA_method( $self )"
}
プロセス内の呼び出しの場合
→ プロセス内の呼び出しの場合
子プロセスを呼び出す場合
→ 子プロセスを呼び出す場合
g_SetupFileNames=( "./Child1.sh" "./Child2.sh" )
function Main_func()
{
local name_sh ; local result
for name_sh in ${g_SetupFileNames[@]};do
$name_sh --FuncA_func --Param1=Value1 --Param2=Value2
done
for name_sh in ${g_SetupFileNames[@]};do
result=`$name_sh --FuncB_func --Param1=Value1`
echo "\$result = $result"
done
}
Main.sh
g_AllArguments="$@"
g_FuncName=${1#--*} #// cut -- from $1
function Main_func()
{
$g_FuncName $g_AllArguments
}
function FuncA_func()
{
echo "FuncA_func in Package1.sh"
}
function FuncB_func()
{
echo "FuncB_func in Package1.sh"
}
Child1.sh
g_AllArguments="$@"
g_FuncName=${1#--*} #// cut -- from $1
function Main_func()
{
$g_FuncName $g_AllArguments
}
function FuncA_func()
{
echo "FuncA_func in Package1.sh"
}
function FuncB_func()
{
echo "FuncB_func in Package1.sh"
}
Child2.sh
関数名は、クラス名+Class+ピリオド+メソッド名_method。
クラス名は、単語の先頭は大文字、後は小文字。(Java準拠)
メソッド名は、先頭の単語はすべて小文字、後の単語は先頭文字のみ大文字。(Java準拠)
メソッドに相当する関数の第1引数は、オブジェクトの名前(=連想配列の名前)。
関数内では、self という変数名にする。
function SampleClass.doSample_method()
{
local self="$1"
サンプル
オブジェクトの名前を、ファイル名、または、第1パラメーターにします。
メソッド名を、関数名と同じ、パラメーターなしのオプションにします。
メソッドのパラメーターを、パラメーターありのオプションにします。
declare_AssociativeArrayClass
連想配列の宣言を行います。
declare -A は、bash ver3 では使えませんが、declare_AssociativeArrayClass は、
bash ver3 と bash ver4 のどちらでも使えます。
サンプル
$declare_AssociativeArrayClass object #// 変数 object を連想配列として宣言する
if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
declare_AssociativeArrayClass="declare -A" #// bash ver4
else
declare_AssociativeArrayClass="declare" #// bash ver3
fi
$declare_AssociativeArrayClass object
サンプル
メイン・スクリプト・ファイルのグローバル変数
declare_AssociativeArrayClass は、メイン・スクリプト・ファイルの末尾にある bashlib
include が行われてから使えますが、その前であるメイン・スクリプト・ファイルの
グローバルに連想配列を宣言するときは、その前に、declare_AssociativeArrayClass の
実装をコピーしてください。
Attr_func
Attr_func <self> <AttrName> ; <Value>="$g_Ret"
連想配列の値(オブジェクトの属性の値)を、返します。
【引数】
self
連想配列の変数名=オブジェクト名
属性名=連想配列のキー
AttrName
サンプル
$declare_AssociativeArrayClass object_a
object_a["Attr1"]="Value1"
Attr_func object_a "Attr1"
echo "$g_Ret"
(出力)属性の値=連想配列の値
g_Ret
4(src)
参考
→ bash によるオブジェクト指向 [bashool]
3(src)
SetAttr_func
SetAttr_func <self> <AttrName> <Value>
連想配列の値(オブジェクトの属性の値)を、設定します。
【引数】
self
連想配列の変数名=オブジェクト名
属性名=連想配列のキー。 英数字から始めること
AttrName
サンプル
$declare_AssociativeArrayClass object_a
local obj
obj="object_a"
SetAttr_func $obj "Attr1" "Value1"
属性の値=連想配列の値
Value
4(src)
参考
→ bash によるオブジェクト指向 [bashool]
bash ver3 では、連想配列の代わりに、bashlib が用意した擬似連想配列を使います。
bash ver4 でも、連想配列の名前を変数に代入した変数から、連想配列の値を参照
するには、SetAttr_func 関数の中で行っている複雑な記述が必要になります。
C言語的に表現すると、構造体のポインターからメンバー変数への代入になります。
obj = &object_a;
obj->Attr1 = "Value1";
サンプル
$declare_AssociativeArrayClass object_a
SetAttr_func object_a "Attr1" "Value1"
C言語的に表現すると、構造体のメンバー変数への代入になります。
object_a.Attr1 = "Value1";
object_a[Attr1]="Value1"
bash ver4 的に表現すると、
→ T_Str.sh # [T_Attr_func]
テスト
→ T_Str.sh # [T_Attr3_func]
サンプル
function Main_func()
{
$declare_AssociativeArrayClass object_a
Sub_func object_a
Attr_func object_a "Attr1" ; echo "$g_Ret"
Attr_func object_a "Attr2" ; echo "$g_Ret"
}
function Sub_func()
{
local AssocArrayName="$1"
SetAttr_func $AssocArrayName "Attr1" "Value 1"
SetAttr_func $AssocArrayName "Attr2" "Value 2"
}
連想配列の名前を代入した変数から、連想配列の値を参照する
関数の中で、連想配列に代入する
→ T_Str.sh # [T_SetAttrInFunc_func]
3(src)
AssociativeArrayClass.getLength_method
AssociativeArrayClass.getLength_method <self> ; <Length>="$g_Ret"
連想配列の要素数を返します。
【引数】
self
連想配列の変数名=オブジェクト名
(出力)要素数
g_Ret
$declare_AssociativeArrayClass assoc_arr
SetAttr_func assoc_arr "Key1" "Value1"
SetAttr_func assoc_arr "Key2" "Value2"
AssociativeArrayClass.getLength_method assoc_arr
echo "Length=$g_Ret"
サンプル
4(src)
3(src)
テスト
→ T_Str.sh # [T_CopyAssociativeArray4_func]
→ T_Str.sh # [T_CopyAssociativeArray3_func]
AssociativeArrayClass.getKeys_method
4(src)
AssociativeArrayClass.getKeys_method <self> ; <Keys>=( $g_Ret )
連想配列にあるすべてのキー(オブジェクトのすべての属性名)を返します。
【引数】
self
連想配列の変数名=オブジェクト名
(出力)すべてのキー(フィールド形式)
g_Ret
$declare_AssociativeArrayClass assoc_arr
SetAttr_func assoc_arr "Key1" "Value1"
SetAttr_func assoc_arr "Key2" "Value2"
AssociativeArrayClass.getKeys_method assoc_arr
local keys=( $g_Ret )
local key
for key in "${keys[@]}" ;do
Attr_func assoc_arr "$key"
echo "$key = $g_Ret"
done ; done_func $?
サンプル
→ T_Str.sh # [T_Attr3_func]
テスト
3(src)
値に空白文字を含む場合、正しく動作しません。
→ T_Str.sh # [T_CopyAssociativeArray4_func]
→ T_Str.sh # [T_CopyAssociativeArray3_func]
AssociativeArrayClass.getItems_method
AssociativeArrayClass.getItems_method <self> ; <Keys>=( $g_Ret )
連想配列にあるすべての値(オブジェクトのすべての属性値)を返します。
【引数】
self
連想配列の変数名=オブジェクト名
(出力)すべてのキー(フィールド形式)
g_Ret
$declare_AssociativeArrayClass assoc_arr
SetAttr_func assoc_arr "Key1" "Value1"
SetAttr_func assoc_arr "Key2" "Value2"
AssociativeArrayClass.getItems_method assoc_arr
local values=( $g_Ret )
サンプル
値に空白文字を含む場合、正しく動作しません。
AssociativeArrayClass.getKeys_method のサンプルのように、キーのループを
使ってください。
4(src)
3(src)
テスト
→ T_Str.sh # [T_CopyAssociativeArray4_func]
→ T_Str.sh # [T_CopyAssociativeArray3_func]
AssociativeArrayClass.destroy_method
4(src)
3(src)
AssociativeArrayClass.destroy_method <self>
連想配列(オブジェクト)を削除します。
【引数】
self
連想配列の変数名=オブジェクト名
$declare_AssociativeArrayClass assoc_arr
SetAttr_func assoc_arr "Key1" "Value1"
SetAttr_func assoc_arr "Key2" "Value2"
AssociativeArrayClass.destroy_method assoc_arr
サンプル
テスト
→ T_Str.sh # [T_CopyAssociativeArray4_func]
→ T_Str.sh # [T_CopyAssociativeArray3_func]
CopyArray_func
4(src)
CopyArray_func <DstArray> <SrcArray>
配列、または、連想配列をコピーします。
【引数】
DstArray
(出力)コピー先の配列変数名
コピー元の配列変数名
SrcArray
$declare_AssociativeArrayClass ObjectA
SetAttr_func ObjectA "Attr1" "Value1"
SetAttr_func ObjectA "Attr2" "Value2"
SetAttr_func ObjectA "Attr3" "Value3"
local arr=ObjectA
$declare_AssociativeArrayClass ObjectB
CopyArray_func ObjectB $arr
サンプル
→ T_Str.sh # [T_CopyArray_func]
テスト
→ T_Str.sh # [T_CopyAssociativeArray4_func]
3(src)
→ T_Str.sh # [T_CopyAssociativeArray3_func]
CopyArrayAttr_func
CopyArrayAttr_func <self> <AttrName> <out_Array>
指定したオブジェクトの、配列型の属性の値を取得します。
【引数】
self
連想配列の変数名=オブジェクト名
属性名=連想配列のキー
AttrName
(出力) 属性の配列のコピー
out_Array
$declare_AssociativeArrayClass obj
local arr
SetAttr_as_ArrayName_func obj "AttrA" "a" "b" "c"
CopyArrayAttr_func obj "AttrA" arr #//[out] arr
Assert_func '"${arr[0]}" = "a"'
Assert_func '"${arr[1]}" = "b"'
Assert_func '"${arr[2]}" = "c"'
サンプル
→ T_Str.sh # [T_CopyArrayAttr_func]
テスト
SetAttr_as_ArrayName_func
SetAttr_as_ArrayName_func <self> <AttrName> <Params> ...
配列を生成して、その配列を、連想配列のアイテムに代入します。
【引数】
self
連想配列の変数名=オブジェクト名
属性名=連想配列のキー
AttrName
生成する配列の要素の並び
Params ...
$declare_AssociativeArrayClass obj
local arr
SetAttr_as_ArrayName_func obj "AttrA" "a" "b" "c"
CopyArrayAttr_func obj "AttrA" arr #//[out] arr
Assert_func '"${arr[0]}" = "a"'
Assert_func '"${arr[1]}" = "b"'
Assert_func '"${arr[2]}" = "c"'
サンプル
→ T_Str.sh # [T_CopyArrayAttr_func]
テスト
SetAttr_as_AssociativeArrayName_func
SetAttr_as_AssociativeArrayName_func <self> <AttrName> <Params> ...
連想配列を生成して、その連想配列を、別の連想配列のアイテムに代入します。
【引数】
self
連想配列の変数名=オブジェクト名
属性名=別の連想配列のキー
AttrName
サンプル
$declare_AssociativeArrayClass object
local obj=object
SetAttr_as_AssociativeArrayName_func $obj "Assoc" \
AttrA "ValueA" \
AttrB "ValueB"
Attr_func $obj "Assoc" ; assoc="$g_Ret"
Attr_func $assoc "AttrA"
Assert_func "$g_Ret" == "ValueA"
Attr_func $assoc "AttrB"
Assert_func "$g_Ret" == "ValueB"
上記のサンプルを、C言語的に表現すると、
obj->Assoc->AttrA = "ValueA";
obj->Assoc->AttrB = "ValueB";
assoc = obj->Assoc;
ASSERT( assoc->AttrA == "ValueA" );
ASSERT( assoc->AttrB == "ValueB" );
Params ...
生成する連想配列のキーと値の並び
→ T_Str.sh # [T_Attr3_func]
テスト
bashlib_inc.sh (bashlib のベース・システム)
bashlib を使うには、メイン・スクリプト・ファイルの末尾に、bashlib をインクルードする
十数行のコードを配置する必要があります。 menu から新規作成
スクリプト・ファイルには、そのコードが含まれています。
scriptlib
main
sample
メイン・スクリプトの末尾にある bashlib include
のコードから、bashlib_inc.sh をインクルードする
bashlib_inc.sh
bashlib.sh
bashlib3.sh
bashlib_inc.sh から、
すべてのライブラリをインクルードする
(NewShなど)
インクルードの構成
メイン・スクリプト・ファイルがあるフォルダーに scriptlib フォルダーがあれば、それを
使いますが、無ければ、親フォルダーの方向に scriptlib を探します。 その動きは
SearchParent_func
と同じです。
Main_func
g_StartInPath
g_Arguments
bashlib を使うスクリプトは、Main_func から内容を記述します。
プロセス起動時のカレント・フォルダーの絶対パス。
プロセスを起動した時のコマンドライン。
してできた
Main_func
Main_func <Option> <AppKey>
bashlib を使うスクリプトは、この Main_func から内容を記述します。
【引数】
Option
AppKey
未定義
アプリケーション・キー
ユーザ定義関数です。
引数はあってもなくてもかまいませんが、ファイルに出力するスクリプトは、
AppKeyClass.newWritable_method
を呼ぶ必要があります。
AppKey 引数を使った
Main_func 関数を定義しているスクリプト・ファイルの中に、
(bashlib をインクルードして Main_func を呼び出すコード)が必要です。
bashlib include
のコード
Main_func 関数が呼ばれるときのカレント・フォルダーは、スクリプトがあるフォルダー
になります。 起動したときのカレント・フォルダーは、
に入っています。
g_StartInPath
→ bashlib/sample フォルダ
サンプル
g_StartInPath
declare g_StartInPath as string
プロセス起動時のカレント・フォルダーの絶対パス。
Main_func 関数を呼ばれたときのカレント・フォルダーは、メイン・シェルスクリプト・ファイル
があるフォルダーになります。 プロセス起動時のカレント・フォルダーは、g_StartInPath から
取得する必要があります。
このように変更した理由は、書かれたスクリプトが、汎用コマンドとして使われることより、
スクリプトがあるフォルダーに対して固有の処理を行うことが多いためです。
g_StartInPath を変更すると、
cd "$g_StartInPath"
サンプル
→ T_File.sh # [T_StartIn_func]
テスト
の基準フォルダーを変更することができます。
InputPath_func
g_Arguments
declare g_Arguments as array of string
プロセスを起動した時のコマンドライン。
./sample.sh -o opt_param --option="param X" Param1 "Param 2"
サンプル
起動したときのコマンド:
g_Arguments の値:
"${g_Arguments[0]}" == "/home/user1/sample.sh"
"${g_Arguments[1]}" == "-o"
"${g_Arguments[2]}" == "opt_param"
"${g_Arguments[3]}" == "--option=param X"
"${g_Arguments[4]}" == "Param1"
"${g_Arguments[5]}" == "Param 2"
→ ArrayClass.remove_method
関連
パラメーターをシフトします。
テスト
サンプル
ArrayClass.remove_method g_Arguments 1
コマンドラインの第1パラメーターを削除します。
→ T_File.sh # [T_StartIn_func]
サンプル
local here ; here=`dirname "${g_Arguments[0]}"`
スクリプトが入っているフォルダーのパス
エラー処理
CheckPipeStatus_func
done_func
Error_func
g_Err_Desc
g_ExitStatus
TryStart_func, TryEnd1_func, TryEnd2_func
ErrClass.raiseOverwrite_method
ErrClass.clear_method
パイプを使った処理において、エラーを検出します。
ループの直後に、; done_func $? を記述してください。
エラーを発生させます。
エラーメッセージ。
終了ステータスのコピー。
エラーをキャッチします。構造化例外処理。
処理中のエラーを、上位の TryStart に投げます。
エラーをクリアします。
CheckPipeStatus_func
CheckPipeStatus_func <PipeStatus>
直前のパイプを使った処理において、1つでも終了ステータスが 0 以外ならエラーにします。
【引数】
PipeStatus
"${PIPESTATUS[@]}" を指定してください
サンプル
true | false
CheckPipeStatus_func "${PIPESTATUS[@]}"
→ T_Err.sh # [T_CheckPipeStatus_func]
テスト
サンプル
line=`cat "not_found" | head --lines=1 ; CheckPipeStatus_func "${PIPESTATUS[@]}"`
CheckPipeStatus_func を使わないと、パイプの最後の段のエラーしか検出しません。
done_func
while true; do
CheckWritable_func "$PWD/out/a.txt"
break
done ; done_func $?
; done_func $?
ループの直後(break コマンドのジャンプ先)に、; done_func $? 記述してください。
エラーが発生した状態にも関わらず、ループのすぐ外から続きを実行することが、
なくなります。
→ T_Err.sh # T_NotTryLoop_func
テスト
→ T_NotTryLoopSub_func
→ T_Err.sh # T_DoneNoParam_func
→ T_Err.sh # T_DoneInErrMode_func
→ T_DoneInErrModeSub_func
Error_func
Error_func [<Message>]
エラーを発生させます。 標準エラー出力にメッセージを表示します。
【引数】
Message
メッセージ。省略時=メッセージなしのエラー
サンプル
Error_func "エラー"
<ERROR msg="エラー"/>
表示例:
表示例:
<ERROR msg="エラー" value="123"/>
value="123"
Error_func "<ERROR msg=\"エラー\" value=\"$value\"/>"
サンプル
<ERROR> タグを指定すると、そのまま表示します。
エラーメッセージは、<ERROR> タグを付けて表示されます。
エラーメッセージは、g_Err_Desc 変数に格納されます。
終了ステータス(return値)は、1になります。
テスト
表示例:
<ERROR/>
Error_func
サンプル
引数を省略したとき
→ T_ErrorInErrModeSub_func
→ T_Err.sh # T_ErrorInErrMode_func
g_Err_Desc
declare g_Err_Desc as string
エラーメッセージ。
Error_func
を呼び出すと、g_Err_Desc にエラーメッセージが格納されます。
Error_func 以外で発生したエラーでは、メッセージは格納されません。
サンプル
echo "$g_Err_Desc" >&2
g_ExitStatus
declare g_ExitStatus as integer
終了ステータスのコピー。
TryStart_func ~ TryEnd2_func
終了ステータスが 0 以外になると、TryEnd2_func にジャンプして、
g_ExitStatus にその終了ステータスが格納されます。
bashlib を使う環境では、
ErrClass.clear_method
を呼び出すと、0 にクリアされます。
エラー処理モードなら、1~255 のどれかが、通常モードなら 0 が入っています。
の間で実行したコマンドの
サンプル
if [ "$g_ExitStatus" == "2" ];then
TryStart_func, TryEnd1_func, TryEnd2_func
while TryStart_func; do
CheckWritable_func "$PWD/out/a.txt"
TryEnd1_func; done ;TryEnd2_func $?
if [ "$g_ExitStatus" == "0" ]; then Error_func "Error exptected" ;fi
echo "${g_Err_Desc}${LF}This error is OK"; ErrClass.clear_method
TryStart_func
TryEnd1_func
TryEnd2_func $?
テスト
→ T_Err.sh # T_TryLv0_func
→ T_Err.sh # T_TryLv1_func
→ T_Err.sh # T_TryLv1Clear_func
→ T_Err.sh # T_TryLv2_func
→ T_Err.sh # T_TryLv2Change_func
→ T_Err.sh # T_TryLv1Proc1_func
→ T_Err.sh # T_NotTryLoop_func
エラーをキャッチします。
エラーが発生してもシェル・スクリプトを終了させたくないときに使います。
サンプル
while TryStart_func; do
CheckWritable_func "$PWD/out/a.txt"
TryEnd1_func; done ;TryEnd2_func $?
#// Finally
if [ "$g_ExitStatus" != "0" ]; then ErrClass.raiseOverwrite_method ;fi
エラーであることのテスト
サンプル
Finally ブロック。 正常時でもエラー時でも実行するブロック。
TryStart_func ~ TryEnd2_func の間で実行したコマンドの終了ステータスが 0 以外に
なると、TryEnd2_func にジャンプして、終了ステータスを g_ExitStatus 変数に格納し、
エラー処理モードに入ります。
エラーが発生したときは、必要なエラー処理を行った後で、ErrClass.clear_method を
呼び出してエラー処理モードから通常モードに戻すか、Error_func または
ErrClass.raiseOverwrite_method を呼び出して、コールスタックの浅い方にある
TryStart_func ~ TryEnd2_func にジャンプするか、シェル・スクリプトを正しく異常終了
する必要があります。
bashlib は、終了ステータスをエラー番号として扱い、終了ステータスが 0 以外なら
エラーが発生したものとみなします。 これは、bash の -e オプションや、make と同じ
仕様です。
→ 終了ステータスの取得は、|| を使う
関連
→ T_TryLv2Sub_func
→ T_TryLv1ClearSub_func
→ T_TryLv1Sub_func
→ T_TryLv0Sub_func
→ T_TryLv2ChangeSub_func
→ T_TryLv1Proc1Sub_func
→ T_NotTryLoopSub_func
→ T_Err.sh # T_DoneInErrMode_func
→ T_DoneInErrModeSub_func
→ T_ErrorInErrModeSub_func
→ T_Err.sh # T_ErrorInErrMode_func
TryStart_func
TryEnd1_func
TryEnd2_func $?
ErrClass.raiseOverwrite_method
ErrClass.raiseOverwrite_method [<ErrMessage>]
処理中のエラーを、上位の TryStart に投げます。
【引数】
ErrMessage
上書きするエラーメッセージ。 省略=上書きしない
テスト
→ T_Err.sh # T_TryLv2Change_func
→ T_TryLv2ChangeSub_func
while TryStart_func; do
CheckWritable_func "$PWD/out/a.txt"
TryEnd1_func; done ;TryEnd2_func $?
#// Finally
if [ "$g_ExitStatus" != "0" ]; then ErrClass.raiseOverwrite_method ;fi
サンプル
ErrClass.raiseOverwrite_method
TryStart_func
ErrClass.clear_method
エラーをクリアします。
ErrClass.clear_method
g_ExitStatus 変数、g_Err_Desc 変数の値はクリアされます。
テスト
→ T_Err.sh # T_TryLv1Clear_func
→ T_TryLv1ClearSub_func
while TryStart_func; do
CheckWritable_func "$PWD/out/a.txt"
TryEnd1_func; done ;TryEnd2_func $?
if [ "$g_ExitStatus" == "0" ]; then Error_func "Error exptected" ;fi
echo "${g_Err_Desc}${LF}This error is OK"; ErrClass.clear_method
サンプル
ErrClass.clear_method
TryStart_func
その他
→ CheckArgCount_func
関数に渡された引数の数をチェックします
困ったときは? (デバッグ)
エラーメッセージを見ても分からないときは、スクリプトの開発者に質問してください。
あなたが開発者であるときは、下記のデバッグ用の関数を使ってください。
debugger, de
es
Pause_func
ステップ実行を開始します。 開始地点で、コールスタックを表示します。
指定した変数の値をダンプします。
Enter キーを押すまで、実行途中で止めます。
ec
現在位置と、変数の値を表示します。
BashSyntax
" ' ` の対応関係が誤っている箇所を探します。 vbslib4 が提供するツールです。
gedit でも、" ' ` の対応関係は、文字の色から分かります。
ソフトウェアデザイン館 Sage Plaisir 21 http://www.sage-p.com/
サポート
ホームページにあるサポート掲示板かメールアドレスへ
de, debugger
debugger
ステップ実行を開始します。 開始地点で、コールスタックを表示します。
de は、debugger の別名です。 どちらを使ってもかまいません。
コールツリー:
(global) ./T_Err_Manually.sh:120
FuncA_func() ./T_Err_Manually.sh:105
--- デバッガ情報 ---------------------------
ステップ実行 … Enter キーを押してください
変数の値を表示 … 変数名を入力
----------------------------------------------------
FuncA_func() ./T_Err_Manually.sh:105
105: local self="$1"
FuncA_func() ./T_Err_Manually.sh:106
106: local Prompt="$2"
FuncA_func() ./T_Err_Manually.sh:107
107: local Opt="$3" Prompt
$Prompt = 番号 >
サンプル
function FuncA_func()
{
de
local self="$1"
local Prompt="$2"
local Opt="$3"
}
FuncA_func "obj" "番号 >"
de
画面の様子
105, 106 行目では Enter を押しています。
107 行目では、Prompt と入力して Enter を押しています。
→ T_Err_Manually.sh # [T_Step_func]
テスト
→ T_Err_Manually.sh # [T_EchoStep_func]
de
ec
ec <Expression>
現在の位置と、引数の内容を表示します。 引数に指定した式も表示します。
【引数】
Expression
式、' ' で囲むこと。 省略可
サンプル
ec
ec> FuncA_func() sample.sh(115)
表示例
標準エラー出力へ出力します。
表示例
ec> FuncA_func() sample.sh(115)
ec> $VAR = "ABC"
ec '$VAR'
サンプル
echo の代わりに Watch を使うと、echo による返り値を返す関数の中でも表示されます。
echo for debug
es
es <Name>
指定した変数の値をダンプします。
【引数】
Name
変数名。 先頭に $ を付けないこと
サンプル
local var="AB DE"
es var
"$var"="AB DE"
00000000 41 42 20 20 44 45 |AB DE|
00000006
表示例
→ T_Err.sh # T_DumpVar_func
テスト
標準エラー出力へ出力します。
echo string for debug