【问题标题】:Apply setCaseSensitiveInfo recursively to all folders and subfolders将 setCaseSensitiveInfo 递归应用到所有文件夹和子文件夹
【发布时间】:2018-07-30 09:40:20
【问题描述】:

我正在尝试将我的 dotnet 核心项目(在 Windows 中)配置为“区分大小写”,因此它的行为就像在我的生产服务器 (linux) 中一样。

我有 found this way 这样做:

fsutil.exe file setCaseSensitiveInfo "C:\my folder" enable

问题是这个函数不是递归的:

区分大小写标志只影响您应用它的特定文件夹。该文件夹的子文件夹不会自动继承它。

所以我正在尝试构建一个 powershell 脚本,以递归方式将其应用于所有文件夹和子文件夹。

我尝试过用谷歌搜索类似的东西,只是修改了命令行,但我似乎没有找到正确的关键字。这是the closest that I've gotten 这类示例。

【问题讨论】:

  • (gci -Recurse -Directory).FullName | % {fsutil.exe file setCaseSensitiveInfo $_ enable}(没有 Windows 10 来测试它)
  • @robdy 这是正确答案。谢谢。它回答“setCaseSensitiveInfo 是一个无效参数”,但这是 Window7 的错……我用(gci -Recurse -Directory).FullName | % {echo $_} 测试了你的脚本,它就像一个魅力。
  • 遗憾的是,虽然上述方法曾经有效,但微软现在已经向 fsutil 添加了一个“功能”,它将不再允许您在非空目录上设置区分大小写。现在,当您尝试将上述内容应用于具有子目录的目录时,您将得到一堆这样的:错误:目录不是空的。

标签: powershell


【解决方案1】:

正确代码:

(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}

解释:

注意:答案中的代码假定您位于目录树的根目录中,并且您想对里面的所有文件夹运行 fsutil.exe,正如 cmets 中所指出的那样(感谢@Abhishek Anand!)

Get-ChildItem -Recurse -Directory 将为您提供所有文件夹的列表(递归)。

当你想传递他们的完整路径时,你可以使用.FullName[1](或更不言自明的| Select-Object -ExpandProperty FullName)来访问它。

然后你使用ForEach-Object 多次运行fsutil.exe。当前文件的FullName 可以使用$_ 访问(这表示ForEach-Object 中的当前对象)[2]

提示:

如果您想更多地跟踪当前正在处理的内容,您可以添加以下内容以将当前处理的文件的路径写入控制台:; Write-Host $_(分号;fsutil 调用分开)原样在 cmets 中指出(感谢Fund Monica's Lawsuit !)


[1] .FullName 表示法适用于 PowerShell 3.0 及更高版本,如果有可能使用较低版本,则首选 Select-Object -ExpandProperty FullName

[2] $_$PSItem 的别名

【讨论】:

  • 第一个 cd 到需要区分大小写的目录树的根目录。
  • 如果您想更深入地了解问题发生的位置,您可以在 { 之后添加一个 echo $_; ,它会在执行任何操作之前打印出当前正在运行的内容.
  • 我收到.FullName was unexpected at this time. 怎么了?
  • 检查Get-ChildItem的输出。你运行它的目录可能是空的
  • 两件事:使用 (Get-ChildItem foldername -Recurse -Directory).Fullname | ForEach-Object {fsutil file setCaseSensitiveInfo "$_" enable} 并将 foldername 替换为您要使用的文件夹。其次,确保你打开了一个管理员 shell,另外我发现,如果一个文件夹已经包含了一些东西,它显然是行不通的;我收到The direcotry is not empty 错误。
【解决方案2】:
(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {if (-Not ($_ -like '*node_modules*')) { fsutil.exe file setCaseSensitiveInfo $_ enable } }

我修改了@robdy 的代码以允许排除node_modules。您可以将上面的“node_modules”位替换为任何内容以排除包含它的文件路径。

如果您正在使用 npm,您可能希望排除 node_modules。 @robdy 的 answer 很棒,但是即使我没有安装包,每次迭代每个节点包文件夹也需要几分钟时间;考虑到这是一个可能需要经常运行的东西,因为可能会一直添加目录,而且您可能没有修改 node_modules 中的任何内容,排除它似乎是合理的。

【讨论】:

  • 请注意,在区分大小写的目录下创建的子目录是区分大小写的,因此您永远不需要在该目录上再次运行此脚本。
  • node_modules 是我需要此命令的有问题的目录。
  • @eric.green 我认为这不是真的。 From Microsoft: "请注意,每个目录的区分大小写标志不会被继承;在区分大小写的目录中创建的目录本身不会自动区分大小写。您必须明确将每个目录标记为区分大小写。"
  • 原来我的 jenkins 构建问题来自 node_modules 中的一个库并被 Windows 隐藏,但炸毁了我在类型敏感的 linux 系统上构建的 jenkins 管道,所以我不建议忽略 node_modules 中的大小写跨度>
【解决方案3】:

使用 Cygwin 和 bash shell,您可以这样做:

$ find $THEDIR -type d -exec fsutil file setCaseSensitiveInfo "{}" enable \;

Windows 似乎可以很好地处理 find 命令输出的“/”字符。

【讨论】:

    【解决方案4】:

    就我而言,我必须先启用 Linux 子系统,然后才能使用 fsutil 工具。所以我的步骤是:

    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    

    然后重启,然后@robdysolution

    (Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-03
      • 2016-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2018-10-16
      • 2018-11-12
      相关资源
      最近更新 更多