タブで始まる変数値の検索中に問題が発生しました。

タブで始まる変数値の検索中に問題が発生しました。

makeBashスクリプトを使用して単純なLinuxコマンドを作成しようとしています。これが私がこれまでに書いた内容です:

#!/usr/bin/env bash

function make_cmd()
{
  read target colon sources
  for src in $sources; do
    if [ $src -nt $target ]; then
      while read cmd && [[ $(echo "$cmd" | grep "$(printf '\t')"*) ]]; do
        echo "executing $cmd";
        eval ${cmd#$(printf '\t')};
      done
      break;
    fi
  done
}

入力形式は次のとおりです。

target.file : source.file
[tab]command

たとえば、

target.txt : source.txt
    ls
    cd

スクリプトは正常に実行されますが、タブで始まるコマンドは見つかりません。常に実行されます。たとえば、この入力のコマンドは引き続き実行されます。

target.txt : source.txt
ls
cd

この問題をどのように解決できますか?

答え1

組み込みコマンドは、デフォルトでスペース、タブ、および改行を含むread値を使用して単語を分割します。IFSしたがって、入力を受け取るとreadタブが削除されます。

関数は次から始まります。

IFS_SAVE="$IFS"
IFS=' '

これで、空白のみの単語を区別できます。関数が終了したら、IFSを元の値に復元します。

IFS="$IFS_SAVE"

バックスラッシュでエスケープすると、リテラルタブを使用できます。また、grepマッチングタブを使用せずに可能な限り組み込み機能を使用する方が高速です。私の機能バージョンは次のとおりです。

function make_cmd()
{
  SAVE_IFS="$IFS"
  IFS=' '
  read target colon sources
  for src in $sources; do
    if [ $src -nt $target ]; then
      while read cmd; do
        case "$cmd" in
          $'\t'*)  echo "executing $cmd"
                eval ${cmd# }
                ;;
          *)    ;;
        esac
      done
      break;
    fi
  done
  IFS="$SAVE_IFS"
}

リテラルタブを置き換えました$'\t'(ヒントをくれたKusalalanandaに感謝します)。

#変数の置換後にリテラルタブを挿入します。しかし、printf使用する方が読みやすくなります。

関連情報