실행 된 명령의 출력을 일반적으로 테스트 할 수있는 Bash 함수를 작성하는 방법은 무엇입니까?

vitus37

명령을 문자열과 검색 바늘로 전달할 수있는 작은 Bash 함수를 작성하고 싶습니다. 명령의 실행 출력에 주어진 검색 바늘이 포함되어 있으면 "OKAY", 그렇지 않으면 "ERROR"를 인쇄해야합니다.

그것이 내가 지금까지 생각 해낸 것입니다.

red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

function psa_test {
  result=$($1 2>&1)
  echo "Result: $result"
  if [[ $result == *"$2"* ]]; then
    echo "[${green} OK  ${reset}] $3"
  else
    echo "[${red}ERROR${reset}] $3"
  fi
  echo "        Command: '$1' | Needle: '$2' | Name: '$3'"  
}

그렇게 불러 내면

psa_test 'curl -v google.com' "HTTP 1.1" "Testing google.com"

아름답게 작동합니다.

# .. output
[ OK  ] Testing google.com
            Command: 'curl -v google.com' | Needle: 'HTTP 1.1' | Name: 'Testing google.com'

그러나 명령에 포함 된 문자열이 있으면 더 이상 작동하지 않습니다. 예 :

psa_test 'curl --noproxy "*" http://www1.in.example.com' "HALLO 1" "HTTP www1.in.example.com"

산출:

# Proxy answers with HTML error document ... <html></html> ... saying
# that it can't resolve the domain (which is correct as 
# it is an internal domain). But anyway, the --noproxy "*" option 
# should omit all proxies!
[ERROR] HTTP www1.in.example.com
        Command: 'curl --noproxy "*" http://www1.in.example.com' | Needle: 'HALLO 1' | Name: 'HTTP www1.in.example.com'

내가 실행하면

curl --noproxy "*" http://www1.in.example.com

내 셸에서 (우리가 원하는) 프록시를 무시하지만

curl --noproxy * http://www1.in.example.com

하지 않습니다.

.NET을 사용하여 MySQL 데이터베이스를 테스트하려고하면 비슷한 동작이 발생합니다 mysql -u ... -p ... -e "SELECT true". 그래서 따옴표와 관련이 있다고 생각합니다. 누군가가이 기능을 개선하기위한 힌트를 줄 수 있다면 기쁠 것입니다. 감사!

프레드

전체 명령을 단일 문자열로 제공하려면 모든 종류의 불편한 방법으로 인용해야합니다. 필요하지 않은 약간 다른 접근 방식을 시도해 볼 것을 제안합니다.

#!/bin/bash
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

psa_test()
{
  local needle="$1"
  local name="$2"
  local -a command=("${@:3}")
  local result ; result=$("${command[@]}" 2>&1)
  echo "Result: $result"
  if
    [[ $result == *$needle* ]]
  then
    echo "[$green OK  $reset] $name"
  else
    echo "[$red ERROR $reset] $name"
  fi
  echo "        Command: ${command[@]} | Needle: $needle | Name: $name"
}

그런 다음 대화 형 쉘에서 호출하는 것과 똑같이 명령을 인용되지 않은 문자열로 전달하여 함수를 호출 할 수 있지만 앞에 두 개의 인수를 넣습니다.

psa_test "HTTP/1.1" "Testing google.com" curl -v google.com

몇 가지 참고 사항 :

  • 명령은 배열에 저장되고 단어 분할을 방지하기 위해 개별적으로 인용 된 모든 요소를 ​​확장하여 실행됩니다 "${command[@]}".

  • 배열 확장을 둘러싼 큰 따옴표는 셸이 배열 요소 당 한 단어 씩 배열을 확장하도록 지시하고 각 배열 요소 내에서 단어 분할이 발생하지 않도록하기 때문에 매우 중요합니다 (예 : 공백을 포함하는 배열 요소를 허용하기 위해).

  • 함수 내에서 변수를 로컬로 선언해야합니다. 꼭 필요한 것은 아니지만 같은 이름의 변수를 가진 여러 함수가있을 때 스크립트를 디버그하기 쉽고 불쾌한 실패 모드에 덜 취약합니다.

  • "HTTP / 1.1"이 원하는 검색 문자열이라고 생각합니다.

  • 성능이 문제가되는 경우 데이터에 가장 적합한 텍스트 일치 방식 (예 : Bash regexes =~, grep)을 시도 해야합니다.

위의 스크립트는 다음과 같이 단순화 될 수 있습니다.

  • 교체 local -a command=("${@:3}")shift 2
  • 사용 "${command[@]}"되는 "$@"모든 곳에서 교체

이 경우 말이 되겠지만, 스크립트에서 종종 유용하기 때문에 명령을 배열로 빌드하는 방법을 설명하기 위해이 기회를 사용했지만, 간단한 경우에는 위치 인수를 사용하는 것이 매우 잘 작동하고 가독성이 향상되었습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관