如何设置可选参数?

hel*_*hod 4 bash

假设您有以下问题:

根据脚本是否在管道内执行,您希望将-print0参数附加到find.

我可以想到至少两种方法来做到这一点:

[[ -p '/dev/stdin' ]] && local null_terminated='-print0'
find -mindepth 1 -maxdepth 1 ! \( "${args[@]}" \) "$null_terminated"
Run Code Online (Sandbox Code Playgroud)

或者

    if [[ -p '/dev/stdin' ]]; then
        find -mindepth 1 -maxdepth 1 ! \( "${args[@]}" \) -print0
    else
        find -mindepth 1 -maxdepth 1 ! \( "${args[@]}" \)
    fi
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来做到这一点?问题是针对bash,但sh也欢迎其他 shell 或便携式/标准解决方案的解决方案。

Sté*_*las 5

第一个不会像$null_terminated空或未设置一样工作,find会抱怨那个空的额外参数。

find -mindepth 1 -maxdepth 1 ! \( "${args[@]}" \) $null_terminated
Run Code Online (Sandbox Code Playgroud)

可以工作,但前提$null_terminated是不包含任何通配符或来自 IFS 的字符。

正在做:

if [[ -p '/dev/stdin' ]]; then
  extra_args=(-print0)
else
  extra_args=()
fi

find -mindepth 1 -maxdepth 1 ! \( "${args[@]}" \) "${extra_args[@]}"
Run Code Online (Sandbox Code Playgroud)

不会有问题。

Bourne/POSIXly,你可以这样做:

set -- find . ! -name . -prune ! \( "$@" \)
[ -p /dev/stdin ] && set -- "$@" -exec printf '%s\0' {} +
"$@"
Run Code Online (Sandbox Code Playgroud)

对于一个论点:

unset extra_arg; [ -p /dev/stdin ] && extra_arg=-print0
find . ! -name . -prune ! \( "$@" \) ${extra_arg+"$extra_arg"}
Run Code Online (Sandbox Code Playgroud)

(请注意,这-print0不是 POSIX)。