当默认 shell 与 bash 不兼容时,为什么 bash 脚本不能正常工作?

end*_*ith 4 bash shell-script chsh fish

我的默认外壳是鱼,因为它更好。但通常当我运行脚本时,我收到的错误似乎是由 fish 处理的 bash 脚本引起的。我认为这是因为脚本编写者假设默认的 shell 是 bash,但我不明白其中的机制。

例如,CrashPlan install.sh 脚本以 bash shebang 开头:

~/CrashPlan-install> head install.sh
#!/bin/bash

#############################################################
# Linux Client Installer Script
#############################################################
Run Code Online (Sandbox Code Playgroud)

所以当我运行./install.sh它时,它应该由 bash 处理,对吗?默认终端外壳应该是无关紧要的。然而,当我的默认 shell 是 fish 时,运行这样的脚本会导致 fish 返回错误,就好像它正在处理脚本一样:

fish: Expected a command name, got token of type “Run job in background”. Did you mean
 “COMMAND; and COMMAND”? See the help section for the “and” builtin command by typing “help and”.
Standard input: sed -imod "s|Exec=.*|Exec=/usr/local/crashplan/bin/CrashPlanDesktop|" 
 /home/username/Desktop/CrashPlan.desktop && rm -rf /home/username/Desktop/CrashPlan.desktopmod 
Run Code Online (Sandbox Code Playgroud)

这是因为我的计算机配置错误还是因为脚本是以不可移植的方式编写的?

Den*_*nis 6

所以当我运行./install.sh它时,它应该由 bash 处理,对吗?

的确。这正是shebang的用途。

故障排除

  • 将以下内容另存为test.sh并尝试从鱼运行它。

    #!/bin/bash
    
    true && true
    
    Run Code Online (Sandbox Code Playgroud)

    它可以在我的电脑上运行,也应该在你的电脑上运行。

  • 检查第一行是否install.sh只包含字符#!/bin/bash

    不可见的字符(例如 CR 换行符)可能会迷惑鱼。

  • /bin/bash --version
    
    Run Code Online (Sandbox Code Playgroud)

    检查 bash 实际上是 bash 并且随着时间的推移没有被意外替换/修改。

安装文件

$SRC_USER只是脚本为$SUDO_USER.

结果,当脚本以 root 权限运行时,命令

su ${SRC_USER} -c "sed -imod \"s|Exec=.*|Exec=${GUISCRIPT}|\" ${DESKTOP_LAUNCHER} && rm -rf ${DESKTOP_LAUNCHER}mod"
Run Code Online (Sandbox Code Playgroud)

自动使用 sudo 用户的默认 shell,即fish。

要覆盖此默认值,请将指令添加-s /bin/bashsu命令中。

  • 是的,我认为是 `su` 命令。我已经创建了一个用户 `fishy`,以 fish 作为它的默认 shell。在 bash 中,`su fishy "true && true"` 会导致错误。`su fishy -s /bin/bash -c "true && true"` 工作正常。 (2认同)