スペースによってパスが破損することなく、スクリプトで「$@」またはデフォルトのパラメータリストを使用できるようにするにはどうすればよいですか。

スペースによってパスが破損することなく、スクリプトで「$@」またはデフォルトのパラメータリストを使用できるようにするにはどうすればよいですか。

引数が渡されない場合は、一部のデフォルトパスで別のユーティリティを実行するスクリプトが必要です。理想的には、スペースを含むパスに対して安全であることを望みます。

これまで私はscript.sh

#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"

「foo bar」というフォルダに入れて実行すると:

foo\ bar/script.sh

私はそれが最終的にそうなることを願っています:

touch foo\ bar/aaa foo\ bar/bbb

つまり、スクリプトが配置されている「foo bar」ディレクトリに「aaa」ファイルと「bbb」ファイルが作成されます。

代わりにエラーが発生しました。

touch: 'foo bar/aaa foo bar/bbb' をタッチできません: そのファイルやディレクトリはありません

(スクリプトに引数を渡すと正常に動作するようです。おそらく最後のコマンドから外側の引用符を削除すると、状況が反転します。)

答え1

の拡張では、デフォルトパラメータを設定できないように見え、単一の${@:-...}文字"${@:-"$base/aaa" "$base/bbb"}"列に拡張されます。

デフォルトのパラメータを設定するには、次のようにします。

base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
    set -- "$base/aaa" "$base/bbb"
fi

その後、"$@"参照パラメータ置換の魔法が減ることなく発生します。

touch -- "$@"

答え2

デフォルトの拡張では、複数のパラメータを使用できます${@-...}

このように:

#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")

touch "${@:-"${arr[@]}"}"

ただし、配列(ksh、zsh、bashなど)を持つシェルにのみ適用されます。

関連情報