Bash 在find+中获得退出代码123;沙尔格斯格雷普

Bash 在find+中获得退出代码123;沙尔格斯格雷普,bash,find,xargs,Bash,Find,Xargs,这是我的剧本 eval "find \\( -type f -a \\( -name '*.h' \\) \\) -print0" | xargs -0 -n100 grep -f <(echo "stdio") echo $? eval“find\\(-type f-a\\(-name'*.h'\\)\)-print0”| xargs-0-n100 grep-f.P eval“find\\(-type f-a\\(-name'*.h'\\)\\)-print0”| xargs-0-n

这是我的剧本

eval "find \\( -type f -a \\( -name '*.h' \\) \\) -print0" | xargs -0 -n100 grep  -f <(echo "stdio")
echo $?
eval“find\\(-type f-a\\(-name'*.h'\\)\)-print0”| xargs-0-n100 grep-f.P
eval“find\\(-type f-a\\(-name'*.h'\\)\\)-print0”| xargs-0-n100 grep123表示“以非零状态退出的任何调用”。因此
xargs
至少运行了两次
grep
(因为您输入了太多的文件,它们将超过最大命令行长度,您将其限制为100个文件),并且至少有一次调用是在一组不包含匹配项的文件上进行的,这导致
grep
的退出代码为非零(失败)

也许你应该解释一下你想要完成什么。
eval
看起来是多余的,双重定向可能无法实现您想要的功能(
grep
的标准输入不能同时从
eval
连接到管道和
.P

如果要将第一个参数参数参数化为
grep
,可以执行以下操作

#!/bin/sh
find -type f -name '*.h' -print0 |
xargs -0 -n100 grep "$1"
。。。在这里,您使用例如
stdio
作为第一个参数来调用它

(还要注意,
查找
的参数非常简化。您只有两个谓词,因此不需要插入任何内容,然后也可以删除
-a
。)


如果存在返回零匹配的
grep
调用,则退出代码仍然是123。您可以通过省略
-n100
(这似乎很难提供任何有用的功能)来减少这种可能性,但是如果您想绝对防止这种情况发生,您可以将整个管道输送到
|grep.
,如果有任何输出,它将报告成功。(或者你可以在一个包装器上运行
xargs
,如果
grep
的退出代码是0或1,它总是返回成功,但这更复杂,即使在零匹配的情况下,你也会看到“成功”。

我将此作为一个单独的答案发布,以回应你最近的编辑。我并不特别想改变我现有的答案,因为它已经解决了基本问题

不幸的是,您的脚本是中描述的问题的经典示例:“我试图将命令放入变量中,但是”

简短的版本是“不要那样做”。较长的版本是,尝试使用数组,并避免使用非绝对必要的变量。下面是一个沿着这些思路重构工具的尝试

#!/bin/bash
#set -e -o pipefail

grep_patterns=( )
grep_options=( )

eval ARGV=($(getopt -l '' -o 'e:li' -- "$@")) || exit 1
for((i=0;i<${#ARGV[@]};i++)) {
    case ${ARGV[$i]} in
    -e) i=$((i+1))
        grep_patterns+=("-e" "${ARGV[$i]}") ;;
    -i | -l)
        grep_options+=("${ARGV[$i]}") ;;
    --) i=$((i+1));
        break;;
    esac
}

find_options=("${ARGV[@]:$i}")

find -type f -a \( "${find_options[@]}" \) -print0 |
xargs -0 grep "${grep_options[@]}" "${grep_patterns[@]}"
#/bin/bash
#set-e-o管道故障
grep_模式=()
grep\u选项=()
eval ARGV=($(getopt-l'-o'e:li'-“$@”)||退出1

对于((i=0;i)您为什么在这里使用
eval
#!/bin/sh
find -type f -name '*.h' -print0 |
xargs -0 -n100 grep "$1"
#!/bin/bash
#set -e -o pipefail

grep_patterns=( )
grep_options=( )

eval ARGV=($(getopt -l '' -o 'e:li' -- "$@")) || exit 1
for((i=0;i<${#ARGV[@]};i++)) {
    case ${ARGV[$i]} in
    -e) i=$((i+1))
        grep_patterns+=("-e" "${ARGV[$i]}") ;;
    -i | -l)
        grep_options+=("${ARGV[$i]}") ;;
    --) i=$((i+1));
        break;;
    esac
}

find_options=("${ARGV[@]:$i}")

find -type f -a \( "${find_options[@]}" \) -print0 |
xargs -0 grep "${grep_options[@]}" "${grep_patterns[@]}"