정규식 검사 명령 매개변수

정규식 검사 명령 매개변수

grep실행 중인 명령에 해당 단어가 인수로 포함되어 있는지 확인하는 데 사용하고 싶습니다 . (나는 Bash에서 그것에 대해 알고 있지만 사용하고 싶지 않습니다).cmdname!*

이라는 변수에 명령이 있다고 가정해 보겠습니다 process.

처음에는 echo $process | grep 'cmd name'. 이는 하나의 매개변수만 고려하므로 완벽하지는 않습니다.

그래서 regex를 사용하여 마지막 매개변수로 캡처할 수 있는지 알아보려고 했습니다 cmd .*(?= )name. 아이디어는 무엇이든 캡처한 다음 공백과 name(다음 cmd)을 캡처하는 것입니다. 그러나 이것은 작동하지 않습니다.

이것이 효과가 있다면, 나의 목표는 그것을 어떤 입장에서든 논증으로 해석하려고 노력하는 것입니다.

정규식을 사용하여 이 작업을 어떻게 수행할 수 있나요?

답변1

아래 답변에서는 grep명령줄은 개별 항목의 목록이므로 텍스트 줄이 아닌 그대로 구문 분석해야 합니다.


명령과 명령의 인수를 모두 단일 문자열(바람직하게는 배열)에 저장한다고 가정합니다.변수에 저장된 명령을 어떻게 실행할 수 있나요?) 그러면 다음과 같은 작업을 수행할 수 있습니다.

process='cmd with "some arguments" and maybe name'

set -f
set -- $process

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

이렇게 하면 먼저 파일 이름 생성이 비활성화됩니다. 파일 이름 $process을 따옴표 없이 별도의 단어로 분할하고 문자열에 파일 이름 글로빙 패턴(예: *)이 포함되어 있으면 구문 분석이 엉망이 되기 때문입니다. 우리는 이런 일을 하곤 합니다 set -f.

그런 다음 위치 매개변수를 의 단어로 설정합니다 $process. 그 후에, 그렇다면 "$1"명령줄의 나머지 부분을 cmd살펴 봐야 한다는 것을 압니다. name그렇지 않다면 여기서 멈추겠습니다.

위치 매개변수 목록을 shift그대로 두고 매개 변수를 통해 반복을 시작합니다. cmd각 반복에서 우리는 단순히 인수를 문자열과 비교합니다 name. 그것을 찾으면, 우리는 말하고 그만둡니다.

루프가 끝나면 아직 매개변수를 찾지 못했다는 것을 알게 되므로 name이를 보고하고 실패로 종료합니다.

위의 예에서는 매개변수가 some arguments두 개로 구문 분석됩니다.분리strings "somearguments", 이것이 명령과 해당 인수를 단일 문자열에 저장하고 싶지 않은 이유 중 하나입니다. 이는 또한 name단일 매개변수 내에서 매개변수를 감지한다는 의미이며 "some name string", 이는 거짓양성(false positive)이 됩니다.


명령줄이 배열(예 bash: )에 저장되어 있는 경우 다음을 수행할 수 있습니다.

process=( cmd with "some arguments" and maybe name )

if [ "${process[0]}" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

for arg in "${process[@]:1}"; do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

확장은 "${process[@]:1}"전체 배열이지만 첫 번째 항목(명령 이름)은 아닙니다.

/bin/sh(and dash및 기타 POSIX 셸) 의 경우 bash위의 내용은 덜 장황합니다.

set -- cmd with "some arguments" and maybe name

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

이는 기본적으로 첫 번째 코드 조각과 동일하지만 명령줄의 모든 요소를 ​​단일 텍스트 문자열로 결합하지 않기 때문에 모든 인수(인용부호 등)를 올바르게 처리합니다.

답변2

bash를 언급했으므로 또 다른 옵션은 패턴 일치 연산자입니다 =~.

if [[ $process =~ ^cmd[[:space:]].*name([[:space:]]|$) ]]
then
  _name_ was found as an argument to _cmd_
fi

cmd이는 변수의 내용이 로 시작 하고 공백이 뒤따르고 아무것도 뒤따르지 않거나 아무것도 뒤따르지 않고 name공백 또는 줄 끝이 뒤 따르는 지 확인합니다 .

관련 정보