데이터베이스 이름을 얻기 위해 스키마로 mysql 데이터베이스를 쿼리하고 있습니다. 현재 구현은 다음과 같습니다.
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"
팁: 이 스크립트는 많은 하위 쉘을 사용하므로 개선해야 합니다.