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[@]}"