make
Bash 스크립팅을 사용하여 간단한 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
사용하는 것이 더 읽기 쉬울 수 있습니다.