シェルスクリプトはエラー終了の代わりにエラーを返します。

シェルスクリプトはエラー終了の代わりにエラーを返します。

私はそれがset -e私の友人が誤ってやめたことを知っていました。しかし、コンソールで関数を実行するなど、スクリプトがソースとして提供されている場合はどうなりますか?エラーが原因でコンソールを閉じたくないので、スクリプトを停止してエラーメッセージを表示したいと思います。

$を確認する必要がありますか?これを可能にするには、各コマンドを手動で実行しますか?

myScript.sh問題を示すサンプルスクリプトは次のとおりです。

#!/bin/sh
set -e

copySomeStuff()
{
    source="$1"
    dest="$2"
    cp -rt "$source" "$dest"
    return 0
}

installStuff()
{
    dest="$1"
    copySomeStuff dir1 "$dest"
    copySomeStuff dir2 "$dest"
    copySomeStuff nonExistingDirectory "$dest"
}

スクリプトは次のように使用されます。

$ source myScript.sh
$ installStuff

これでコンソールが閉じます。表示されたエラーがcpありません。

答え1

スクリプトをサブシェルとして実行することをお勧めします。関数定義を読み取ることができるファイルを取得することもできます。スクリプトerrexitに独自のシェルオプションを設定させます。

コマンドラインでそれを使用する場合、source「スクリプト」は実際に対話型シェルです。シャットダウンとは、シェルセッションを終了することを意味します。この問題を解決するにはいくつかの方法がありますが、errexitセッションを確立したい場合は、最良の方法は次のとおりです。

#!/bin/bash

set -o errexit

source file_with_functions
do_things_using_functions

ボーナス:関数の対話型セッションを汚染しません。

答え2

これを取得すると無視され、呼び出しシェルに#!適用されるため、後続のすべてのコマンドに適用されます。set -e

サブシェルを強制的に使用できます。

copySomeStuff()
{
    (
        set -e
        source="$1"
        dest="$2"
        cp -r "$source" "$dest"
        return 0
    )
}

また安全のため:

  • 環境名と競合する可能性があるため、変数名はすべて大文字にしないでください。 (先週にスクリプトが機能しない理由について質問がありましたが、スクリプトには変数PATHがありました)

  • 引用符を使用してください。

  • 常に-tまたは-Tオプションcp、、、mvを使用してくださいln。例えば

    • cp -t destination_directory source_files …
    • cp -T source_file destination_file

    -tGnu拡張は-T他の一部のUnixでは利用できないため、移植性のためにそれらの-tオプションを置き換えることができます。

    • cp source_files … destination_directory/

    代替セキュリティの形式がわかりません。-T

関連情報