명령줄에서 나에게 매우 효과적인 명령은 다음과 같습니다.
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
위 명령을 실행하고 검색 경로를 임의의 경로로 바꾸면 명령은 여전히 확장자 .
가 또는 확장자를 가진 파일 목록만 표시합니다..c
.h
이제 명령을 다시 입력할 필요 없이 비슷한 검색을 수행하기 위해 약간의 수정만으로 스크립트를 실행할 수 있도록 변수 값과 동일한 명령을 사용하는 간단한 bash 스크립트를 작성하고 싶습니다. 그러나 여기서 나는 탈출 규칙의 악몽(또는 그에 대한 적절한 이해 부족)에 직면하게 됩니다.
나는 다음과 같이 스크립트를 작성했습니다.
#!/bin/bash
path="/home/vinod"
string="somestring"
command="find ${path} -type f -exec grep -Hin --include=*.h --include=*.c '${string}' {} \;"
echo $command
$command
위 스크립트를 실행하면 아래와 같이 명령이 한 번이 아닌 두 번 에코됩니다.
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
그리고 다음 런타임 오류:
find: missing argument to -exec
에코에서 볼 수 있듯이 명령은 명령줄에서 실행할 때와 정확히 동일하며 예상한 결과를 얻습니다.
내 스크립트에 어떤 문제가 있을 수 있는지에 대한 아이디어가 있나요?
티아
답변1
명령을 저장하기 위해 변수를 사용하지 마십시오. 대신 변수를 사용하여 데이터를 저장하고 함수를 사용하여 명령을 저장(정의)합니다.
검색 경로 시작과 검색 문자열이라는 두 가지 매개변수를 사용하여 명령을 생성할 수 있습니다.
시작 검색 경로도 고정된 경우 검색 모드만 사용하도록 간단히 수정할 수 있습니다. 실제로 검색 경로가 생략되면 기본값이 사용자 $HOME
디렉터리가 되도록 매개변수의 순서를 반대로 바꿔 보겠습니다.
#!/bin/sh
# Search in *.c and *.h files for a matching pattern
#
pattern=$1
path=${2:-$HOME}
find "${path:-.}" -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +
파일로 저장하고 chfind
실행 가능하게 만든 다음( chmod a+rx chfind
)에 넣습니다 $PATH
. 이제 다른 유틸리티처럼 사용할 수 있습니다.
chfind 'main'
chfind 'main' /some/other/tree/of/files
grep -F
정규 문자열이 아닌 실제로 정규 표현식인 검색 문자열을 사용하지 않기 때문에 이와 같은 명령문을 검색하는 것은 FILE *fp
작동하지 않습니다.
마지막으로 경로 이름을 검색 경로에 상대적으로 지정하려면 디렉터리를 다음으로 변경한 $path
다음 거기에서 검색할 수 있습니다.
cd "$path" &&
find -- * -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +
스크립트에서 인라인이 아닌 함수를 통해 이 작업을 수행하는 방법을 설명하는 것이 좋습니다. 나는 귀하의 기본 요구 사항을 해결했습니다("명령을 다시 입력하지 않고도 유사한 검색을 수행하기 위해 [...] 스크립트를 실행할 수 있도록 간단한 bash 스크립트 [...]를 작성하고 싶습니다."). 하지만 함수를 사용하려는 경우 거의 똑같습니다.
#!/bin/bash
# Search in *.c and *.h files for a matching pattern
#
chFind() {
local pattern=$1 path=$2
find "${path:-.}" -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +
}
chFind "$1" "${2:-$HOME}"