从 find 调用函数时变量的范围

从 find 调用函数时变量的范围

在 bash 脚本中,我定义了一个从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 "{}"' \;

除了它不可移植这一事实之外,它还非常危险,因为文件名最终会被解释为bashshell 代码。例如,考虑一下如果那里有一个文件被调用会发生什么$(rm -rf ~)。写下来:

find . -type f -exec bash -c 'myfunction "$1"' find+bash {} \;

或者甚至更好(以避免bash每个文件运行一个):

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在当前bashshell 中进行调用,因此无需导出myfunction或运行其他bashshell。

如果你find支持-print0谓词(比如 GNU、busybox 和一些 BSD 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

当您分配给一个变量时,它开始时是一个 shell 变量。为了获取传递给子进程的环境变量,您需要导出它。

variable="Filename:"
export variable

您可以将作业与export:放在同一行export variable="Filename:"

该变量对于 启动的 shell 可见find,但对函数不可见。在 bash 中,您还可以导出函数。这种可能性在 ksh、dash 和其他经常使用的 shell 中不存在,sh因为它们更快、更精简。

export -f myfunction    # bash only

切勿在(或){}中的字符串内使用,除非您知道文件名是字母数字。如果文件名中有任何特殊字符,内壳将对其进行解析。相反,在 shell 的命令行上传递文件名。find -exec …xargs …

find . -type f -exec bash -c 'for x; do myfunction "$x"; done' _ {} +

对于 bash 以外的 shell,在内 shell 中定义函数,或者直接放入其代码。

或者,在 bash 中,您可以使用递归通配符代替查找。请注意,bash 会遍历目录的符号链接。

variable="Filename:"
myfunction () { … }
shopt -s globstar dotglob
for x in **/*; do
  if [[ -f $x ]]; then myfunction "$x"; fi
done

相关内容