Bash
bash mapfile NUL 錯誤?
在處理 NUL 分隔輸入時, bash
mapfile
似乎被破壞了。特別是,它沒有-
正確處理減號 ( ),將一個後面的空字元串視為行尾標記。例如:
#!/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 字元時終止一行。bash 版本是
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
顯式空參數 (
""
或''
) 被保留並作為空字元串傳遞給命令。$$ … $$該詞在分詞和刪除空參數後
-d''
變為。-d
args
在您的工具箱中有一個 shell 腳本來解決參數處理問題會很有幫助。這是一種可能的實現:#!/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>
我們看到我們認為我們傳遞給
-d
選項的 NUL 不存在。選項的參數-d
是命令行中的下一個參數:-t
!
-d
選項的文件mapfile
$$ link $$說:delim的第一個字元用於終止每個輸入行
的第一個字元
-t
是-
。因此這兩個呼叫是等價的:
mapfile -d'' -t files mapfile -d '-' files
這解釋了您所經歷的結果。