【问题标题】:How to run through password function twice with different variables?如何使用不同的变量两次运行密码功能?
【发布时间】:2017-05-17 17:20:07
【问题描述】:

我有个密码功能是从How do I echo stars (*) when reading password with read?借来的

我尝试对其进行调整,以便我可以运行两次该函数以进行密码确认,然后评估 2 个密码以确定它们是否匹配,但我似乎缺少一些关于 bash 在这种情况下如何工作的基础知识。

我尝试用$1 替换PASSWORD,但不断收到command not found 错误

passWord() {
  unset PASSWORD
  unset CHARCOUNT
  stty -echo
  CHARCOUNT=0
  while IFS= read -p "$PROMPT" -r -s -n 1 CHAR; do
      # Enter - accept password
      if [[ $CHAR == $'\0' ]] ; then
          break
      fi
      # Backspace
      if [[ $CHAR == $'\177' ]] ; then
          if [ $CHARCOUNT -gt 0 ] ; then
              CHARCOUNT=$((CHARCOUNT-1))
              PROMPT=$'\b \b'
              PASSWORD="${PASSWORD%?}"
          else
              PROMPT=''
          fi
      else
          CHARCOUNT=$((CHARCOUNT+1))
          PROMPT='*'
          PASSWORD+="$CHAR"
      fi
  done
  stty echo; echo
  ${1}=${PASSWORD}
}

echo -n "Enter the password > "
passWord passOne
echo -n "Please re-enter the password > "
passWord passTwo
if [[ $passOne == $passTwo ]]; then
   PASSWORD=$passOne
else
   echo "Passwords did not match, please try again."
fi

更新 这是最新更新的脚本

#!/bin/bash
passWord() {
  unset password
  local prompt char
  stty -echo
  charcount=0
  while IFS= read -p "$prompt" -r -s -n 1 CHAR; do
    # Enter - accept password
    if [[ $char == $'\0' ]] ; then
      break
    fi
    # Backspace
    if [[ $char == $'\177' ]] ; then
      if [ $charcount -gt 0 ] ; then
        charcount=$((CHARCOUNT-1))
        prompt=$'\b \b'
        password="${password%?}"
      else
        prompt=''
      fi
    else
      charcount=$((charcount+1))
      prompt='*'
      password+="$char"
    fi
  done
  stty echo; echo
}

echo -n "Enter the password > "
passWord
pass1=$password
echo -n "Please re-enter the password > "
passWord
pass2=$password
if [[ "$pass1" == "$pass2" ]]; then
  PassWord=$pass1
else
  echo "Passwords did not match, please try again."
fi

【问题讨论】:

  • Shellcheck.net 告诉您有关您的代码的哪些信息?
  • @David 关于通配符和分词的一些警告,但不能解决我的问题。你在暗示什么?
  • 问题是${1}=${PASSWORD} 没有将${PASSWORD} 分配给passOnepassTwo。 (如果没有eval,你不能以这种方式进行变量赋值——不推荐)替换为echo ${PASSWORD},然后在外面做类似passOne=$(passWord)的事情,passTwo也是如此。关键是 shellcheck 告诉你 passOnepassTwoReferenced but Unassigned
  • @DavidC.Rankin 知道了,谢谢。
  • 您还应该在函数顶部使用local PROMPT(或unset PROMPT),以防止在第二个密码提示的开头回显*

标签: bash function variables


【解决方案1】:

您缺少 shell 的声明。
请在第一行添加一个 shebang:

#!/bin/bash

变量的赋值(${1}=${PASSWORD} 行)不起作用。
解决它的一种方法(不推荐)是添加 eval:

eval "${1}=${PASSWORD}"     # don't use quite risky.

但这会使任何输入成为安全问题,您应该使用其他行。

一种解决方案是使用声明(bash 4.2+):

declare -g "${1}=${PASSWORD}"

-g 是必需的(从 bash 4.2 开始是必需的并且可用)来更改常规变量(不是函数的本地变量)。

或者使用 printf(从 bash 3.1 开始):

printf -v "${1}" '%s' "${PASSWORD}"

除此之外,您应该为函数内部使用的变量添加一个本地命令以避免与外部变量冲突,并且应该在循环之前添加一个PROMPT='',以避免在第二次调用函数时打印初始星号时间。

应该说应该避免在CAPS中使用变量。 CAPS 中的变量表示环境变量,其余变量使用小写以避免冲突。

【讨论】:

  • 所有好的解决方案,我一直更喜欢从函数输出并使用进程替换,(例如passOne=$(passWord)),但@没有任何问题987654329@ 或 declare -g.
  • @DavidC.Rankin 好吧,printf -v 避免了由 $(…) 引起的启动(和关闭)额外子 shell 的延迟。延迟通常很小,但可以测量(通常约为 ~1 毫秒)。
猜你喜欢
  • 2022-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
相关资源
最近更新 更多