WSL 9P 安装上的 bash 中的星号全局扩展 (*) 出现意外行为

问题描述 投票:0回答:1

我仅在 9P 安装上的 WSL 中观察到脚本中的奇怪行为(Windows 磁盘,如

/mnt/c/...
)。

如果存在写入临时文件的管道,则

*

 循环中的星号 (
for
) 的全局扩展会导致下次调用时出现
重复

#!/bin/bash # save true file number true_f_num=$(for fn in *; do echo; done | wc -l) while :; do # count of iterations to outer loop pipe echo # save current file list in file echo -n '' >.list for fn in *; do echo "$fn" >>.list # line below causes unexpected behaviour # on 9P mounts (like /mnt/c/...) # (WSL2, ubuntu 22.04) done | cat > .tmp; rm .tmp # check [ $(cat .list | wc -l ) -ne $true_f_num ] && break done | wc -l
这里有一个脚本来测试和说明这一点。预计它将永远运行。但在 WSL 的 9P 安装上,它会在随机次数的迭代后停止。

我无法理解这个机制。我假设 glob 扩展发生一次,只有稍后它才开始传递到管道(子 shell)并更改目录的内容。这将如何影响下一次迭代?该文件曾经在那里,但现在已经不存在了。目录中是否出现了一些看不见的fifo?

请智者解释一下这里发生了什么。

bash pipe windows-subsystem-for-linux glob plan-9
1个回答
0
投票
[示例脚本]预计将永远运行。但在 WSL 的 9P 安装上,它会在随机次数的迭代后停止。

大概这是因为

[ $(cat .list | wc -l ) -ne $true_f_num ]

 在某些评估中评估为 true,事实上,您在注释中观察到,在脚本终止后,您会在留下的 
.list
 文件中发现重复的名称。  这样就可以了,除非你还漏掉了一个名字。

文件

.list

 的创建和填充方式如下:

echo -n '' >.list for fn in *; do echo "$fn" >>.list # [...] done | cat > .tmp

接下来是 
rm .tmp

,但这不是管理

.list
的一部分,并且直到上述管道完成后才会执行。 但是,由于
.tmp
在每次执行管道后都会被删除,因此可以合理地假设它在控制到达管道之前不存在。
因为

for

命令出现在管道中,所以它是在子shell中执行的。 其中的模式 (

*
) 在子 shell 中展开,在执行该命令之前
为每个文件生成一个单词。然后子shell的标准输出被重定向到管道中,最后,循环体对
*扩展中的每个单词执行一次。
同时,
cat

的标准输入从管道重定向,其标准输出被重定向到

.tmp

,如果需要,首先创建该文件,然后启动
cat
请注意,然后,相对于 
.tmp

命令中

*

 模式的扩展,何时创建 
for
 是未指定的,并且通常不可预测。  可能是之前、期间或之后。
观察:

默认情况下,路径名扩展会忽略名称以
    .
  • 开头的文件,除非

    .

     与模式显式匹配。  因此,在上述代码中,无论其创建的相对时间如何,
    .tmp
    预计不会出现在
    *
    的扩展中。

    在示例命令中,预计在执行循环体的任何迭代之前执行一次路径名扩展。
  • 它与 Bash 或 POSIX shell 的路径名扩展规范不一致,会产生重复的路径名。
  • 除非文件
  • .list
  • 同时被其他未披露的内容修改,否则其中出现重复行表明至少违反了前两个期望之一。

    这将是一个错误。

    
    
    

    在我看来,这样的错误很可能与在
  • .tmp
  • 命令中评估路径扩展期间不合时宜地创建文件

    for

     相关。  我可以想到至少一种可能导致此类问题的特定形式的实施缺陷。这当然是推测,但我认为这是合理的。
    
    

  • 这会如何影响下一次迭代?

我认为外循环的每次迭代都有其自己的独立机会来触发错误。 而且我认为这可能是路径名扩展中的一个错误,因此也不是内部循环的一次迭代影响另一次迭代的问题。

目录中是否出现一些不可见的fifo?

不太可能。

© www.soinside.com 2019 - 2024. All rights reserved.