나는 일부 쉘이 이런 종류의 테스트를 허용한다는 것을 알고 있습니다.
t() { [[ $var == *$'\n'* ]] && res=yes || res=no
printf '%s ' "$res";
}
var='ab
cd'
t
var='abcd'
t
echo
실행 시:
$ bash ./script
yes no
POSIX에 해당하는 작업은 무엇입니까(대시)
다음 테스트 방법은 신뢰할 수 있습니까?
nl=' ' t() { case "$var" in *$nl* ) res=yes ;; * ) res=no ;; esac printf '%s ' "$res" } var='ab cd' t var='abcd' t echo
답변1
변수에 새 줄을 넣고 패턴 일치를 수행할 수 있습니다 case
.
$ cat nl.sh
#!/bin/sh
nl='
'
case "$1" in
*$nl*) echo has newline ;;
*) echo no newline ;;
esac
$ dash nl.sh $'foo\nbar'
has newline
$ dash nl.sh $'foobar'
no newline
줄 바꿈을 만드는 또 다른 방법은 다음과 같습니다.
nl=$(printf "\nx"); nl=${nl%x}
명백한 명령 대체는 대체가 후행 줄 바꿈을 제거하기 때문에 작동하지 않습니다.
답변2
예,
nl='
'
case $var in
(*"$nl"*) echo yes;;
(*) echo no;;
esac
case
(원칙적으로 패턴으로 처리되기를 원하지 않는 한 패턴 내에서 모든 변수 확장을 인용하고 싶습니다 . 하지만 여기서는 $nl
와일드카드가 포함되지 않기 때문에 차이가 없습니다.)
또는
case $var in
(*'
'*) echo yes;;
(*) echo no;;
esac
모든 것이 잘 작동하고 POSIX와 호환되어야 하며 이것이 제가 사용할 것입니다. s를 제거하면 (
이전 Bourne 쉘에서도 작동합니다 .
변수를 설정하는 $nl
또 다른 방법 :
eval "$(printf 'nl="\n"')"
알아채다$'\n'
POSIX 표준의 다음 버전에 포함될 예정. 최소한 ksh93
, zsh
, bash
, mksh
busybox 및 FreeBSD에서 지원됩니다(2018년 2월 기준).sh
보유한 테스트가 충분한지 여부에 대해 두 경우 모두 테스트했으므로 모든 코드 경로가 테스트됩니다.
현재 POSIX 사양에 명시적으로 지정되지 않은 사항은 *
유효한 문자를 형성하지 않는 바이트 시퀀스가 포함된 문자열을 일치시킬지 여부 또는 쉘 변수에 이러한 문자열을 포함할 수 있는지 여부입니다.
실제로 변수는 문자만 포함할 수 있다는 점을 제외하면 yash
NUL 바이트(셸이 가능하지 않지만 zsh
변수에 저장할 수 있음) 이외의 *$nl*
문자열을 포함하는 $nl
문자열은 유효한 바이트 시퀀스를 형성하지 않는 문자가 포함되어 있더라도 일치해야 합니다( UTF-8 과 같은 $'\x80'
).
예를 들어 일부 find
구현은 -name "*$nl*"
일치하지 않으므로 새 셸을 테스트하고 텍스트(예: 파일 이름)가 보장되지 않는 항목을 처리하려는 경우 이에 대한 테스트 사례를 추가할 수 있습니다. . 다음과 같이:
test=$(printf '\200\n\200')
UTF-8 로케일.