test(1)
매뉴얼 페이지 에 따르면 :
-n STRING
the length of STRING is nonzero
그래서 나는 이것이 잘 작동할 것이라고 기대했습니다.
[ -n ${var} ] && echo "var is not empty"
이 로직을 실제 사례에서 사용했는데, 스크립트는 다음과 같습니다.
[...]
dne() {
echo DEBUG: wc -c: $(echo -n $peopkg |wc -c)
echo DEBUG: pdir: $pdir
echo "Error: ${package}: doesn't exist in local repos"
exit 1
}
# packages are listed as such:
# p/pname/package-version-release-distrelease...
# pname is inconsistent, but it is guaranteed that the first word in package
# (all to lowercase) will match at least one pname.
# NOTE: package-[0-9]* matches package-32bit. *-32bit is a subpackage we want
# to match later, but not when it's not already in pcase.
# So that must be negated too
pfirst=${pcase%%-*}
for pdir in ${p}/${pfirst}*
do
# check if the glob matched anything at all
[ ${pdir} = "${p}/${pfirst}*" ] && dne
peopkg=$(find ${pdir} \
-name ${package}-[0-9]* \
! -name *.delta.eopkg \
! -name ${package}-32bit* |sort -rn |head -1)
echo DEBUG: in-loop peopkg: $peopkg
echo DEBUG: in-loop wc -c: $(echo -n $peopkg |wc -c)
echo DEBUG: in-loop test -n: $(test -n $peopkg && echo true || echo false)
#------------------------------------------------------------#
# break on ANY match. There's supposed to be only one anyway #
[ -n ${peopkg} ] && break # <--- [issue here] #
#------------------------------------------------------------#
done
[ -z ${peopkg} ] && dne
[...]
여기서 중요한 점은 실행하면 다음과 같은 메시지가 나타난다는 것입니다.
DEBUG: in-loop peopkg:
DEBUG: in-loop wc -c: 0
DEBUG: in-loop test -n: true
DEBUG: wc -c: 0
DEBUG: pdir: a/alsa-firmware
Error: alsa-utils: doesn't exist in local repos
이것은 나에게 이해가 되지 않습니다. DEBUG: pdir: a/alsa-firmware
루프가 항상 첫 번째 반복에서 종료됨을 나타냅니다. 이는 glob 패턴 a/alsa*가 무언가와 일치하고 peopkg의 길이가 0이 아닌 경우에만 발생합니다.
추신: 저는 POSIX 호환성을 연구 중입니다.
답변1
var
빈 문자열이 포함된 경우 ( [ -n $var ]
토큰화 후 $var
) 단어로 확장 됩니다 [
. 이는 단일 매개변수가 null이 아닌지 테스트하는 의 단일 매개변수 버전입니다 . 문자열이 비어 있지 않으므로 테스트는 true입니다.-n
]
test
-n
GNU 매뉴얼 페이지에서는 인용한 단락 뒤에 이 내용이 언급되어 있습니다.
-n STRING
the length of STRING is nonzero
STRING equivalent to -n STRING
물론 문제는 인용이 부족하다는 것입니다.공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?그리고언제 큰따옴표가 필요합니까?
따옴표가 없으면 빈 문자열만 손상되는 것이 아닙니다. var
여러 단어가 포함된 경우에도 문제가 발생할 수 있습니다.
$ var='foo bar'; [ -n $var ]
bash: [: foo: binary operator expected
또는 와일드카드:
$ var='*'; [ -n $var ]
bash: [: file.txt: binary operator expected
답변2
-n
따옴표가 없는 변수에는 작동하지 않습니다.
맨페이지에 표시된 대로 -n
0이 아닌 길이를 테스트합니다.끈.
따라서 변수를 사용하여 null로 확장되는지 테스트할 때 변수를 참조해야 합니다.
그래서 이 문제의 해결책은[ -n "${peopkg}" ]
답변3
예, 비어 있지 않은 문자열이 없는 것 같습니다. 그러나 값에 공백이 있으므로 변수를 인용해야 합니다.
예를 들어
a="hello, world"
b=""
test -n "$a"
test -n "$b"