1. 程式人生 > 其它 >Windows和Linux的不同換行符導致指令碼執行異常

Windows和Linux的不同換行符導致指令碼執行異常

問題描述

有一個配置檔案 config:

KAFKA_HOME=/home/wy/dev/kafka_2.13-2.6.0
BOOTSTRAP_SERVER=127.0.0.1:9092

另有一個使用該配置檔案的指令碼 list-topics.sh:

#!/bin/bash
. config

"$KAFKA_HOME"/bin/kafka-topics.sh --bootstrap-server "$BOOTSTRAP_SERVER" --list

我使用虛擬機器Ubuntu掛載Windows分割槽,執行在Windows環境下編寫的指令碼,提示:

wy@ship:/mnt/hgfs/D/projects/kafka-mate/scripts$ ./list-topics.sh 
/bin/kafka-topics.sh: No such file or directory13-2.6.0

解決

找了好久的原因,最終注意到config檔案的換行符編碼為CRLF

三種換行符(line separator):

  • Windows:CRLF(\r\n)
  • Unix and macOSLinux:LF(\n)
  • CLassic Mac OS:CR(\r),少見

改為LF後,指令碼執行正常。我用的IDEA,在右下角更改:

vim狀態列的[noeol] [dos]是什麼意思?

當config的line separator問CRLF時,vim開啟Windows分割槽上的檔案時,狀態列顯示[noeol][dos]

當config的line separator問LF時,vim開啟Windows分割槽上的檔案時,狀態列顯示[noeol]

noeol:no end of line。

如果是Linux分割槽上的檔案,且line separator為LF時,狀態列不會額外顯示。

以下內容來自:Vim 編輯器底端 [noeol], [dos] 的含義 - Trekshot - 部落格園 (cnblogs.com)

有時使用 Vim 開啟一個檔案會在視窗底部發現 [noeol], [dos] 提示資訊:

"hello-dos.txt" [noeol][dos] 2L, 10C                          1,1           All

這兩個符號有何含義?

直觀上理解,'noeol' 就是 'no end-of-line', 即“沒有行末結束符”, Linux 下的文字編輯器(如 Vim)會在每一行 (包括最後一行)末尾新增一個換行符。比如我們在 Debian 下新建一個名為 'hello-unix.txt' 的文字檔案,內容如下:

Hello
Unix

那麼,使用cat -A hello-unix.txt命令可以看到這些換行符:

ts@TS:~/www/document$ cat -A hello-unix.txt
Hello$
Unix$
ts@TS:~/www/document$

從中可以清楚地看到每行末尾的 '$' 字元,這就是 Linux 下的“行末結束符”。

下面我們再在 Windows 下建立一個名為 'hello-dos.txt' 記事本檔案,內容如下:

Hello
DOS

在 Debian 下檢視此檔案的換行符資訊:

ts@TS:~/www/document$ cat -A hello-dos.txt
Hello^M$
DOSts@TS:~/www/document$

同樣是兩行,每行一個單詞,Windows 和 Linux 下的換行符有兩個明顯不同:

  1. Windows 下的換行符比 Linux 下的多了個 ^M
  2. 最後一行行末沒有換行符;

這兩個不同之處也正是 [dos], [noeol] 兩個 Flag 資訊出現的原因。 Windows 下文字檔案每行的換行符為“回車+換行”(CRLF,^M$), 而 Linux 下則僅為 “換行” (LF, $). Vim 發現文字中含有 ^M$換行字元判定為 Windows 下建立的 檔案,用 [dos] Flag 提示;Vim 沒有在最後一行發現換行符,判定此檔案不是在 Linux 下建立/編輯,用 [noeol] Flag 提示使用者。

如何消除 [noeol] Flag?

只需在 Debian 下將該檔案重新儲存即可,還是上面的 hello-dos.txt 檔案,開啟它, 不做任何修改直接 :wq儲存退出,再檢視換行符:

ts@TS:~/www/document$ cat -A hello-dos.txt
Hello^M$
DOS^M$
ts@TS:~/www/document$

換行符已經追加上去,這裡要注意的是追加的是 Windows 下的換行符(回車+換行) ^M$, 而不是 Linux 下的換行符(換行)$, 因為 Vim 已經發現此檔案是在 Windows 下建立的([dos] Flag),儘管是在 Linux 下編輯,Vim 也會按照檔案建立時所在的作業系統下的換行規則新增換行符。

如何消除 [dos] Flag?

有兩種簡單的方法:

  1. Linux 下提供有兩個命令用來進行 Windows 和 Unix 檔案的轉化:dos2unix unix2dos;
  2. 在 Debian 下使用 touch template.txt 建立一個模板,在 Windows 下建立的任 何文字檔案都以此模板為基礎;

Reference

Vim 編輯器底端 [noeol], [dos] 的含義 - Trekshot - 部落格園 (cnblogs.com)


本文同步釋出於: