Linux 换行符在ls-Q中没有正确引用

Linux 换行符在ls-Q中没有正确引用,linux,bash,sh,ls,quoting,Linux,Bash,Sh,Ls,Quoting,使用ls-Q和--quoting style=shell,将文件名中的换行符(是的,我知道…)转换为?。这是虫子吗?有没有一种方法可以让文件名的格式与shell 100%兼容(如果可能的话是sh或bash) 示例(bash): 可能不是您想要的,但是“escape”样式似乎与bash4.4中即将到来的${…@E}参数扩展配合得很好 $ touch $'a\nb' $'c\nd' $ ls -Q --quoting-style=escape ??? | while IFS= read -r fna

使用
ls-Q
--quoting style=shell
,将文件名中的换行符(是的,我知道…)转换为
。这是虫子吗?有没有一种方法可以让文件名的格式与shell 100%兼容(如果可能的话是sh或bash)

示例(bash):


可能不是您想要的,但是“escape”样式似乎与
bash
4.4中即将到来的
${…@E}
参数扩展配合得很好

$ touch $'a\nb' $'c\nd'
$ ls -Q --quoting-style=escape ??? | while IFS= read -r fname; do echo =="${fname@E}==="; done
==a
b==
==c
d==
以下是链接的相关部分(链接到原始源):

${parameter@operator}
参数转换。扩展要么是一个转换,要么是一个-
参数的值或有关参数的信息的设置
本身,取决于运算符的值。每个操作员都是一个
单字母:
Q扩展是一个字符串,它是参数的值
以可重复用作输入的格式引用。
扩展是一个字符串,它是参数的值
将反斜杠转义序列扩展为
$“…”引用mechansim。
P展开是一个字符串,它是展开的结果
参数的值,就像它是提示字符串一样(请参见
(见下文)。
扩展是赋值形式的字符串
语句或声明命令,如果对其求值,将
重新创建参数及其属性和值。
扩展是一个由标志值rep组成的字符串-
重新指定参数的属性。
如果参数为@或*,则操作将应用于每个posi-
参数,展开式是结果
列表If参数是以@或下标的数组变量
*,则案例修改操作将应用于
数组依次展开,展开部分是结果列表。
扩展的结果会被分词和删除
路径名扩展,如下所述。

通过一些实验,它看起来像是
--quoting style=escape
与被包装在
$'…
中是兼容的,但有两个例外:

  • 它通过预加反斜杠来逃避空格;但是,
    $“…”
    不会在空格之前放弃反斜杠
  • 它不会转义单引号
因此,您可以这样写(在Bash中):

为了测试这一点,我创建了一个目录,其中包含一堆带有奇怪字符的文件名;及

eval ls -l $(ls-quote-shell)
按计划工作。尽管我不会对此做出任何坚定的保证

或者,这里有一个版本,它使用
printf
处理转义,然后使用
printf%q
以shell友好的方式重新转义:

function ls-quote-shell () {
    ls -Q --quoting-style=escape "$@" \
    | while IFS= read -r escaped_filename ; do
        escaped_filename="${escaped_filename//'\ '/ }"  # unescape spaces
        escaped_filename="${escaped_filename//'%'/%%}"  # escape percent signs
        # note: need to save in variable, rather than using command
        # substitution, because command substitution strips trailing newlines:
        printf -v filename "$escaped_filename"
        printf '%q\n' "$filename"
      done
}

但是如果第一个版本不能正确处理某些情况,那么第二个版本很可能也会有同样的问题。(FWIW,
eval ls-l$(ls quote shell)
在这两个版本中都按预期工作。)

coreutils 8.25具有新的“shell转义”引用样式,事实上,默认情况下它允许ls的输出始终可用,并且可以安全地复制并粘贴回其他命令。

--quoting style=“escape”
--quoting style=“c”
应该能用…@l'l'l:不行
eval ls$(ls-Q--quoting style=escape)
产生
ls:无法访问anb:没有这样的文件或目录
,因此它不会往返。如果没有
eval
,它也无法工作。
c
可能是您的最佳选择。。。而且,每当你在子shell中求值ls,那么ls就会得到奇怪的结果。@l'l'l,
--quoting style=shell
的整个要点就是生成一些
eval
可以正确解析的东西。这是一个明显的错误。@charlesduff:报告为。我找不到解释,你有链接吗?我找不到;我将复制手册页的相关部分。这也是我从错误报告中得到的。不幸的是,我的箱子上还有8点22分和8点23分。
eval ls -l $(ls-quote-shell)
function ls-quote-shell () {
    ls -Q --quoting-style=escape "$@" \
    | while IFS= read -r escaped_filename ; do
        escaped_filename="${escaped_filename//'\ '/ }"  # unescape spaces
        escaped_filename="${escaped_filename//'%'/%%}"  # escape percent signs
        # note: need to save in variable, rather than using command
        # substitution, because command substitution strips trailing newlines:
        printf -v filename "$escaped_filename"
        printf '%q\n' "$filename"
      done
}