windows の資格情報削除
2021/10/02 17:10
Windows の資格情報削除
Windows を利用していると Teams のログインなどで登録されることがあるアカウント情報。消すならWinキー→資格といれて資格情報にアクセス
資格情報マネージャーへのアクセス方法
サーチ利用
Win キーから「資格」と入力した状態で、資格情報マネージャーにアクセスできる。ちなみに、英語で Credential Manager らしく、cred を入力してもアクセス可能。
アカウント情報削除
アカウントへのアクセス
「Web 資格情報」と「Windows 資格情報」があるが、Teams で利用するアカウントは Windows 資格情報の中にある。情報削除
Windows 資格情報のなかで、汎用資格情報のなかに「SSO_POP_User:user=xxx@example.co.jp」のような内容があるので、それを開く。SCL テンプレート
2021/08/17 19:10
シェルスクリプトテンプレート
シェルコマンド言語は、インタープリタの性質上、実行速度の面で不利です。そのため、大規模なアプリとしての実装には向きません。
しかし、ログ出力といった最低限の機能は作るほうが、メンテナンス等で楽になります。
ここでは、シェルコマンド言語を利用する場合のテンプレートを公開しています。いずれもライセンスは 3条項BSDライセンス としていますので、自由に改変してください。
また、日本語を含むため UTF-8 で保存しています。日本語行を削除した場合は、エディタの実装によって ASCII や Shift JIS として処理されます。
テンプレート A (標準構成)
ひとつのファイルですべてを完結する、標準的なテンプレートです。そのまま利用する場合は /var/log/script ディレクトリを事前に作成してください。
スクリプトの格納場所は指定しません。
利用時には Timing の Anytime か Cron どちらかを消してください。他にも不都合がある部分は修正してください。
ファイルは こちら からダウンロードできます。
template_a_20210807.zip
もしくは、下記をコピペしてください。文字コードを UTF8 にすることをお勧めします。
template_a.sh
#!/bin/bash ###################################################################### # # Script name : template_a.sh # Usage : template_A.sh [-h] [-v] # Update : 2021.8.7 / Kazuya Jimba # yyyy.mm.dd / Name # Timing : Anytime # Timing : Cron (* * * * *) # # オリジナル配布元 http://ttm.jimba.ddo.jp/ # 改変は自由ですが、改変者の責任に基づくものとします。 ###################################################################### ### Parameter and Bariable ########################################### ## Directory pLogDir="/var/log/script" ## File pLogFile="$(basename $0 .sh).log" ## Path pLogPath="${pLogDir}/${pLogFile}" ## etc pVersion="20210807.01" ## Numbers nReportDay=0 nRV=0 ## Flag # Script log # 0 - Script log # 1 - Standard output # 2 - Standard error output # 3 - /var/log/messages fLogOutput=0 ### Function ######################################################### fnLog() { case ${fLogOutput} in 0 ) echo "$(date '+%Y/%m/%d %H:%M:%S') $*" >> ${pLogFile};; 1 ) echo "$*";; 2 ) echo "$*" >&2;; 3 ) /usr/bin/logger -t ${0##*/} "$*";; esac } fnErr() { echo "$*" >&2 fnLog "Error: $*" } fnEnd() { case ${1} in 0 ) fnLog "Normal end.";; 11 ) fnErr "Read permission not exist (${2})";; 12 ) fnErr "Write permission not exist (${2})";; 13 ) fnErr "Exec permission not exist (${2})";; 14 ) fnErr "Directory not exist (${2})";; 15 ) fnErr "File not exist (${2})";; * ) fnErr "Unknown error (${2})";; esac exit ${1} } ### Main ############################################################# # Environment check fnLog "Script start (${0##*/})" [ -d "${pLogDir}" ] || fnEnd 14 "${pLogDir}" [ -f "${pLogPath}" ] || fnEnd 15 "${pLogPath}" # Argument analyse while getopts vh tOpt; do case ${tOpt} in h ) fnLog "Option: Help message." echo "${0##*/} [-h] [-v]" echo " [-v] Version print." echo "" fnEnd 0 ;; v ) fnLog "Option: Version print." echo "Script version: ${pVersion}" echo "" fnEnd 0 ;; esac done # xxxxx ### End ############################################################## # report nReportDay=$(( $(date -u +'%d' --date="@${SECONDS}") - 1 )) fnLog "Exec Time: ${nReportDay} day $( date -u +'%H:%M:%S' --date=@${SECONDS} )" # end fnEnd ${nRV} ######################################################################
テンプレート B (Source あり)
source コマンド . で変数および関数を外部ファイルにした、中規模~大規模向けのテンプレートです。デフォルトでは、スクリプトの格納場所を /usr/local/script で想定しています。
そのまま利用する場合は /usr/local/ ディレクトリにファイルを置いて、unzip コマンドで解凍してください。
ファイルは、次の構成になっています。
./script/ ./script/template_b.sh ./script/conf/ ./script/conf/common.cnf ./script/conf/template_b.cnf ./script/log/ ./script/tmp/展開後は、各ディレクトリ、各ファイルの権限を適切に変更してください。
利用時には Timing の Anytime か Cron どちらかを消してください。他にも不都合がある部分は修正してください。
ファイルは こちら からダウンロードできます。
template_b_20210808.zip
もしくは、下記をコピペしてください。文字コードは UTF8 をお勧めします。
template_b.sh
個別に作るスクリプトのテンプレートです。コピーして使います。
#!/bin/bash ###################################################################### # # Script name : template_b.sh # Usage : template_b.sh [-h] [-v] # Update : 2021.8.8 / Kazuya Jimba # yyyy.mm.dd / Name # Timing : Anytime # Timing : Cron (* * * * *) # # オリジナル配布元 http://ttm.jimba.ddo.jp/ # 改変は自由ですが、改変者の責任に基づくものとします。 ###################################################################### ### Parameter and Bariable ########################################### # common.cnf if [ -f conf/common.cnf ];then . conf/common.cnf else echo "Not exist conf/common.cnf" exit 1 fi # template_b.cnf [ -f conf/template_b.cnf ] || fnErrEnd 11 "conf/template_b.cnf" . conf/template_b.cnf ### Main ############################################################# # Environment check fnLog "Script start (${0##*/})" [ -d "${pConfDir}" ] || fnErrEnd 14 "${pConfDir}" [ -d "${pLogDir}" ] || fnErrEnd 14 "${pLogDir}" [ -d "${pTmpDir}" ] || fnErrEnd 14 "${pTmpDir}" # Argument analyse while getopts vh tOpt; do case ${tOpt} in h ) fnLog "Option: Help message." echo "${0##*/} [-h] [-v]" echo " [-v] Version print." echo "" fnEnd ${nRV} ;; v ) fnLog "Option: Version print." echo "Script version: ${pVersion}" echo "" fnEnd ${nRV} ;; esac done # xxxxx ### End ############################################################## # report nReportDay=$(( $(date -u +'%d' --date="@${SECONDS}") - 1 )) fnLog "Exec Time: ${nReportDay} day $( date -u +'%H:%M:%S' --date=@${SECONDS} )" # end fnEnd ${nRV} ######################################################################
common.cnf
スクリプト共通の設定ファイルです。作成するスクリプトで追加したい共通機能があれば、こちらに追記します。
利用したい環境に応じて、各設定を変更してください。
###################################################################### # # Script name : common.cnf # Usage : . ./common.sh # Update : 2021.8.7 / Kazuya Jimba # yyyy.mm.dd / Name # Timing : Anytime # # オリジナル配布元 http://ttm.jimba.ddo.jp/ # 改変は自由ですが、改変者の責任に基づくものとします。 ###################################################################### ### Parameter and Bariable ########################################### ## Directory pBaseDir="/usr/local/script" pConfDir="${pBaseDir}/conf" pLogDir="${pBaseDir}/log" pTmpDir="${pBaseDir}/tmp" ## File pLogFile="$(basename $0 .sh).log" ## Path pLogPath="${pLogDir}/${pLogFile}" ## etc ## Numbers nReportDay=0 nRV=0 ## Flag # Log Severity level # NAME Lv Message content # EMERG 0 System is unusable # ALERT 1 Should be corrected immediately # CRIT 2 Critical conditions # ERR 3 Error conditions # WARNING 4 May indicate that an error will occur if action is not taken. # NOTICE 5 Events that are unusual, but not error conditions. # INFO 6 Normal operational messages that require no action. # DEBUG 7 Information useful to developers for debugging the application. pLogNotifyLv=5 # Log output # 0 - Script log # 1 - Standard output # 2 - Standard error output # 3 - /var/log/messages fLogOutput=0 # ログ管理 0=通知する fEnLog=0 fEnLogEmerg=0 fEnLogAlert=0 fEnLogCrit=0 fEnLogErr=0 fEnLogWarn=0 fEnLogNotice=0 fEnLogInfo=0 fEnLogDebug=0 ### Function ######################################################### fnLog() { case ${fLogOutput} in 0 ) echo "$(date '+%Y/%m/%d %H:%M:%S') $*" >> ${pLogPath};; 1 ) echo "$*";; 2 ) echo "$*" >&2;; 3 ) /usr/bin/logger -t ${0##*/} "$*";; esac } fnEmerg() { echo "$*" >&2 [ "${fEnLogEmerg}" -eq "0" ] && fnLog "[Emergency] $*" } fnAlert() { if [ "${pLogNotifyLv}" -ge "1" ]; then echo "$*" >&2 [ "${fEnLogAlert}" -eq "0" ] && fnLog "[Alert] $*" fi } fnCrit() { if [ "${pLogNotifyLv}" -ge "2" ]; then echo "$*" >&2 [ "${fEnLogCrit}" -eq "0" ] && fnLog "[Critical] $*" fi } fnErr() { if [ "${pLogNotifyLv}" -ge "3" ]; then echo "$*" >&2 [ "${fEnLogErr}" -eq "0" ] && fnLog "[Err] $*" fi } fnWarn() { if [ "${pLogNotifyLv}" -ge "4" ]; then [ "${fEnLogWarn}" -eq "0" ] && fnLog "[Warn] $*" fi } fnNotice() { if [ "${pLogNotifyLv}" -ge "5" ]; then [ "${fEnLogNotice}" -eq "0" ] && fnLog "[Notice] $*" fi } fnInfo() { if [ "${pLogNotifyLv}" -ge "6" ]; then [ "${fEnLogInfo}" -eq "0" ] && fnLog "[Info] $*" fi } fnDebug() { if [ "${pLogNotifyLv}" -ge "7" ]; then [ "${fEnLogDebug}" -eq "0" ] && fnLog "[Debug] $*" fi } fnParam() { fnDebug '[Param] $'"$1 = $2" } fnErrEnd() { # common.cnf を利用するスクリプト共通のエラー番号 caseValue=$1 case ${caseValue} in 0) fnWarn "Normal number input...";; 1) fnErr "Read Permission error ($2)";; 2) fnErr "Write Permission error ($2)";; 3) fnErr "Exec Permission error ($2)";; 10) fnErr "Directory not exist error ($2)";; 11) fnErr "File not exist error ($2)";; *) fnErr "Unknown error (${caseValue})";; esac exit ${caseValue} } ######################################################################
template_b.sh
スクリプト個別の設定ファイルです。必要の都度、コピーして使います。
###################################################################### # # Script name : template.cnf # Usage : [template.sh] . conf/template.cnf # Update : 2021.8.7 / Kazuya Jimba # yyyy.mm.dd / Name # Timing : Anytime # # オリジナル配布元 http://ttm.jimba.ddo.jp/ # 改変は自由ですが、改変者の責任に基づくものとします。 ###################################################################### ### Parameter and Bariable ########################################### ## Directory ## File ## Path ## etc pVersion="20210807.01" ## Numbers ## Flag # Log Severity level # NAME Lv Message content # EMERG 0 System is unusable # ALERT 1 Should be corrected immediately # CRIT 2 Critical conditions # ERR 3 Error conditions # WARNING 4 May indicate that an error will occur if action is not taken. # NOTICE 5 Events that are unusual, but not error conditions. # INFO 6 Normal operational messages that require no action. # DEBUG 7 Information useful to developers for debugging the application. pLogNotifyLv=5 # Log output # 0 - Script log # 1 - Standard output # 2 - Standard error output # 3 - /var/log/messages fLogOutput=0 # ログ管理 0=通知する fEnLog=0 fEnLogEmerg=0 fEnLogAlert=0 fEnLogCrit=0 fEnLogErr=0 fEnLogWarn=0 fEnLogNotice=0 fEnLogInfo=0 fEnLogDebug=0 ### Function ######################################################### fnEnd() { # template.sh で利用するエラー番号 case ${1} in 0 ) fnLog "Normal end.";; * ) fnErr "Unknown error (${2})";; esac fnLog "Script end (${0##*/})" exit ${1} } ######################################################################
IT系エンジニア
2021/10/25 18:02
エンジニア系
IT 系エンジニアがどのような職種なのか、簡単に説明する資料を作ってみました。
以下で、それぞれの枠について説明したいと思います。
システム開発
システムエンジニアを大雑把にいえば、システムの組み合わせと調整を主に行います。小さな運用スクリプトやマクロ等は作ることがありますが、大規模なアプリケーション開発は行いません*1。
システム開発において「要件定義」「設計」「構築」「検証」といったフェーズで、それぞれの成果物を要求されます。
要件定義は、お客様から聞いた内容を要件として整理するフェーズです。
どんな要求があり、何を使って解決するのか、システムの大枠を整理します。
プロジェクトによっては、コンサルタントが既に済ませていることもあります。
アウトプットとして、要件定義書が求められます。
設計は、要件定義を具体的に落とし込むフェーズです。
細かい設定値はさておいて、要件に沿った方針を決める基本設計と、基本設計をもとに設定値に落とし込む詳細設計に分けることが多いです。
アウトプットとしては設計書(基本設計書/詳細設計書)になるのですが、実際に構築するための作業手順書が含められることも多いです。
構築は、設計値を元に、実際にシステムをくみ上げていくフェーズです。
作業手順書をもとに作業するため、アウトプットとして、いつ、手順書のどこを、どのように実行したかを示すエビデンスと、第三者が設定値を検証可能なエビデンスを求められます。
よく利用されるのは、ツーマンセルで一人が実行役、一人が記録役になります。記録役が、印刷された手順書に実行時刻を記載することが多い *2 です。
専用のアプリを作るまでもない、運用のためのスクリプトを作ることもあります。
最低限、フローチャートは読めないと困るでしょう。
システムで利用する機器とそれに付属する OS /専用アプリはもちろん、アプライアンス(システム用の製品)関係の知識も必要です。
非常に幅広い知識と応用力などが要求されます。
なお、システムエンジニアは基本的にプレイヤーなので、マネジメントも行うようになるとマネジメントプレイヤーもしくは何でも屋という名称で呼ばれたりします。
インフラエンジニア
システムエンジニア内でも専門性があり、次のように分かれます。サーバエンジニア
コンピュータでサービスを動かし、システムに必要なサーバを提供するのが主な仕事になります。サーバの物理的なスペックから載せる OS についての知識、サービス用のアプリケーションインストール、状況に拠ってはチューニングといった仕事を行います。
サーバには UNIX や Linux といった POSIX 準拠の OS 上で動くものや、Windows で動くものなどがあります。
Linux しか触れない、Windows しか触れないといったエンジニアもいます。
POSIX で共通仕様は決められていてもベンダーごとに特徴はあるので、HP-UX は使えても Solaris は分からないといったことはあり得ます。
ネットワークエンジニア
ネットワークケーブルを敷設し、お客様とサーバが円滑に通信できるネットワークを提供するのが主な仕事になります。実績と信頼性の高さから、商業用には主に Cisco 製品の知識が求められます。
普段は bps (bit per sec) の単位でネットワークを見ているので、Byte 単位が基本のアプリ側とやり取りするときは変換が必須です。
データベースエンジニア
システムが利用する情報を整理し、適切に応答するデータベースを提供するのが主な仕事になります。商業用には主に Oracle 製品の知識があると良いでしょう*3。
OSS としては mariaDB が採用されることも多いです。
SQL という、DB 向けの言語であってもアプリ毎の設計方針から方言の癖がつよいので、この DB しか使えないという DB エンジニアもいます。
セキュリティエンジニア
システムに含まれる脆弱性と、無数のアタッカーからシステムを守るシステムを提供するのが主な仕事になります。ネットワーク、OS、アプリそれぞれのセキュリティ情報や、防御用アプライアンスの知識などが求められます。
ソフトウェアエンジニア
ソフトウェエンジニアもシステムエンジニアに数えられますが、ここでは割愛して別項目にします。ウェブエンジニア(未掲載)
ウェブエンジニアもシステムエンジニアに数えられます。ただし、ウェブ上で利用されるシステムという、分かるような分からないような曖昧な定義になっています。
共通するのは、WebUI *4 をもつシステムに携わるというところです。
WebUI のデザインを行っているかと思えばネットワークのボトルネックを調べていたり、アプリケーション開発をしていたり、サーバのチューニングをしていたりします。
扱う範囲が広すぎるので、お客様が直接扱うソフトウェア側をフロントエンド、フロントエンドを構成するためのインフラ側をバックエンドと呼ぶようです。
上の図には未掲載です。
フロントエンドエンジニア
ブラウザで直接操作するアプリと、その UI を主に扱うエンジニアを、フロントエンドエンジニアと呼びます。お客様の前に立つ、ホテルのフロントをイメージすると理解しやすいかもしれません。
HTML / CSS / XML / JSON といった、ブラウザで直接扱うマークアップ言語や、そのコードを出力するためのアプリケーションに Java / Ruby / PHP といったスクリプト(インタプリタ型言語)が使われています。
まれに、高速な応答が必要なシステムで C 言語といったコンパイラ言語(コンパイル型言語)が使われることもあるようです。
担当する業務によっては、ネットワークを意識することがないとか、他にもウェブデザイナー業務を担当することがあると聞いています。
バックエンドエンジニア
ブラウザ操作で意識しない、裏方のシステムを主に扱うエンジニアを、バックエンドエンジニアと呼びます。インフラエンジニアと業務内容が被るのですが、インフラエンジニアはウェブ操作とは全く関係ないシステムも扱うため、微妙な差異で使い分けられています。
クラウドエンジニア(未掲載)
IaaS を中心としたサービスを主に扱うシステムエンジニアです。コーポレートエンジニア
どちらかというと発注側のエンジニアで、社内システムに特化しているのがコーポレートエンジニアです。社内エンジニアとも呼ばれます。
外注のために浅くても広い知識や、査収といった業務を行います。
このため、会社の業務知識だったり、他社への発注手続きだったりと、庶務系に比重が置かれることも多くなります。
また、次のツイートが参考になると思います。
言及のある、タスクディクショナリは、こちら。
https://icd.ipa.go.jp/icd/icd
コンサルタント
コンサルタントは、経営者やプロジェクトの責任者などが抱える課題について、アドバイスやソリューションを提供するのが主な仕事になります。コンサルタントも専門で分かれるのですが、システムエンジニアからすると上流の仕事になります。
提案書を求められることがあります。
プリセールスエンジニア
プリセールスエンジニアはインフラエンジニアのなかでも営業に近く、システムの知識を持ちつつ、知識を生かした提案や、経営課題のソリューションを提供するのが主な仕事になります。システムを見ながら、コンサルティングできるエンジニアです。
提案力(プレゼン能力)やコミュニケーションといった、政治力が強く求められます。
ワーカー
出来上がっている手順書の通りに、システムを構築したり検証したりといった作業を行います。設計がおかしければ指摘したりする必要はありますが、基本的には事前にやることが決まっています。
そのため、エンジニアとは呼ばれません。
組込エンジニア
システムとしては少し毛色が変わりますが、組み込みエンジニアもエンジニアです。サービスが動くのではなく、マイコンなどのデバイスで動くシステムを作ります。
どちらかというと、デバイスを制御するためのシステムですね。
ハードウェアの知識が必要になるため、デバイスの開発を行うこともあるようです。
コンピュータを内蔵する機械であれば組込システムが存在するため、目立ちませんが必要な役割です。
デバイス
組込エンジニアでも、身近な製品(デバイス)を開発するのがメインのエンジニアです。IC やら抵抗やら、基盤設計を行う人がいると思えば、出来上がった基盤を制御するソフトウェア開発を行う人もいます。
もちろん、全部面倒みる人もいます。
マイコン(マイクロコンピュータ)や、組込 Linux もあって、外部からはかなり混沌とした業界のように見えます。
制御ソフト
ミシンや自動車といった身近なものから、工業ロボットのような大型の機械を制御するソフトウェア開発も、組込エンジニアのようです。ステークホルダー
アプリ開発
ここでは、システムエンジニア視点でのステークホルダーとしてくくっています。デベロッパ
開発する人たちの総称です。BIND、Apache/nginx、Sendmail、Samba、Docker/CRI-Oなどサーバとして動かすアプリを開発する人たちが含まれます。
彼らがいなければ、システムエンジニアは成り立ちません。
アプリに対する深い理解が必要不可欠です。
アプライアンス
特定目的のアプリを、想定されるユースケースにおいて使いやすいシステムで提供するベンダーです。条件によっては採用するほうがコストが安く品質を上げられるため、彼らが世に出す製品は広く知っておくべきです。
あまり詳細を知れないので、雲の向こう側として表現しています。
その他
ソフトウェアエンジニアという呼称が存在する、立派なエンジニアです。こちらもシステム開発動揺、要件定義、設計、コーディング、検証といった流れが存在します。
Web アプリを開発するなら、Web エンジニアと呼ばれたりするようです。
書いている人がソフトウェアエンジニアではないので外から眺めた感じの表現になってしまいますが、概ね間違っていないと思います。
ソフトウェアエンジニア
要件定義から検証まで、一貫して行えるアプリケーション開発者がソフトウェアエンジニアだと考えています。プログラマ
要件定義の済んでいるアプリケーションを、設計から行うのがプログラマだと考えています。コーダ
コーダは設計済みのフローチャート通りにコーディングする人のことだと考えています。システムエンジニアにおけるワーカーのようなものですね。
テスタ
開発の済んだコードが、要件を満たす挙動をするかどうか試験するのがテスタだと考えています。デバッガ
ほぼほぼテスタなのですが、開発の済んだコードの検証に加えて、開発者の想定外の挙動までチェックするのがデバッガのイメージです。運用・保守
システムを作っても、それを維持したり、状況の変化に応じてメンテナンスしたりしなければ、動かないシステムになってしまいます。基本的には想定される状況がすべて網羅された手順書があり、就職先としてのハードルは低いです。
問題が起きたら即座に対応しなければならないサービスの場合、システムエンジニアが兼任することもあります。
ヘルプデスク
クライアントの設定から故障対応まで、ユーザが操作するコンピュータを責任範囲とします。理不尽が多いのも特徴です。
オペレータ
運用(オペレーション)を行います。運用とは、たとえばユーザアカウントの追加や定期的な稼働確認といった内容になります。
24時間365日、システム監視ツールが動き、問題を検出したら状況確認から対応することになります。
対応は、関係部署への連絡です。
手順書はありますが、簡単に障害箇所を切り分ける能力が、ある程度求められます。
サーバが不通であればシステムエンジニアへ連絡。
ネットワークに問題があれば、ネットワークエンジニアに連絡。
物理機器が故障しているようであれば、保守員へ連絡。
そういった連絡が主な仕事です。
ただし、切り分けの結果によってはその場で対応しなければならないことも多く、運用と保守はひとまとめにされることも多いです。
保守員
保守(メンテナンス)を行います。勤務時間は保守契約により日中対応だけのものから、24時間対応のものもあります。
保守とは機械が壊れたときに交換するといった内容になります。
基本的には連絡待ちになりますが、初期稼働を早めるためにシステム監視を行うことがあります。
内容的に運用と被るものが多いので、運用と保守はひとまとめにされやすいです。
管理
プロジェクトやプレイヤーのマネジメントを行う人たちです。PM
PM はプロジェクトマネージャーの略で、プロジェクトを管理します。管理とは、予定をたてたり、進捗状況をみてテコ入れをしたり、お客様と交渉したり、成果物を見て改善を指示したりといった内容です。
進捗管理や品質管理といった呼称が使われます。
PMO
PMO はプロジェクトマネジメントオフィスの略で、PM が担当するプロジェクトをチームとして支援します。PM は一人ですが、PMO は複数人でプロジェクトにあたります。
大規模な開発では一人で進行を管理しきれないため、必要となります。
PL
PM の立てた計画を遂行する立場です。場合によってはシステムエンジニアが兼任することもありますし、システムエンジニアに PL の能力を求める人もいますが、基本的に PL はマネジメント側になります。
発注
ビジネスオーナー
ここでは、プロジェクトを定義して、システムを発注するのがビジネスオーナーであると定義しています。システムエンジニアが直接話す機会は少なく、雲の上の存在となっています。
コーディング規約案
2021/07/24 09:06
シェルコマンド言語 コーディング規約案
いろいろな考え方があり、それぞれのプロジェクトで最適解が異なります。規約のたたき台として、まずは作成しました。
参考の一助になれば幸いです。
ここでは、自分が使いやすい規約にしてみました。
臨機応変に変更してください。
Google Shell guide といったものも存在します。
https://google.github.io/styleguide/shellguide.html
プロジェクトにおけるシェルコマンド言語を利用したスクリプトは、視認性やメンテナンス性の向上を目的として、次の規約に則り作成すること。
汎用性の考慮
UNIX として共通の仕様である POSIX に規定された範囲でのコーディングとし、独自拡張は極力利用しないこと。https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
また、必要があって利用する場合は、ヘッダに注意事項として記載すること。
[Tips]
たとえば、Linux の for 文で C 言語のような ( i=0 ; i < x ; i++ ) という形式を利用できます。これは便利なのですが bash の独自実装なので汎用性が下がります。
スクリプト
スクリプトは、次の要件を満たすこと。ファイル名
ファイル名は、英数字 + 拡張子とする。拡張子
拡張子は、シェルスクリプト単体で実行するものを .sh とする。また、変数や関数を別途まとめたファイルについては .src とする。
[Tips]
csh / tcsh / fish / bash / dash といった、シェルを複数利用するようなプロジェクトでは、拡張子をそれぞれに合わせた方が良いと思います。
bash しか利用しないことが分かっている環境で、シバンにも bash 指定のみの場合は .sh でも不都合はないと思います。
.src は、内容として bash なのですが source コマンド (ビルトインでは . コマンド) で呼ぶことを意図しています。
実行権限
実行権限は、システムとして特に指定のない限り 610 とする。[Tips]
権限を 755 や 700 で運用することは多いのですが、セキュリティを考慮すると、権限は最小限にすべきでしょう。
ここでは本番環境を想定していて、作成するユーザと、実行するユーザが異なることを考慮しています。
所有者は、更新できるが実行できない。前提条件を満たさない、不用意な実行を阻止できる。
グループ(実行者)は、更新できないが実行できる。JP1 のような自動実行ユーザのスクリプト改変を阻止できる。
ファイル内容
構成
スクリプトは、次の構成を基本とする。段落 | 内容 | 備考 |
---|---|---|
ヘッダ | シバンやスクリプトの目的などを記載する。 | |
変数宣言 | スクリプトが利用する変数を宣言もしくは指定する。 | source (.) での指定も可 |
関数宣言 | スクリプトが利用する関数を宣言する。 | source (.) での指定も可 |
メイン処理 | スクリプトが目的とする処理を行う。 | |
終了処理 | 一時利用のために展開していたテンポラリファイルの削除などを行う。 |
文字コード
文字コードは UTF-8 とする。また、BOM は付与しないこと。
日本語はコメントに限定する。
[Tips]
コメントに日本語を使わない場合は ASCII を指定してもよいです。
むしろ ASCII として認識されるでしょう。
改行コード
改行コードは LF とする。[Tips]
Windows でスクリプトを書くと、改行コードは考慮から漏れがちです。
Linux や UNIX 上で書くと気にしなくても良いのですが、プロジェクトの進行状況や管理方法次第で、どうしても Windows 端末での開発を行わなければならない状況もあります。
致命的ではない文字コードやインデントも指定するのですから、致命的エラーとなる改行コードは指定しておきましょう。
インデント
インデントは、半角スペース2つとする。[Tips]
タブ (半角スペース4つもしくは8つ) だと、横に広がりすぎて視認性が悪くなることがあります。
シバン
シバンは、以下の通り bash とする。#!/bin/bash
[Tips]
シバンとヘッダは、ひとまとめにしてしまっても良いかもしれません。
もしくは、拡張子の指定でシバンも固定することになるでしょう。
ヘッダ
スクリプトの冒頭には、スクリプトの概要を記載する。項目 | 内容 | 備考 | |
---|---|---|---|
スクリプト名 | Script name | ファイル名称を記載する。 | |
変更 | Modify | 変更日・変更者・変更内容を記録する。 |
以下は、定義する際のサンプル。
項目 | 内容 | 備考 | |
---|---|---|---|
スクリプト名 | Script name | ファイル名称を記載する。 | |
目的 | Purpose | スクリプトの目的を記載する。 | |
引数 | Option | 指定可能なオプションを記載する。 | |
変更 | Modify | 作成日を記録する。 | 日付と担当者をひとまとめにしてもよい。 |
作成者 | Auther | 作成者を記載する。 | |
更新日 | Update | 更新日を記載する。 | 更新内容も併記するとなおよい。 |
権限 | Permission | 実行者や権限を記載する。 |
# Script name: example.shサンプル 2
# スクリプト名: example.sh # 目的: スクリプトサンプル
コメント
適宜コメントを記載すること。コメント内は日本語で記述する。
サンプル
# システム
パラメータ関係
変数名
変数名は、別途定めるプレフィックス/サフィックスを含め、キャメルケースで指定する。一部の予約された変数名以外は、単語の組み合わせで指定すること。
[Tips]
私がスネークケースよりキャメルケースのほうが読みやすいと感じるタイプなので、キャメルケースを指定しています。
メリット・デメリットを考慮して、規定するのが良いです。
変数名はスクリプト上部にまとめて宣言しておくので、エディタの画面分割機能でコピペすることが前提としてあります。
画面分割は vim でも可能です。
変数名が短くても、何回も手入力していればタイポする可能性は高いです。
プレフィックス
プレフィックスは、変数の用途に応じて次の文字を使用する。文字 | 用途 | 備考 |
---|---|---|
p | 汎用パラメータ | Parameter を意図 |
n | 数値用パラメータ | Number を意図 |
f | 0 を真としたフラグ情報 | Flag を意図 |
t | ループで頻繁に書き換える使い捨てパラメータ | Temporary を意図 |
i | ループ用に予約 | Integer を意図 (while/until での数値ループに使用) |
s | ループ用に予約 | String を意図(for での文字列ループに使用) |
サフィックス
サフィックスは、特定の用途で次の文字列を使用する。文字 | 用途 | 備考 |
---|---|---|
Path | 絶対パスでファイル情報を指定する場合に利用 | |
Dir | ディレクトリ情報の場合に利用 | 文字列の最後は / で終わること。 |
Name | ファイル情報の場合に利用 | ディレクトリは含めないこと。 |
Enable | フラグ管理など、0 で有効とする場合に利用 |
利用時の指定方法
変数を利用する場合は、ブラケットで括ること。Exit Status
終了ステータスは、スクリプトの目的が満たされることを正常とし、正常終了した場合に 0 とする。関数関係
関数は、関数名
関数名は、別途定めるプレフィックスを含め、キャメルケースで指定する。一部の予約された関数名以外は、単語の組み合わせで指定すること。
プレフィックス
プレフィックスは、変数の用途に応じて次の文字を使用する。文字 | 用途 | 備考 |
---|---|---|
fn | 関数 (ファンクション) であることを示す |
テンプレート関数
fnLog
特定のログファイルに、毎回リダイレクトを記述するのは可視性としても悪くなり、ミスも誘発しやすい。引数としてメッセージをログファイルへ書き込む関数を用意した。
スクリプトの進捗状況を記述する目的で利用すること。
サンプル
fnLog "Sample message"
fnDebug
開発時に利用したデバッグ用メッセージを、メンテナンス時にも再利用できるよう、フラグに応じて出力指定もできる関数を用意した。デバッグ情報を記述する目的で利用すること。
サンプル
fnDebug "Debug message"
fnErr
シェルスクリプトが標準エラー出力を行うための関数を用意した。エラー出力を記述する目的で利用すること。
サンプル
fnErr "Standard Error message"
fnErrEnd
存在しなければ即時で終了するための関数を用意した。引数として、エラー番号と、対象のファイルまたはディレクトリなどを指定すること。
サンプル
[ -d "/etc" ] || fnErrEnd 14 "/etc" [ -f "/etc/hosts" ] || fnErrEnd 15 "/etc/hosts" [ -x "/bin/ps" ] || fnErrEnd 13 "/bin/ps"
メイン
オプション解析
getopts を利用した解析を行う。[Tips]
- help といったロングオプションを使いたい場合は、getopts ではなく、引数そのものを case で解析するほうがよいと思います。
備考
テンプレート
シェルスクリプト
サンプル#!/bin/bash ############################################################ # Script name: example.sh # Modify : yyyy.mm.dd 名前 初版作成 ############################################################ ### Parameter and Variable ################################# pCommon=./src/common.src if [ -f "${pCommon}" ]; then . ${pCommon} else echo "${pCommon} not exist." exit 1 fi ### Function ############################################### fnEnd() { # スクリプト内で異常終了する際の Exit Status と、メッセージ内容の定義 nExitStatus=$1 case "${nExitStatus}" in 0 ) fnLog "Script ${0##*/} end.";; * ) fnErr "Unknown error ($2)"; nExitStatus=1;; esac exit ${nExitStatus} } ### Main ################################################### fnLog "Script ${0##*/} start." ## オプション解析 while getopts h OPT; do case ${OPT} in h ) fnDebug "Option h used." echo "Usage ${0##*/} [-h]" echo " [-h] help messages." fnEnd 0 ;; * ) fnDebug "Unknown option used." fnErrEnd 10 "${OPT}" ;; esac done # xxx 処理 ### End #################################################### fnEnd 0 ############################################################
外部ファイル
サンプル# 共通ファイル (common.src) ### Parameter and Variable ################################# ## ディレクトリ pLogDir="/var/log/script/" ## ファイル pLogName=$(basename ${0%.*}.log) ## パス # ログファイル pLogPath="${pLogDir}${pLogName}" # ヌルクリア i="" s="" # Exit Status nExitStatus=0 ## フラグ fDebugEnable=0 ### Function ############################################### # 目的:ログ出力 fnLog() { echo "$(date +'%Y/%m/%d %H:%M:%S') $*" >> ${pLogPath} } # 目的:デバッグ出力 fnLog() { [ "${fDebugEnable}" -eq "0" ] && fnLog "[Debug] $*" } # 目的:エラー出力 fnErr() { # ログ出力 fnLog "$*" # 標準エラー出力 echo "$(date +'%Y/%m/%d %H:%M:%S') $*" >&2 } # 目的: エラー終了 fnErrEnd() { nExitStatus=${1} # 引数確認 if [ -z "${nExitStatus}" ]; then fnErr "Not argument." exit 1 fi case "${nExitStatus}" in 0 ) fnErr "Function (fnErrEnd) argument error."; nExitStatus=1;; 10 ) fnErr "Argument error ($2)";; 11 ) fnErr "Read permission not exist ($2)";; 12 ) fnErr "Write permission not exist ($2)";; 13 ) fnErr "Exec permission not exist ($2)";; 14 ) fnErr "Directory not exist ($2)";; 15 ) fnErr "File not exist ($2)";; * ) fnErr "Unknown error ($2)";; esac exit ${nExitStatus} } ||