BashスクリプトでFromを定義します。find
問題は、変数の範囲が関数に拡張されないことです。関数内の変数にどのようにアクセスしますか?例は次のとおりです。
variable="Filename:"
myfunction() {
echo $variable $1
}
export -f myfunction
find . -type f -exec bash -c 'myfunction "{}"' \;
これにより、「Filename:」文字列なしでファイル名が出力されます。
find
見つかったすべてのファイルに対して呼び出され、find
まだ変数を定義するために関数を呼び出すより良い方法はありますか?
答え1
あなたの質問に対する答えではありませんが、大丈夫です。いいえする:
find . -type f -exec bash -c 'myfunction "{}"' \;
移植性がないという事実に加えて、ファイル名がbash
シェルコードとして解釈されるため、非常に危険です。たとえば、というファイルがある場合はどうなるか考えてみましょう$(rm -rf ~)
。書き下ろす:
find . -type f -exec bash -c 'myfunction "$1"' find+bash {} \;
bash
または、より良い方法は次のとおりです(ファイルごとに1つずつ実行したくない場合)。
find . -type f -exec bash -c 'for file do
myfunction "$file"; done' find+bash {} +
それでは、トピックの質問に答えてみましょう。
次のことができます。
{ find . -type f -exec printf '%s\0' {} + | while IFS= read -ru3 -d '' file; do
myfunction "$file"; done 3<&0 <&4 4<&-; } 4<&0
これにより、myfunction
現在のシェル内で呼び出すことができるため、他のシェルをbash
エクスポートまたは実行する必要はありません。myfunction
bash
GNU、busybox、一部のBSDなどの述語をfind
サポートしている場合は、置き換えることができます。-print0
find
-exec printf '%s\0' {} +
-print0
答え2
variable
環境変数として宣言できます。
export variable="Filename:"
答え3
私はこれをします。
#!/bin/bash
myfunction() {
local var="Filename: "
local file=$1
echo "$var" "$file"
}
export -f myfunction
find . -type f -exec bash -c 'myfunction {}' \;
変数をローカル変数として宣言し、「{}」を最初の位置引数として関数に渡します$1
。
答え4
変数に代入すると、シェル変数で始まります。環境変数を子プロセスに渡すには、それをエクスポートする必要があります。
variable="Filename:"
export variable
export
:と同じ行に課題を配置できますexport variable="Filename:"
。
この変数は起動シェルには表示されますが、find
関数には表示されません。 Bashでは、関数をエクスポートすることもできます。 ksh、dash、およびその他の頻繁に使用されるシェルには、これらの可能性はありません。sh
より速く効率的だからです。
export -f myfunction # bash only
{}
ファイル名が英数字であることを知らない限り、(または)の文字列内で使用しないでください。ファイル名に特殊文字が含まれている場合、内部シェルはそれを解析します。代わりに、シェルのコマンドラインにファイル名を渡してください。find -exec …
xargs …
find . -type f -exec bash -c 'for x; do myfunction "$x"; done' _ {} +
Bash 以外のシェルの場合は、内部シェルで関数を定義するか、そのコードを直接入力します。
あるいは、bashではfindの代わりに再帰ワイルドカードを使用できます。 Bashはディレクトリへのシンボリックリンクを通過します。
variable="Filename:"
myfunction () { … }
shopt -s globstar dotglob
for x in **/*; do
if [[ -f $x ]]; then myfunction "$x"; fi
done