find(fd)は、ユーザー定義関数と複数のパラメータを使用して実行されます。

find(fd)は、ユーザー定義関数と複数のパラメータを使用して実行されます。

私は初めてbashスクリプトに触れましたので、粗雑さをご理解ください。私はディレクトリを含むすべてのディレクトリを巡回し.git、作業ツリーがきれいか汚れているかを確認する簡単なスクリプトを書いています。効果がある、しかし、私は3つのパラメータが欲しい:

  • rootDir: .git ディレクトリの最上位ディレクトリを検索します。
  • status:clean|dirty|allディレクトリの状態に基づいて出力をフィルタリングします。
  • \0区切り文字:この出力を渡して追加のコマンドを実行できるように、区切り文字を実行するためのNULL転送を許可し、スペースのあるパスもサポートしますxargs

私が直面している問題は、パラメータをfd exec私のisRepoDirty関数に渡すことです。パラメータ$cleanOrDirtyが何とか入ってきましたが、パラメータ$separatorは機能しません。私の一重引用符、二重引用符の知識はここで少し不安定です。パラメータを一重引用符で囲んでも絶対に拡張されません。

これが私が持っているものです:

#!/bin/bash
# DOES NOT WORK IN ZSH!
# https://unix.stackexchange.com/questions/50692/executing-user-defined-function-in-a-find-exec-call

rootDir=$1
cleanOrDirty=$2
separator=$3

# echo "Root: $rootDir"
# echo "Clean or Dirty: $cleanOrDirty"
# echo "Separator: $separator"

function isRepoDirty() {
    if [[ $(git --git-dir "$1" --work-tree "$1/.." status --porcelain | wc -l) > 0 ]]; then
        status="dirty"
    else
        status="clean"
    fi

    # echo "Repo: $1, Status: $status"
    if [[ $2 == $status || $2 == "all" ]]; then
        # echo "Separator: $3"
        if [[ $3 == "null" ]]; then
            printf "%b" "$1/..\0"
        else
            echo "$1/.."
        fi
    fi
}
export -f isRepoDirty

fd --no-ignore --hidden -t d "\.git$" $rootDir -x /bin/bash -c 'isRepoDirty "{}" '$cleanOrDirty $separator

私のアプローチが完全に間違っている場合は、ベストプラクティスと見なされることを学び、実行するのに非常に情熱的ですので、教えてください。ハハ、私が渡したパラメータは少し初歩的です。 bashで-pパラメータを簡単に処理してスタイルを設定する簡単な方法が見つかりませんでした。--parameter-name

時間をいただきありがとうございます!

ベストアンサー1

同様の問題がありましたが、bash次のパラメータを追加して問題を解決しました。

bash -c 'command "$@"' bash arg1 arg2

Stéphane Chazelasが指摘したように、最初の引数は$0呼び出されるコマンドとして扱われるため、_初期デバッグよりもデバッグが簡単になります。

あなたの場合、答えは次のとおりです。

fd --no-ignore --hidden -t d '\.git$' "$rootDir" -x /bin/bash -c 'isRepoDirty "$1" "$2" "$3"' bash {} "$cleanOrDirty" "$separator"

$rootDirで始まらず、、、、、を含めないとします。-$cleanOrDirty$separator;{}{/}{//}{.}{/.}

このような状況を回避するには、オプションの区切り文字を使用します。つまり--、パターンの前に移動する-xという意味であり、引数の代わりに環境を介してこれらの追加変数の内容を渡すことができます。

(
  export cleanOrDirty separator
  exec fd --no-ignore --hidden -t d -x /bin/bash -c '
    isRepoDirty "$1" "$cleanOrDirty" "$separator"
    ' bash {} ';' -- '\.git$' "$rootDir"
)

おすすめ記事