5

su_mt_user(現在)次のような関数を記述できるようにしたいと思います。

su_mt_user() {
    su someuser -c "$*"
}

目的は、次のように使用できるようにすることです。

su_mt_user mt-auth --stuff etc

mt-auth --stuff etcuser としてコマンドを実行しますsomeuser。現在のバージョンはこの特定のコマンドで機能しますが、次のようなコマンドでは失敗します:

some_filename_with_spaces="/home/user/hello there i like spaces in filenames.txt"
su_mt_user stat "$some_filename_with_spaces"

これは次のエラーで失敗します。

stat: cannot stat '/home/user/hello': No such file or directory
stat: cannot stat 'there': No such file or directory
stat: cannot stat 'i': No such file or directory
stat: cannot stat 'like': No such file or directory
stat: cannot stat 'spaces': No such file or directory
stat: cannot stat 'in': No such file or directory
stat: cannot stat 'filenames.txt': No such file or directory

$some_filename_with_spacesこのエラーは、関数に1 つの引数として適切に渡されたにもかかわらずsu_mt_user、その関数が"$*".

私も試行錯誤してこれを試しました:

su_mt_user() {
    su someuser -c "$0 $@"
}

しかし、それも失敗します ( /usr/bin/stat: cannot execute binary file(なに?))

もちろん、stat "$some_filename_with_spaces"現在のユーザーとユーザーの両方から期待どおりに機能しsomeuserます。

これはエスケープを行う必要があるように見えますが、bash はそれを行う方法を知っていますか? 手動での置換が必要ですか? もしそうなら、どの文字をエスケープする必要がありますか?

4

1 に答える 1

12

関数を介して複数の引数をコマンドに渡すには、"$@". "$@"は、二重引用符で囲まれているにもかかわらず、個別の引数が異なる単語になるため、そのまま渡されるという点で特別です。これは、空白を含む各引数を追加で分割し、結果の各単語をグロブ パターンとして解釈する引用符の有無$@とは異なります。$*"$*"

suは引数を直接消費せず、シェルを通過するため、追加のしわがあります。へのオプションではない引数は、suへの引数として渡されるsh -cため、-c.

su_mt_user() {
    su someuser -c '"$0" "$@"' -- "$@"
}
于 2012-09-09T22:56:17.180 に答える