1. ホーム
  2. bash

[解決済み] bashスクリプトで変数の束縛を解除

2022-02-18 10:35:58

質問

自分のスクリプトをデバッグするときに、先輩から勧められた構文を使ったのですが、どうすれば正しく動作するのかわからなくなってきました。

 #!/bin/bash -x
set -ueo pipefail
exec &>/tmp/dq.log
source ${BASH_SOURCE%/*}/env-prd.sh

times=${2:-1}
sleep=${3:-1}

name="all-dq_hourly"


fs_lock_file="/tmp/mwa/jobs/prd-${name}.lock"

( flock -n 200
    log="/var/log/mwa/prd/$(date +%Y-%m-%d)__${name}.log"
    for i in $(seq 1 $times); do
        if [[ ! -f /tmp/stop ]]; then
        couple commands

      fi
        sleep $sleep
    done

) 200>"$fs_lock_file" | tee -a $log

rm $fs_lock_file

実行結果から、私は、以下の変数に未束縛の問題があることがわかりました。 tee -a $log の部分です。 couple commands はちゃんと実行されます。ログパスでbackticsを使ってみましたが、効果はありませんでした。fs_lock_fileと同じ問題だと思いますが、まだロギングを先に修正していません。
誰か私の目を覚まして、何が足りないのか教えてください。スクリプトのロギングを指定されたパスにすることができないのです。

どうすればいいですか?

を変数に代入しています。 log の中にある サブシェル ( [...] ) . その変数はそのサブシェルの外では束縛されない。

この場合、単に log サブシェルの外側で、つまり、サブシェルブロックの前に変数の割り当てを移動します。

一般に同様のケースでは、サブシェルの括弧を中括弧に置き換えてみることができます ( グループコマンドの構文 ) { [...] } .

グループコマンドは、現在のシェルで実行されます。サブシェル構文とは対照的に、リストは、ニューラインまたはセミコロンで終了しなければならないことに注意してください。

また 一般的なベストプラクティス 変数名、特に定数をスクリプトや関数の最初に設定することで、この種のバグを回避することができます。