gpt4 book ai didi

linux - 使用由内部逻辑定义的查找参数从 bash 脚本调用查找

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:59:58 24 4
gpt4 key购买 nike

我有一个脚本在内部调用 find 并且 id 喜欢做这样的事情:

FIND_CRITERIA="-name \"*.[ch]\" -o -name \"*.cpp\" -o -name \"*.hpp\""
if [ "$1" != "" ]; then
FIND_CRITERIA=$1
fi

echo "Find command: find / ${FIND_CRITERIA} > /tmp/output.txt"
find / ${FIND_CRITERIA} > /tmp/output.txt

它准确地打印出我想要执行的查找命令。但是它没有正确执行。

有人知道为什么吗?

非常感谢。

最佳答案

简答:参见 BashFAQ #50:I'm trying to put a command in a variable, but the complex cases always fail! .

长答案:当 shell 解析像 find/${CRITERIA} 这样的命令时,它首先解析引号、转义符等;然后它将 ${CRITERIA} 之类的变量替换为它们的值,但不会回过头来查找引号等——它已经这样做了。因此,将引号、转义符等放在变量中没有任何用处。

在 bash 中执行此类操作的最佳方法是将参数存储在数组中:

#!/bin/bash
CRITERIA=(-name "*.[ch]" -o -name "*.cpp" -o -name "*.hpp")

echo "Find command: find / ${CRITERIA} > /tmp/output.txt"
find / "${CRITERIA[@]}" > /tmp/output.txt

...但这不适用于您将 $1 视为一组可选标准的方式。脚本是否需要任何其他参数?如果没有,我建议将搜索条件作为单独的参数而不是单个参数(即 ./findscript -name "*.c" 而不是 ./findscript "-名称\"*.c\""),像这样:

#!/bin/bash
if [ $# -gt 0 ]; then
CRITERIA=("$@")
else
CRITERIA=(-name "*.[ch]" -o -name "*.cpp" -o -name "*.hpp")
fi

echo "Find command: find / ${CRITERIA} > /tmp/output.txt"
find / "${CRITERIA[@]}" > /tmp/output.txt

编辑:根据您关于需要允许脚本的其他选项/参数的评论,我看到三个选项:

  1. 使用eval 将getopt 参数解析为一个数组:

    case "$opt" in
    f) eval "CRITERIA=($OPTARG)" ;;

    这具有与 eval 相关的所有常见问题,主要与以奇怪的(并且可能是危险的)方式失败有关,具体取决于作为 OPTARG 传递的内容。恶心。

  2. 如果脚本不需要采用任何“常规”(非选项)参数,则将标准作为常规参数传递(./script -a -b -c -d -- -名称“.cpp”-o -名称“.hpp”)。 这个问题是 IIRC getopts 不会将 -- 读取为选项和常规参数之间的分隔符,因此您至少必须做一些“手动”解析。 更正:至少在 bash 版本 3.2.48 中,getopts 自动处理 --

  3. 如果您需要传递的唯一条件是 -name's,您可以使用多个 -f 选项来指定名称模式以构建条件,例如./script -a -b -c -d -f "*.cpp"-f "*.hpp"

    CRITERIA=()
    ...
    case "$opt" in
    f) if [[ ${#CRITERIA[@]} -eq 0 ]]; then
    CRITERIA=(-name "$OPTARG")
    else
    CRITERIA+=(-o -name "$OPTARG")
    fi ;;
    ...

    if [[ ${#CRITERIA[@]} -eq 0 ]]; then
    CRITERIA=(-name "*.[ch]" -o -name "*.cpp" -o -name "*.hpp")
    fi

关于linux - 使用由内部逻辑定义的查找参数从 bash 脚本调用查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16219071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com