탭으로 시작하는 변수 값을 찾는 중에 문제가 발생했습니다.

탭으로 시작하는 변수 값을 찾는 중에 문제가 발생했습니다.

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'(팁을 주신 Kusalananda에게 감사드립니다).

#변수 대체 후 리터럴 탭을 삽입합니다. 그러나 printf사용하는 것이 더 읽기 쉬울 수 있습니다.

관련 정보