grep
실행 중인 명령에 해당 단어가 인수로 포함되어 있는지 확인하는 데 사용하고 싶습니다 . (나는 Bash에서 그것에 대해 알고 있지만 사용하고 싶지 않습니다).cmd
name
!*
이라는 변수에 명령이 있다고 가정해 보겠습니다 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 "some
및 arguments"
, 이것이 명령과 해당 인수를 단일 문자열에 저장하고 싶지 않은 이유 중 하나입니다. 이는 또한 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
공백 또는 줄 끝이 뒤 따르는 지 확인합니다 .