While 循环出现意外的 bash 退出

Rob*_*t J 2 bash

问题陈述:

while当我使用时,我似乎遇到了循环问题set -e

 1  #!/bin/bash
 2  # This is a script to perform initial configurations of CentOS 7.2
 3  # Written by Robert J.
 4  
 5  # Exit if unexpected condition
 6  set -e;
 7  
 8  # Simple die function
 9  dieaquickdeath(){
10      code=$1;
11      message=$2;
12      printf "$message\n";
13      exit "$code";
14  }
15  
16  #
17  ## There is an initial prompt here that was removed for simplification.
18  #
19  InputPassword1=1
20  InputPassword2=2
21  
22  # Sanity check for password
23  unset n;
24  while [[ "$InputPassword1" != "$InputPassword2" ]];
25  do
26      # Counter
27      ((n++));
28  
29      # Prompt for new password
30      printf "\nPasswords do not match\n";
31      read -sp "Enter password: " InputPassword1;
32      echo;
33      read -sp "Re-enter password: " InputPassword2;
34  
35      # End loop after passwords match.
36      [[ "$InputPassword1" == "$InputPassword2" ]] &&
37          break;
38  
39      # End loop after 3 attempts
40      [[ "$n" == 3 ]] &&
41          dieaquickdeath 1 "Third failed password attempt";
42  
43  done;
Run Code Online (Sandbox Code Playgroud)

尝试的解决方案:

我最初认为这可能只是因为测试的退出代码,所以我临时硬连线了 true 语句以进行故障排除(这仍然不起作用):

36      [[ "$InputPassword1" == "$InputPassword2" ]] &&
37          break || 
38          true;
39  
40      # End loop after 3 attempts
41      [[ "$n" == 3 ]] &&
42          dieaquickdeath 1 "Third failed password attempt" || 
43          true;
Run Code Online (Sandbox Code Playgroud)

在没有set -e; 的情况下运行时,这似乎没有任何问题;

[root@Wiki ~]# vi testing
[root@Wiki ~]# ./testing
[root@Wiki ~]# grep -v "set -e" testing > test2
[root@Wiki ~]# ./test2
-bash: ./test2: Permission denied
[root@Wiki ~]# chmod +x test2
[root@Wiki ~]# ./test2

Passwords do not match
Enter password: 
Re-enter password: 
Passwords do not match
Enter password: 
Re-enter password: 
Passwords do not match
Enter password: 
Re-enter password: Third failed password attempt
[root@Wiki ~]#
Run Code Online (Sandbox Code Playgroud)

问题:

  • 有没有人看到我的意外出口在哪里?
  • 这是我不知道的一些 bash 警告的原因吗?

我觉得我一直盯着这个看太久了。

在此先感谢大家都很棒。

Joh*_*024 5

要查看它停止的位置,请运行bash -x testing

$ bash -x testing
+ set -e
+ InputPassword1=1
+ InputPassword1=2
+ unset n
+ [[ 2 != '' ]]
+ (( n++ ))
Run Code Online (Sandbox Code Playgroud)

它停止是因为n(实际上)为零。观察:

$ unset n; ((n++)); echo code=$?
code=1
Run Code Online (Sandbox Code Playgroud)

退出代码1表示失败。因此,set -e在这里终止执行。

以下是两种可能的解决方案,它们将返回零(成功)退出代码:

$ unset n; ((++n)); echo code=$?
code=0
$ unset n; ((n++)) || true; echo code=$?
code=0
Run Code Online (Sandbox Code Playgroud)

一般来说,正如这里所讨论的,会set -e做一些奇怪的事情。它的使用是有争议的。

  • @Robert J,就像`set -e` 一样,您也可以将它放在脚本中,例如,`set -x` 用于测试目的,然后将其注释掉或将其删除。 (2认同)
  • 和`set +x` 以“关闭它”,并`export PS3='$LINENO >'` 让它显示正在执行的代码的行号。祝你们好运。 (2认同)