Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash shell脚本是否对编码和行尾敏感?_Bash_Shell_Sh - Fatal编程技术网

Bash shell脚本是否对编码和行尾敏感?

Bash shell脚本是否对编码和行尾敏感?,bash,shell,sh,Bash,Shell,Sh,我正在Mac上制作一个NW.js应用程序,希望通过双击图标在开发模式下运行该应用程序。第一步,我要让我的shell脚本工作 在Windows上使用VSCode(我想争取时间),我在项目的根目录下创建了一个runnw文件,其中包含以下内容: #!/bin/bash cd "src" npm install cd .. ./tools/nwjs-sdk-v0.17.3-osx-x64/nwjs.app/Contents/MacOS/nwjs "src" & 但我得到的结果是: $ sh

我正在Mac上制作一个NW.js应用程序,希望通过双击图标在开发模式下运行该应用程序。第一步,我要让我的shell脚本工作

在Windows上使用VSCode(我想争取时间),我在项目的根目录下创建了一个
runnw
文件,其中包含以下内容:

#!/bin/bash

cd "src"
npm install

cd ..
./tools/nwjs-sdk-v0.17.3-osx-x64/nwjs.app/Contents/MacOS/nwjs "src" &
但我得到的结果是:

$ sh ./run-nw

: command not found  
: No such file or directory  
: command not found  
: No such file or directory  

Usage: npm <command>

where <command> is one of:  (snip commands list)

(snip npm help)

npm@3.10.3 /usr/local/lib/node_modules/npm  
: command not found  
: No such file or directory  
: command not found
$sh./run nw
:未找到命令
:没有这样的文件或目录
:未找到命令
:没有这样的文件或目录
用法:npm
其中是:(snip命令列表)
(snip npm帮助)
npm@3.10.3/usr/local/lib/node\u modules/npm
:未找到命令
:没有这样的文件或目录
:未找到命令
我真的不明白:

  • 它似乎将空行作为命令。在我的编辑器(VSCode)中,我尝试将
    \r\n
    替换为
    \n
    (以防
    \r
    产生问题),但没有任何改变
  • 它似乎找不到文件夹(带或不带
    dirname
    指令),或者可能不知道
    cd
    命令
  • 它似乎不理解
    npm
    install
    参数
  • 真正让我感到奇怪的是,它仍然在运行应用程序(如果我手动安装了
    npm
由于无法使其正常工作,并且怀疑文件本身有什么奇怪的地方,我直接在Mac上创建了一个新文件,这次使用的是vim。我输入了完全相同的指令,然后。。。现在它可以正常工作了。
两个文件上的差异显示完全没有差异

有什么区别?什么会使第一个脚本不起作用?我怎么知道

更新 在接受答案的建议后,在返回错误的行尾后,我检查了多个内容。事实证明,由于我从Windows计算机复制了
~/.gitconfig
,所以我的
autocrlf=true
,因此每次我在Windows下修改bash文件时,它都会将行结尾重新设置为
\r\n

因此,除了运行dos2unix(您必须在mac上使用自制软件安装),如果您使用的是Git,请检查您的配置。

是。Bash脚本对脚本本身和它处理的数据中的行尾都很敏感。它们应该有Unix风格的行尾,即每一行都以换行字符(十进制10,ASCII中的十六进制0A)结尾

脚本中的DOS/Windows行结尾 对于Windows或DOS样式的行尾,每行都以回车符结尾,后跟换行符。您可以在cat-v yourfile的输出中看到这个不可见的字符:

$ cat -v yourfile
#!/bin/bash^M
^M
cd "src"^M
npm install^M
^M
cd ..^M
./tools/nwjs-sdk-v0.17.3-osx-x64/nwjs.app/Contents/MacOS/nwjs "src" &^M
在这种情况下,回车符(
^M
在插入符号中或
\r
在C转义符号中)不被视为空白。Bash将shebang后面的第一行(由单个回车符组成)解释为要运行的命令/程序的名称

  • 由于没有名为
    ^M
    的命令,它将打印
    :找不到命令
  • 由于没有名为
    “src”^M
    (或
    src^M
    )的目录,它将打印
    :没有这样的文件或目录
  • 它将
    install^M
    而不是
    install
    作为参数传递给
    npm
    ,从而导致
    npm
    投诉
输入数据中的DOS/Windows行结束符 如上所述,如果您有一个带有回车符的输入文件:

hello^M
world^M
sed -i 's/\r$//' filename
然后,在编辑器中以及在将其写入屏幕时,它将看起来完全正常,但工具可能会产生奇怪的结果。例如,
grep
将无法找到明显存在的行:

$ grep 'hello$' file.txt || grep -x "hello" file.txt
(no match because the line actually ends in ^M)
追加的文本将覆盖该行,因为回车符会将光标移动到该行的开头:

$ sed -e 's/$/!/' file.txt
!ello
!orld
字符串比较似乎会失败,即使写入屏幕时字符串看起来相同:

$ a="hello"; read b < file.txt
$ if [[ "$a" = "$b" ]]
  then echo "Variables are equal."
  else echo "Sorry, $a is not equal to $b"
  fi

Sorry, hello is not equal to hello
  • 在有功能的文本编辑器(升华、记事本++、非记事本)中打开文件,并将其配置为使用Unix行结尾保存文件,例如,使用Vim,在(重新)保存之前运行以下命令:

  • 如果您有一个支持
    -i
    -in-place
    选项的
    sed
    实用程序版本,例如GNU
    sed
    ,您可以运行以下命令来剥离尾部回车:

    hello^M
    world^M
    
    sed -i 's/\r$//' filename
    
    对于其他版本的
    sed
    ,可以使用输出重定向写入新文件。确保重定向目标使用不同的文件名(以后可以重命名)

  • 类似地,
    tr
    翻译过滤器可用于从输入中删除不需要的字符:

    tr -d '\r' <filename >filename.unix
    
    由于这一行很长,以octothorpe(
    #
    )开头,Bash将这一行(以及整个文件)视为一条注释

    注:2001年,苹果推出了基于BSD衍生操作系统的MacOSX。因此,OSX也使用Unix风格的LF-only行结尾,从那时起,以CR结尾的文本文件变得极为罕见。尽管如此,我认为值得展示Bash如何尝试解释这些文件。

    是的。Bash脚本对脚本本身和它处理的数据中的行尾都很敏感。它们应该有Unix风格的行尾,即每一行都以换行字符(十进制10,ASCII中的十六进制0A)结尾

    脚本中的DOS/Windows行结尾 对于Windows或DOS样式的行尾,每行都以回车符结尾,后跟换行符。您可以在cat-v yourfile的输出中看到这个不可见的字符:

    $ cat -v yourfile
    #!/bin/bash^M
    ^M
    cd "src"^M
    npm install^M
    ^M
    cd ..^M
    ./tools/nwjs-sdk-v0.17.3-osx-x64/nwjs.app/Contents/MacOS/nwjs "src" &^M
    
    在这种情况下,回车符(
    ^M
    在插入符号中或
    \r
    在C转义符号中)不被视为空白。Bash将shebang后面的第一行(由单个回车符组成)解释为ru的命令/程序的名称
    #!/bin/bash^M^Mcd "src"^Mnpm install^M^Mcd ..^M./tools/nwjs-sdk-v0.17.3-osx-x64/nwjs.app/Contents/MacOS/nwjs "src" &^M
    
    $ tr -d '\r' < dosScript.py > nixScript.py
    
    for f in *$'\r'; do
        mv "$f" "${f%$'\r'}"
    done
    
    Bash script and /bin/bash^M: bad interpreter: No such file or directory
    
    config/* text eol=lf
    run.sh text eol=lf
    
    IFS= read -r somevar    # This will not trim CR
    
    IFS=$'\r' read -r somevar    # This *will* trim CR
    
    read -r field1 field2 ...    # This will not trim CR
    
    IFS=$' \t\n\r' read -r field1 field2 ...    # This *will* trim CR
    
    cr="$(printf '\r')"
    IFS="$cr" read -r somevar    # Read trimming *only* CR
    IFS="$IFS$cr" read -r field1 field2 ...    # Read trimming CR and whitespace, and splitting fields