62038


`command -p1 <param1> -p2 <param2> ...`

みたいなコマンドをデーモンでいくつか動かしたいのですが  
**パラメータを１つの設定ファイルで管理する方法** はないでしょうか？

今は

[code]

    #!/bin/bash
    PARAM1=abc
    PARAM2=123
    command -p1 $PARAM1 -p2 $PARAM2
    
[/code]

みたいなスクリプトをいくつも用意してるのですが  
**パラメータを変更する際全部のファイルに変更が必要なので１ファイルに集約したい** です

例えば config.ini

[code]

    [option1]
    PARAM1: abc
    PARAM2: 123
    
    [option2]
    PARAM1: def
    PARAM2: 456
    
[/code]

みたいな設定ファイルと

start.sh

[code]

    #!/bin/bash
    # config.ini のラベル $1 を読み込み
    command -p1 $PARAM1 -p2 $PARAM2
    
[/code]

という共通の実行ファイルだけ用意して  
`bash start.sh option1`  
`bash start.sh option2`  
みたいにラベル名だけ渡してパラメータを変えられるようにしたいです

設定ファイルのフォーマットは ini でも yaml でも２次元 hash を扱えれば何でもいいです

とりあえず設定ファイルを json にして  
jq で .$1.PARAM1 .$1.PARAM2  
みたいに取得することを考えてますが json ってコメントアウトができないので  
もっと定番の方法があったら教えて欲しいです


CC BY-SA 4.0
2020-01-07T03:48:20.840
62020
2020-01-07T10:39:57.747
2020-01-07T10:19:11.443
question
shellscript shell
シェルスクリプトから使える config ファイルの作り方


source(または.)コマンドを利用すれば  
シンプルにシェルスクリプト内でシェルスクリプトを即時実行できます。  
呼び出したシェルスクリプトの変数はそのまま使えます。

config.sh

[code]

    #!/bin/bash
    $PARAM1=abc
    $PARAM2=123
    
[/code]

cmd.sh

[code]

    #!/bin/bash
    
    source ./config.sh
    
    echo $PARAM1
    echo $PARAM2
    
[/code]

実行結果はこんな形です。

> $ ./cmd.sh  
>  abc  
>  123

あとは引数で切り分けで呼び出すオプション用のシェルを切り替えてはいかがでしょうか？

追記  
sourceか.かはbashかそうじゃないかが大事になってきます。  
適切な方を利用してみてください  
（参考）  
<https://takuya-1st.hatenablog.jp/entry/2017/01/07/111105>


CC BY-SA 4.0
2020-01-07T07:47:13.270
62026
2020-01-07T07:47:13.270
22665
62020
answer


よくあるのは、bash 形式の特定のファイルを読み込む方法だと思います。

ex) .bashrc

[code]

    if [ -f /etc/bashrc ]; then
            . /etc/bashrc
    fi
    
[/code]

なので、引数を元にするなら以下のような感じでしょうか

start.sh

[code]

    #!/bin/bash
    
    if [ -f "${1}.conf" ]; then
      . "${1}.conf"
    fi
    command -p1 $PARAM1 -p2 $PARAM2
    
[/code]

${1}.conf は、通常の bash 形式なので

option1.conf

[code]

    PARAM1=abc
    PARAM2=123
    
[/code]

option2.conf

[code]

    PARAM1=def
    PARAM2=456
    
[/code]

と、言う形になります。

[code]

    # 全体で同じ設定をしたり
    if [ -f "/etc/default/hoe.conf" ]; then
      . "/etc/default/hoe.conf"
    fi
    
    # コマンド毎の設定をしたり
    if [ -f "${0}.conf" ]; then
      . "${0}.conf"
    fi
    
    # 引数でそれらの一部を変更したり
    if [ -f "${1}.conf" ]; then
      . "${1}.conf"
    fi
    
    # 特定のディレクトリの物を見るようにしたり
    if [ -f "/etc/myconf/${1}.conf" ]; then
      . "/etc/myconf/${1}.conf"
    fi
    
[/code]

と、ある程度柔軟にもできるので、お手軽だと思います。

１つの設定ファイルと言う条件にはならず、  
オプション毎に設定ファイルが別になりますが、  
複数の shell からは、同じオプション設定を読めます。


CC BY-SA 4.0
2020-01-07T07:56:24.990
62029
2020-01-07T07:56:24.990
4419
62020
answer


`config.ini` のフォーマットが質問欄にある通りだとして、sed
を使って以下の様に書く事もできるでしょう。テストの意味で最後のコマンドの実行部分は echo の引数にしてあります。

**start.sh**

[code]

    #!/bin/bash
    
    eval $(
      sed -En '
        /^\['"$1"']/,/^$/{
          s/^[ \t]*([^:]+)[ \t]*:[ \t]*(.+)[ \t]*$/\1="\2"/p
        }
      ' < config.ini
    )
    
    echo command ${PARAM1:+-p1} "${PARAM1}" ${PARAM2:+-p2} "${PARAM2}"
    
[/code]

**config.ini**

[code]

    [option1]
    PARAM1: abc
    PARAM2: 123
    
    [option2]
    PARAM1: def
    PARAM2: 456
    
    [option3]
    PARAM1: foo
    
    [option4]
    PARAM2: bar
    
[/code]

**実行例**

[code]

    $ ./start.sh option1
    command -p1 abc -p2 123
    
    $ ./start.sh option2
    command -p1 def -p2 456
    
    ## PARAM1 のみ指定
    $ ./start.sh option3
    command -p1 foo 
    
    ## PARAM2 のみ指定
    $ ./start.sh option4
    command  -p2 bar
    
    ## option 指定なし
    $ ./start.sh
    command  
    
[/code]


CC BY-SA 4.0
2020-01-07T08:30:45.567
62030
2020-01-07T08:30:45.567
62020
answer


bashですよね。シンプルに `source` に引数を渡したらどうでしょうか。

### start.sh

[code]

    #!/bin/bash
    
    CURRENT_DIR=$(cd "$(dirname "$0")" && pwd -P)
    source "${CURRENT_DIR:?}/config.sh" "$1"
    
    echo command -p1 "$PARAM1" -p2 "$PARAM2"
    
[/code]

### config.sh

[code]

    #!/bin/bash
    
    case $1 in
    option1)
        PARAM1=abc
        PARAM2=123
        ;;
    option2)
        PARAM1=def
        PARAM2=456
        ;;
    esac
    
[/code]

実行するとこんな感じ:

[code]

    $ bash start.sh option1
    command -p1 abc -p2 123
    
[/code]


CC BY-SA 4.0
2020-01-07T10:39:57.747
62038
2020-01-07T10:39:57.747
62
62020
answer