【问题标题】:Convert Windows file format to Linux format将 Windows 文件格式转换为 Linux 格式
【发布时间】:2017-10-25 07:31:28
【问题描述】:

我使用 Linux 机器进行开发,然后将我的脚本文件部署到 Windows 机器 Azure 函数应用程序。

然后我将 shell 脚本文件从 Azure 函数应用程序复制到 wasb。

在 Azure HDI 集群的 Edge 节点中运行 shell 脚本时出现以下错误

$'\r': command not found

我的脚本文件没有正确执行。

在 C# Azure 函数中转换 dos2unix 选项的最佳方法是什么?

【问题讨论】:

  • 你使用记事本++吗?在 Windows 上创建文件时,可以选择 Unix 类型。
  • @Walter-MSFT 我没有使用 Windows 机器。我正在将文件从 github 复制到 Azure 函数,然后再复制到 WASB。文件存储在 Windows 机器 Azure 函数应用程序中。我正在将文件从 Linux 机器推送到 github。我需要一种自动化的方法,而不是手动的。
  • 没有Linux File FormatWindows File Format 这样的东西。 text files 的换行符在两个操作系统上是不同的,但 C# 两者都适用。 Linux 中的换行符是\n。在 Windows 中,它是 \r\n。两者都不使用\r

标签: c# linux azure azure-functions


【解决方案1】:

您无需执行任何特殊操作即可读取包含 Unix 样式换行符 (\n) 而不是 \r\n 的文件。 .NET IO 方法将两者都视为换行符。

你可以写

var lines-File.ReadAllLines("myUnixText.txt");

using(var reader=File.OpenText("myUnixText.txt"))
{
    string line;
    while( (line=reader.ReadLine()) !=null)
    {
        // Do something
    }
}

读取行结尾是\r还是\n

证明它:

var numbers = new[]{1,2,3,4,5,6};
var lines=String.Join("\n",numbers);
File.WriteAllText("myUnixText.txt",lines);

var newLines=File.ReadAllLines("myUnixText.txt");

Debug.Assert(newLines.Length==6);

即使只写入了一个单个字符串,File.ReadAllLines 从文件中读取了 6 行

【讨论】:

    【解决方案2】:

    您可以将文件上传到 Linux 并更改文件格式。

    dos2unix <filename>
    

    另一个简单的解决方案是,如果你安装 Notepad++,它支持自动转换格式到 Unix(LF)。

    【讨论】:

    • 或者没有。只需使用File.OpenText(filePath)。 TextReader 处理 \n 就好了
    • Visual Studio 和 Visual Studio Code 也适用于 \n。事实上,如果文件包含不一致的换行符,你甚至会收到来自 VS 的警告
    • @PanagiotisKanavos 谢谢,我会试试这个,我更喜欢在以前的脚本开发中使用 Notepad++。
    【解决方案3】:

    我在将文件从 Azure 函数复制到 WASB 之前调用 Dos2Unix(filePath) 方法。

    调用方法:-

    Dos2Unix(D:\home\site\repository\sample.sh);
    

    以下方法在 C# Azure 函数中实际上对我有用。

    private void Dos2Unix(string fileName)
    {
        const byte CR = 0x0D;
        const byte LF = 0x0A;
        byte[] data = File.ReadAllBytes(fileName);
        using (FileStream fileStream = File.OpenWrite(fileName))
        {
            BinaryWriter bw = new BinaryWriter(fileStream);
            int position = 0;
            int index = 0;
            do
            {
                index = Array.IndexOf<byte>(data, CR, position);
                if ((index >= 0) && (data[index + 1] == LF))
                {
                    // Write before the CR
                    bw.Write(data, position, index - position);
                    // from LF
                    position = index + 1;
                }
            }
            while (index >= 0);
            bw.Write(data, position, data.Length - position);
            fileStream.SetLength(fileStream.Position);
        }
    }
    

    更新 1:-

    这是我将文件(*.sh、*.jar、*.img 等)上传到 blob 存储的代码。

    public bool UploadBlobFile(string containerName, string blobName, string filePath)
    {
    
        try{
            CloudBlobContainer container = blobClient.GetContainerReference(containerName);
            CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
            // convert dos2unix format
            Dos2Unix(filePath);
            using (var fileStream = System.IO.File.OpenRead(filePath))
            {
                blob.UploadFromStream(fileStream);
            }
            return true;
        } catch (Exception e) {
            log.Info("Exception: " + e);
            return false;
        }
    }
    

    【讨论】:

    • 不要这样做,试试简单的File.OpenText(fileName)。你会看到 TextReader 可以很好地处理\n
    • 或写File.ReadAllLines(fileName) 将所有行作为一个数组。您不需要任何此代码
    • @PanagiotisKanavos 使用 File.OpenText(fileName) 或 File.ReadAllLines(fileName) 后该怎么办?因为目前我正在使用此代码上传 blob 文件。 Dos2Unix(文件路径);使用 (var fileStream = System.IO.File.OpenRead(filePath)) { blob.UploadFromStream(fileStream); }
    • 您根本不需要Dos2Unix 方法。你不需要做任何事情。正如我在回答中所展示的,.NET 可以很好地处理\n。您确实 使用了c# 标记,所以我假设您的脚本是一个C# 文件。事实上,您应该发布您的 实际 代码,而不是错误消息
    • @PanagiotisKanavos 我已经更新了代码。你能告诉我我应该修改上面的代码吗?
    【解决方案4】:

    您似乎有 Windows 样式的行尾 (\r\n) - 您需要将它们更改为 unix 样式 (\n)。

    参考:'\r': command not foundConvert DOS line endings to Linux line endings in vim

    【讨论】:

      【解决方案5】:

      sourceforge 中有一个工具可以做到。 是最近实现了一个很好的运行。

      【讨论】:

        猜你喜欢
        • 2012-08-31
        • 2016-06-14
        • 2021-10-15
        • 2021-06-02
        • 2021-12-08
        • 1970-01-01
        • 1970-01-01
        • 2016-06-08
        相关资源
        最近更新 更多