如何使用 bash 中的变量内容传递给脚本中的查找?
How to use content of variable in bash to pass to find in script?
在 bash 脚本中,我尝试使用一个变量的内容作为 find 命令的选项:
#!/bin/bash
FILE_EXTENSIONS=( txt png jpg )
FIRST=1
for FILE_EXTENSION in ${FILE_EXTENSIONS[@]}
do
# echo "$FILE_EXTENSION"
if [[ $FIRST == 1 ]]
then
FIND_FILTER="-iname '*.$FILE_EXTENSION'"
FIRST=0
else
FIND_FILTER="${FIND_FILTER} -o -iname '*.$FILE_EXTENSION'"
fi
done
# Read and write only for user and group, ignore case '-iname'
#find . -type f "$FIND_FILTER" -exec chmod 660 {} \;
echo Find filter: $FIND_FILTER
# This might work with some already provided suggestions:
find . -type f $FIND_FILTER
# But this fails so far
find . -type f $FIND_FILTER -exec chmod 660 {} \;
#EOF
目的是设置适当的访问权限,无论出于何种原因,相当多的文件(例如图片或办公文档)都被标记为可执行。
所以实际上上面的脚本有几个文件扩展名串联的数组,但脚本显示了问题。
第一种方法是遍历最终数组并每次调用查找。但是从运行时的角度来看,每次都一遍又一遍地搜索是愚蠢的。
我也可以在 python 中简单地执行此操作,但有一次我想我想在 bash.
中使用 linux 基本方法解决它
看起来 FIND_FILTER 变量的内容是正确的(至少用 echo 打印的是正确的)但是......它不起作用。
有什么问题的建议吗?
好的,我找到了它不起作用的原因
$ find . $FIND_ARGS & # Does not work
[1] 6312
$ cat /proc/6312/cmdline
find . -iname '*.png'
$ find . -iname '*.png' & # Works
[1] 8901
$ cat /proc/8901/cmdline
find . -iname *.png
因此,直接调用命令时的引号只是为了 bash 而不是扩展参数。间接启动命令时,必须删除这些引号。
您开始(几乎)正确地使用了数组,但随后放弃了它们,转而使用 space 分隔的字符串。继续使用数组。
- 总是引用
@
索引数组的扩展;否则,没有理由使用 @
而不是 *
.
- 作为一般规则,避免使用全大写的变量名称;它们(大部分)保留供 shell.
使用
- 将由
-o
加入的过滤器括在转义括号中,以便 find
将它们视为除 -type
主要条件外还需要满足的单一条件。
- 使用
-exec ... +
以便 chmod
每次调用可以对多个文件进行操作,而不是对每个文件单独调用一次。
#!/bin/bash
file_extensions=( txt png jpg )
first=1
for ext in "${file_extensions[@]}"
do
# echo "$ext"
if [[ $first == 1 ]]
then
find_filter=(-iname "*.$ext")
first=0
else
find_filter+=( -o -iname "*.$ext")
fi
done
# Read and write only for user and group, ignore case '-iname'
find . -type f \( "${find_filter[@]}" \) -exec chmod 660 +
在 bash 脚本中,我尝试使用一个变量的内容作为 find 命令的选项:
#!/bin/bash
FILE_EXTENSIONS=( txt png jpg )
FIRST=1
for FILE_EXTENSION in ${FILE_EXTENSIONS[@]}
do
# echo "$FILE_EXTENSION"
if [[ $FIRST == 1 ]]
then
FIND_FILTER="-iname '*.$FILE_EXTENSION'"
FIRST=0
else
FIND_FILTER="${FIND_FILTER} -o -iname '*.$FILE_EXTENSION'"
fi
done
# Read and write only for user and group, ignore case '-iname'
#find . -type f "$FIND_FILTER" -exec chmod 660 {} \;
echo Find filter: $FIND_FILTER
# This might work with some already provided suggestions:
find . -type f $FIND_FILTER
# But this fails so far
find . -type f $FIND_FILTER -exec chmod 660 {} \;
#EOF
目的是设置适当的访问权限,无论出于何种原因,相当多的文件(例如图片或办公文档)都被标记为可执行。
所以实际上上面的脚本有几个文件扩展名串联的数组,但脚本显示了问题。
第一种方法是遍历最终数组并每次调用查找。但是从运行时的角度来看,每次都一遍又一遍地搜索是愚蠢的。
我也可以在 python 中简单地执行此操作,但有一次我想我想在 bash.
中使用 linux 基本方法解决它看起来 FIND_FILTER 变量的内容是正确的(至少用 echo 打印的是正确的)但是......它不起作用。
有什么问题的建议吗?
好的,我找到了它不起作用的原因
$ find . $FIND_ARGS & # Does not work
[1] 6312
$ cat /proc/6312/cmdline
find . -iname '*.png'
$ find . -iname '*.png' & # Works
[1] 8901
$ cat /proc/8901/cmdline
find . -iname *.png
因此,直接调用命令时的引号只是为了 bash 而不是扩展参数。间接启动命令时,必须删除这些引号。
您开始(几乎)正确地使用了数组,但随后放弃了它们,转而使用 space 分隔的字符串。继续使用数组。
- 总是引用
@
索引数组的扩展;否则,没有理由使用@
而不是*
. - 作为一般规则,避免使用全大写的变量名称;它们(大部分)保留供 shell. 使用
- 将由
-o
加入的过滤器括在转义括号中,以便find
将它们视为除-type
主要条件外还需要满足的单一条件。 - 使用
-exec ... +
以便chmod
每次调用可以对多个文件进行操作,而不是对每个文件单独调用一次。
#!/bin/bash
file_extensions=( txt png jpg )
first=1
for ext in "${file_extensions[@]}"
do
# echo "$ext"
if [[ $first == 1 ]]
then
find_filter=(-iname "*.$ext")
first=0
else
find_filter+=( -o -iname "*.$ext")
fi
done
# Read and write only for user and group, ignore case '-iname'
find . -type f \( "${find_filter[@]}" \) -exec chmod 660 +