関数の内部に-fを設定してください。

関数の内部に-fを設定してください。

file1.cファイルfile2.cfile3.c。コマンドfind 出力:

$find -name "*.c"
./file1.c
./file2.c
./file3.c

find それから引用符なしで使用したいと思います.*cset -f

 $echo $-            # check current options
 himBHs
 $set -f
 $echo $-            # check that f option is set
 fhimBHs
 $find -name *.c
 ./file1.c
 ./file2.c
 ./file3.c
 $set +f             # unset f option

次の関数で同じコマンドを試しました.bashrc

find() {
    set -f
    eval command find $@
    set +f
}

ただし、テストするとエラーが発生します。

$ . ~/.bashrc && find -name *c
find: paths must precede expression: file1.c
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression

関数でこのエラーが発生するのはなぜですか?findバージョン: GNU 4.6.0

答え1

言っていませんが、次のように関数を呼び出す必要があります。

find -name *.c

ただし、ワイルドカードが閉じられていないため、*.c呼び出し前にシェルが拡張されます。したがって、findコマンドには「-name」とそれに続く3つのパラメータ(エラーメッセージ)が表示されます。

引用符の代わりにバックスラッシュを使用できます。

find -name \*.c

答え2

関数はファイル名ワイルドカードを無効にしますが、シェル拡張ワイルドカードを使用して呼び出します(ファイル名ワイルドカードはいいえ呼び出したシェルで閉じます。)

つまり、コマンドのグローブ

find -name *c

find関数を呼び出す前に拡張してください。これにより、findユーティリティが理解できない内部関数呼び出しが発生します。

引用符付き引数を使用して関数を呼び出すと、この問題を解決できます。

find -name "*c"

ただし、この機能はすでに入力したコマンドをコピーするだけなので、まったく役に立ちません。

存在する次へ追加それは役に立たず、間違っています。$@コードで引用されていないため、(デフォルトでは)スペースにパラメータを分割します。これはあなたを意味しますできないたとえば、使用します。

find -name "* *"

スペースを含む名前を見つけます。

また、何らかの理由でevalシェルが$@。これは意味する

find -name '$(echo hello)'

名前がありますが見つかりませ$(echo hello)hello

もう一つは、シェルを呼び出すとすでにを使用するset -fと、その機能は無効になります。


便利な関数を作成しましょう。見つける関数数量ファイル名パターン(例:

myfind "*.c" "*.txt" "* *"

.c上記のコマンドがまたはで終わり、スペースを含む.txtパス名を返したいです。

機能は次のとおりです。

myfind () {
    # Replace each positional parameter "$pattern"
    # with -o -name "$pattern"
    for pattern do
        set -- "$@" -o -name "$pattern"
        shift
    done
    shift  # shift off the initial "-o"

    find . "$@"
}

上記の関数を呼び出すと、最終的に実行されます。

find . -name '*.c' -o -name '*.txt' -o -name '* *'

配列をリストとして使用する方が簡単で、もう少しbash入力しても問題ありません。

myfind () {
    local -a args

    # Build the argument list for find by adding
    # -o -name "$pattern"
    # for each positional parameter 
    for pattern do
        args+=( -o -name "$pattern" )
    done
    args=( "${args[@]:1}" )  # remove the initial "-o"

    find . "${args[@]}"
}

関連情報