프로그램이 두 줄 이상을 반환하면 파이프 종료

프로그램이 두 줄 이상을 반환하면 파이프 종료

패턴별로 데이터베이스 이름을 찾기 위해 mysql db를 쿼리하고 있습니다. 현재 내 구현은 다음과 같습니다.

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
    | paste -sd ",")

패턴과 일치하는 데이터베이스 이름의 쉼표로 구분된 목록이 반환됩니다.

그러나 실제로는 하나의 데이터베이스 이름만 반환될 것으로 예상하고 mysql이 2줄의 결과를 반환할 때 오류를 발생시키는 것이 더 나을 것이라고 생각합니다.

다음과 같은 것이 있습니까?

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
    | __error_if_two_lines__ )

답변1

head첫 번째 줄을 추출하는 데 사용할 수 있습니다 .

include_databases=$(… | head -n 1)

그러나 이는 추가 행을 자동으로 무시합니다. 더 많은 줄이 있는 경우 대신 awk를 사용하여 다른 종료 코드를 반환할 수 있습니다.

include_databases=$(… | awk 'NR>1 {exit(2)} 1')
if [ $? -ne 0 ]; then
  echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
fi

또는 아래에서 set -e:

include_databases=$(… | awk 'NR>1 {print "mysql returned multiple lines! Aborting." >"/dev/stderr"; exit(2)} 1')

또는 출력을 변수에 저장하고 줄 바꿈이 포함되어 있는지 테스트할 수 있습니다. (명령의 마지막 개행 문자는 명령 대체에 포함되지 않습니다.)

include_databases=$(…)
nl='
'
case $include_databases in
  *"$nl"*) echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac

ksh/bash/zsh에서는 일반 sh가 아닌 더 간결한 방식으로 작성할 수 있습니다.

include_databases=$(…)
if [[ "$include_databases" = *$'\n'* ]]; then
  echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac

답변2

내 생각엔 wc당신의 친구인 것 같아요. -l줄 수, 단어 수를 계산 하려면 옵션을 사용하세요 -w. (맨 페이지 참조)

mysql --batch --skip-column-names --execute "SHOW DATABASES" | wc -w

데이터베이스 수를 표시합니다.

예를 들어 이런 것

include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES")
numDB=$(echo $include_databases | wc -w)
[ $numDB -gt 1 ] && echo -n "$numDB dbs is more than "
echo "one db"

힌트: 이 스크립트는 많은 하위 쉘을 사용하므로 개선해야 합니다.

관련 정보