web-dev-qa-db-ja.com

デフォルトのシェルがbashと互換性がない場合、bashスクリプトがうまく機能しないのはなぜですか?

私のデフォルトのシェルは魚です。なぜならそれはずっといいからです。しかし、スクリプトを実行すると、bashスクリプトがfishによって処理されているように見えるエラーが発生することがよくあります。これは、スクリプト作成者がデフォルトのシェルをbashと想定していたためだと思いますが、そのメカニズムがわかりません。

たとえば、CrashPlan install.shスクリプトは、bashShebangで始まります。

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

#############################################################
# Linux Client Installer Script
#############################################################

したがって、./install.shを実行すると、bashで処理する必要があります。デフォルトのターミナルシェルは無関係である必要があります。それでも、デフォルトのシェルが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 

これは、コンピューターの構成が間違っているためですか、それともスクリプトが移植性のない方法で記述されているためですか?

4
endolith

したがって、./install.shを実行すると、bashで処理する必要があります。

確かに。それがまさにShebangの目的です。

トラブルシューティング

  • 以下をtest.shとして保存し、魚から実行してみてください。

    #!/bin/bash
    
    true && true
    

    それは私のコンピューターで動作します、そしてそれはあなたのものでなければなりません。

  • install.shの最初の行に文字#!/bin/bashのみが含まれているかどうかを確認します。

    目に見えない文字(CR改行など)は魚を混乱させる可能性があります。

  • 実行

    /bin/bash --version
    

    bashが実際にbashであり、時間の経過とともに誤って交換/変更されていないことを確認します。

install.sh

$SRC_USERは、スクリプトが$Sudo_USERに対して作成する同義語です。

その結果、スクリプトがroot権限で実行されると、コマンド

su ${SRC_USER} -c "sed -imod \"s|Exec=.*|Exec=${GUISCRIPT}|\" ${DESKTOP_LAUNCHER} && rm -rf ${DESKTOP_LAUNCHER}mod"

sudoユーザーのデフォルトのシェルであるfishを自動的に使用します。

このデフォルトをオーバーライドするには、命令-s /bin/bashsuコマンドに追加します。

5
Dennis