나는 bash 스크립트에 깊이 빠져 있습니다.
grep -Ech 'string1|string2' /server/directory/$servername_log_20150312* | awk ...
"인수가 너무 많습니다" 오류가 발생하여 set -x
파일을 열었고 grep이 다음 파일부터 검색을 시도하고 있음을 발견했습니다.
/server/directory/$servername_log_20150101.000001.log # Notice the date disparity.
문자열의 각 문자열은 $servername
루프에서 반복되는 값을 사용하여 올바르게 확장됩니다. grep이 내가 지정한 문자열로 시작하는 파일 이름으로 제한되지 않는 이유는 무엇입니까?
답변1
질문
서버 이름을 정의하는 것부터 시작해 보겠습니다.
$ servername=SomeName
지금 시도해보세요:
$ echo "$servername_log_20150312"
$
(a) 밑줄은 쉘 변수 이름에서 유효한 문자이고 (b) 밑줄을 정의한 적이 없기 때문에 위의 내용은 아무것도 반환하지 않습니다 servername_log_20150312
.
이제 다음을 고려하십시오.
/server/directory/$servername_log_20150312*
변수가 확장되면 다음과 같습니다.
/server/directory/*
경로명 확장 후에는 위의 내용이 디렉터리의 모든 파일이 됩니다.
두 가지 솔루션
이런 종류의 일은 매우 일반적이기 때문에 쉘에는 변수에 대한 중괄호 표기법이 있습니다.
$ echo "${servername}_log_20150312"
SomeName_log_20150312
다음 문자에서 이름을 분리하는 다른 방법도 가능합니다.
$ echo "$servername""_log_20150312"
SomeName_log_20150312
문서
이제부터 man bash
변수 이름에는 영숫자와 밑줄을 조합하여 사용할 수 있지만 반드시 영문자로 시작해야 합니다.
name A word consisting only of alphanumeric characters and underscores, and
beginning with an alphabetic character or an underscore. Also referred
to as an identifier.
POSIX변수 이름 구현에 대한 제한을 종속시킵니다. 쉘이 이름에 영숫자 문자와 밑줄을 허용하도록 요구하지만 =
NUL 및 NUL을 제외한 모든 것을 허용하는 옵션을 쉘에 제공하는 것으로 보입니다.
답변2
@ john1024가 내 스크립트의 오류를 올바르게 지적했습니다. grep 명령을 실행할 때 쉘은 예상한 $servername_log_20150312
대로 변수를 찾지 않습니다 $servername
.
이를 상쇄하면 "$servername"
문제가 해결됩니다.
grep에 대한 입력에 예상되는 서버 이름이 모두 표시되기 때문에 grep이 이상하게 동작하는 것 같습니다. 그러나 이는 실제로 변수를 찾을 수 없고 $servername_log_20150312
기본적으로 전체 디렉터리를 검색하기 때문에 속임수입니다 . grep의 최대 매개변수 제한에 도달하기 전에 필요한 모든 서버 이름이 디렉토리에 나타난다는 사실은 실제 원인을 더욱 모호하게 만듭니다.