我编写了一个脚本,该脚本在单词文档中循环以匹配其中的单词。下面是一个有效的示例,并找到数字43。其后是一个无效的脚本。我只想在脚本开始时将数字43作为变量,但是它似乎无法正确扩展。有什么想法可以在脚本中使用43作为变量而不是对其进行硬编码吗?
有效的脚本:
find . -type f -name '*.docx' -exec sh -c '
for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "43" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
done
' sh {} +
无效的脚本:
scan_var=43
find . -type f -name '*.docx' -exec sh -c '
for file do
docx2txt "$file" 2>/dev/null - | grep -i --color "$scan_var" && printf "\033[1;32mFound in ${file}\033[0m\n"
#readlink -f "$file"
done
' sh {} +
答案 0 :(得分:3)
从安全角度来看,您应该使用export
通过环境将变量公开给子进程,而不是将这些变量替换为解析为代码的字符串(这样容易导致shell injection攻击)。
也就是说:
export scan_var=43 ## the **only** change is to this line!
# only modifications to code below are formatting with no functional impact
# ...well, and safer printf use (to not expand format strings in filenames)
find . -type f -name '*.docx' -exec sh -c '
for file do
docx2txt "$file" 2>/dev/null - \
| grep -i --color "$scan_var" \
&& printf "\033[1;32mFound in %s\033[0m\n" "$file"
done
' sh {} +
答案 1 :(得分:2)
sh -c
派生一个子进程,该变量不可见,请参见Charles' answer以获取修复。
将变量放入-exec sh -c
的另一种方法是将其用作参数。考虑
$ var=43
$ sh -c 'echo "$var"' # Expands to nothing
$ sh -c 'echo "$1"' sh "$var" # Gets variable value into sh -c
43
请注意,命令后sh -c
的第一个参数在$0
(进程名称)中用作sh -c
。
应用于您的命令:
scan_var=43
find . -type f -name '*.docx' -exec sh -c '
scan_var=$1
shift
for file do
echo docx2txt "$file" 2>/dev/null - \
| grep -i --color "$scan_var" \
&& printf "\033[1;32mFound in ${file}\033[0m\n"
# readlink -f "$file"
done
' sh "$scan_var" {} +
将第一个参数的值读入scan_var
,然后用shift
丢弃该参数。
答案 2 :(得分:0)
您将避免在单引号内使用变量。
调整grep
命令行:
grep -i --color "'"$scan_var"'" && ...
这将关闭find -exec
之前的$scan_var
中的单引号,并为其余代码开始单引号。