在 bash 脚本中实现批处理选项 --yes

che*_*rov 5 bash shell-script

我有几个用户输入语句,例如:

read -r -p "Do u want to include this step (y) or not (n) (y/N)"? answer
if [[ "$answer" =~ ^[Yy]$ ]]; then 
    ...
fi
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方法来自动对所有这些问题回答“是”。想象一个非交互式会话,其中用户使用--yes选项调用脚本。没有进一步的stdin输入。

我现在能想到的唯一方法是在每个if 语句上添加另一个条件。

有什么想法吗?

jes*_*e_b 10

您可以使用yes(1),它根本不需要对脚本进行任何修改。

$ grep . test.sh
#!/bin/bash
read -rp 'What say you? ' answer
echo "Answer is: $answer"
read -rp 'And again? ' answer2
echo "Answer 2 is: $answer2"
$
$ yes | ./test.sh
Answer is: y
Answer 2 is: y
Run Code Online (Sandbox Code Playgroud)

它将无限期地重复指定的咒骂,如果没有指定,它将默认y


mur*_*uru 10

如果您read仅用于这些问题,并且始终调用变量answer,请替换read

# parse options, set "$yes" to y if --yes is supplied
if [[ $yes = y ]]
then
    read () {
        answer=y
    }
fi
Run Code Online (Sandbox Code Playgroud)

  • 这很简洁,但可能会让不了解脚本的读者感到困惑。我建议至少重命名该函数以缓解这种情况(并允许在脚本的其他地方使用通常意义上的“read”,如果需要的话)。 (3认同)
  • @ilkkachu 啊,但是那样的话,OP 将不得不修改 `read` 的用法,这是他们希望避免的。为了避免混淆,最好记录读取正在被覆盖。他们总是可以使用“内置读取”来实现普通意义上的。 (2认同)

ilk*_*chu 6

我会将整个决策逻辑放在一个函数中,既检查自动模式,也可能查询用户。然后在每种情况下从主级别调用它。want_act下面本身返回真/假,不需要在主级别进行字符串比较,读者很清楚条件的作用。

#!/bin/bash
[[ $1 = --yes ]] && yes_mode=1

want_act() {
    [[ $yes_mode = 1 ]] && return 0
    read -r -p "Include step '$1' (y/n)? " answer
    [[ $answer = [Yy]* ]] && return 0
    return 1
}

if want_act "frobnicate first farthing"; then
    echo "frobnicating..."
fi
Run Code Online (Sandbox Code Playgroud)

  • 从维护的角度来看,这是一个比覆盖“read”更好的选择。另一方面,如果尚未提供该选项,我会自己建议。+1 给你们俩,我想。 (2认同)