NUL로 구분된 입력을 처리할 때 bash가 mapfile
손상된 것 같습니다. 특히 -
빼기 문자( )를 올바르게 처리하지 못하고 1 뒤의 빈 문자열을 줄 끝 표시로 처리합니다.
예를 들어:
#!/bin/bash
mkdir /tmp/junk
cd /tmp/junk
touch a.txt b.txt c.txt d-e-f.txt
declare -a files
echo "mapfile using default \\n delimiter"
mapfile -t files < <(find . -maxdepth 1 -type f -name '*.txt')
typeset -p files
echo
echo "mapfile using NUL delimiter"
mapfile -d'' -t files < <(find . -maxdepth 1 -type f -name '*.txt' -print0)
typeset -p files
echo
echo "and again"
mapfile -d$'\0' -t files < <(find . -maxdepth 1 -type f -name '*.txt' -print0)
typeset -p files
$ ./test.sh
mapfile using default \n delimiter
declare -a files=([0]="./d-e-f.txt" [1]="./a.txt" [2]="./c.txt" [3]="./b.txt")
mapfile using NUL delimiter
declare -a files=([0]="./d-" [1]="e-" [2]="f.txt")
and again
declare -a files=([0]="./d-" [1]="e-" [2]="f.txt")
이것은 버그입니까? 아니면 중요한 것을 잊어버리고 잘못하고 있는 걸까요?
매핑 파일 항목은 다음과 man bash
같습니다.
-d
delim의 첫 번째 문자는 개행 문자가 아닌 각 입력 행을 종료하는 데 사용됩니다. delim이 빈 문자열인 경우 mapfile은 NUL 문자를 읽을 때 줄을 종료합니다..
배쉬 버전은 5.1.8(1)-release
다음 과 같습니다
$ bash --version
GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
고쳐 쓰다
더 이상한 점은 배열의 기존 요소가 이미 존재하는 경우(위에 표시된 대로) 파괴하는 것처럼 보이지만, 존재하지 않는 경우에는 생성하지도 않는다는 것입니다.
$ unset files
$ mapfile -t -d'' files < <(find . -maxdepth 1 -type f -name '*.txt' -print0)
$ typeset -p files
-bash: typeset: files: not found
답변1
명시적 빈 인수(
""
또는''
)는 유지되어 빈 문자열로 명령에 전달됩니다. [...] 단어는 토큰화 및 빈 인수 제거 후에-d''
됩니다 .-d
args
매개변수 처리 문제를 해결하려면 도구 상자에 쉘 스크립트가 있으면 도움이 될 수 있습니다. 가능한 구현은 다음과 같습니다.
#!/bin/sh
printf "%d args:" "$#"
test "$#" -gt 0 && printf " <%s>" "$@"
echo
# Source:
# https://lists.gnu.org/archive/html/help-bash/2021-07/msg00044.html
시도 해봐 mapfile -d'' -t files
:
$ args mapfile -d'' -t files
4 args: <mapfile> <-d> <-t> <files>
옵션에 전달된 것으로 생각한 NUL이 -d
존재하지 않는 것을 확인합니다. 이 옵션에 대한 인수는 -d
명령줄의 다음 인수입니다: -t
!
-d
옵션에 대한 문서mapfile
[협회]설명하다:
첫 번째 문자Delim각 입력 라인을 종료하는 데 사용됩니다.
의 첫 번째 문자 -t
는 입니다 -
.
따라서 다음 두 호출은 동일합니다.
mapfile -d'' -t files
mapfile -d '-' files
이것은 귀하가 겪고 있는 결과를 설명합니다.