【Shell】実行時に指定したファイル名とディレクトリパス(複数階層も可)を作成する

■実装するプログラムの概要

shell実行時に指定する引数にディレクトリ階層およびファイル名について、ディレクトリが存在していなければ、ディレクトリを作成し、そのディレクトリの中にファイルを作成する。

なお、
①ディレクトリはshellファイルが格納しているディレクトリをカレントディレクトリとする。
②指定したディレクトリは複数階層も可能とする。
③引数が「/」で終わる場合は、ファイルを作成せず、ディレクトリのみ作成する。

■フローチャート

・メイン処理


・ディレクトリとファイルを作成する処理(ファンクション)

■プログラム仕様

・メイン処理

No.インプット処理内容アウトプット
1実行ファイル名を変数にセットする。
2エラーコードを変数にセットする。
初期値:0(正常)
3処理開始のメッセージを出力する。【メッセージ】
処理開始:「エラーコード」
4【条件分岐】
▼引数が設定されているかチェックする。
・設定されている:
No.5の処理へ移動する。
・設定されていない:
エラーメッセージを出力する。
エラーコードを「1」にする。
処理を終了する。
【メッセージ】
引数が指定されていません。
処理終了:「エラーコード」
5【ループ開始】
指定した引数分繰り返す。
6ディレクトリとファイルを作成する処理を呼び出す。
7【ループ終了】

・ディレクトリとファイルを作成する処理(ファンクション)

No.インプット処理内容アウトプット
1【引数】
ファイルパス
第1引数を変数にセットする。
2【条件分岐】
▼引数に文字が存在しているか確認する。
・存在あり:
No.3へ移動する。
・存在なし:
エラーメッセージを出力する。
エラーコードを「1」にする。
処理を終了する。
【メッセージ】
引数の文字に不備があります。
3ディレクトリ名の変数をセットする。
初期値:空
4【条件分岐】
▼引数がディレクトリ構造か確認する。
真:ディレクトリ名を変数にセットする。
偽:何もしない。
5【条件分岐】
▼ディレクトリ名を変数に格納しているか。
かつ
ディレクトリがすでに存在していないか。
真:ディレクトリを作成する(複数階層可)
偽:何もしない。
【ディレクトリ】
6【条件分岐】
▼ファイルがすでに存在しないか。
真:ファイルを新規作成する。
偽:何もしない。
【ファイル】

■ディレクト階層

「sample.sh」を実行し、同階層の「work」ディレクトリ以降のファイルまたはディレクトリを作成していく。(赤字部分

■サンプルコード

#!/bin/bash

# 実行ファイル名をセット(パスは削除)
readonly MODULE_NAME=${0##*/}

# 指定したファイルパスとファイルを作成する処理
make_dir_and_file()
{
    # 第1引数をセット
    local filepath=$1

    # 引数を指定しているか確認(z:文字数が0かどうか)
    if [[ -z ${filepath} ]]; then
        printf '%s\n' "${MODULE_NAME}:引数の文字に不備があります。" 1>&2
        retuen 1
    fi

    # ディレクトリ名の変数をセット(初期値:空)
    local dir_name=

    # 引数がディレクトリ構造か確認
    # [/]が含まれているかどうかチェック
    # 真の場合はファイル名以外をディレクトリ名に格納
    if [[ ${filepath} == */* ]]; then
        dir_name=${filepath%/*}
    fi

    # ディレクトリ作成(複数階層)
    # -n:変数の文字列数が0より大きいか
    # !-d:ディレクトリがすでに存在していないか
    # mkdirコマンドで不具合が発生した場合はエラーコード2を返す
    if [[ -n ${dir_name} && ! -d ${dir_name} ]]; then
        mkdir -p -- "${dir_name}" || return 2

    fi

    # ファイルが存在していなければ新規作成
    if [[ ! -e ${filepath} ]]; then
        touch -- "${filepath}"
    fi

}

# エラーコードをセット(初期値:0正常)
result=0

printf '%s\n' "${MODULE_NAME}:処理開始:${result}"

# 引数がしていされているかチェック
if [[ $# -le 0 ]]; then
    printf '%s\n' "${MODULE_NAME}:引数が指定されていません。" 1>&2
    result=1
    printf '%s\n' "${MODULE_NAME}:処理終了:${result}"
    exit
fi

for i in "$@"
do
    make_dir_and_file "$i" || result=$?
done

printf '%s\n' "${MODULE_NAME}:処理終了:${result}"

exit

■実行結果

・実行コマンド(複数指定)

$ ./sample.sh work/hoge.txt work/tmp/hoge.txt work/tmp/huga/
sample.sh:処理開始:0
sample.sh:処理終了:0

$ ls -1
sample.sh
work

$ ls -1 work
hoge.txt
tmp

 ls -1 work/tmp
hoge.txt
huga

・実行結果(引数なし)

$ ./sample.sh
sample.sh:処理開始:0
sample.sh:引数が指定されていません。
sample.sh:処理終了:1
タイトルとURLをコピーしました