Использование bash-скрипта с оператором read и return - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть следующий скрипт:

#!/bin/bash
#
# Example script for validating SVN credentials.

var_svn_user_name=
var_svn_password=

function get_svn_credentials()
{
  # First, get the credentials from the user
  read -r -p "Please enter SVN User Name: " var_svn_user_name
  echo -n "Please enter SVN Password:  "
  read -r -s var_svn_password
  echo ""
  echo "----------------"
  echo "The SVN User Name is:     ${var_svn_user_name}"
  echo "The SVN User Password is: ${var_svn_password}"

  # Next, validate provided credentials
  echo -n "Validating credentials... "
  #var_ret=$(svn list --username "${var_svn_user_name}" --password \
  #        "${var_svn_password}" ${var_url} ${var_cfg} ${var_opt}=${var_val} \
  #        --no-auth-cache --non-interactive 2>&1 | grep "Authentication failed")
  if [[ $var_ret == "" ]]
  then
    echo 'Success'
  else
    echo 'Failed'
  fi
}

function main()
{
  # EXAMPLE Call #1
  #result=$(get_svn_credentials)  # FAILURE
  # EXAMPLE Call #2
  get_svn_credentials           # SUCCESS

  echo "Return value is: $result"
  if [[ $var_ret == "Success" ]]
  then
    echo "SVN User Name and Password was validated."
  else
    echo "SVN User Name and Password was NOT validated."
  fi
}

main "$@"

Почему при комментировании примера 2 и раскомментировании примера 1 эхо пароля не отображается до тех пор, пока не будет выполнено чтение?

Я пытаюсь понять, как заставить оператор return работать как оператор возврата в стиле функции C.

Кто-нибудь сможет помочь с этим?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

@ Чепнер объяснил проблему.Другой вариант, если вы просто возвращаете успех / неудачу, вместо использования stderr не захватывать, а возвращать числовой результат:

if [[ $var_ret == "" ]]; then
    return 0
else
    return 1
fi

Выполнить как во втором примере:

get_svn_credentials           
res=$? #0 for success, 1 for failure.
if [ $res -neq 0 ]; then
    echo "-E- Oh no!"
    exit $res
fi

Таким образом, вы можете использовать как stdout, так и stderr как обычно, и использовать обычный доступный механизм неудачного завершения.Я думаю, что для этих типов функций это может быть безопаснее и яснее, но это мнение.@Barmar отмечает, что в сложных случаях, когда вам действительно нужны строки, это не будет работать.

0 голосов
/ 25 сентября 2018

Вы записываете приглашение в стандартный вывод, который фиксируется подстановкой команд.Вместо этого запишите его в стандартную ошибку (как это делает read -p).

function get_svn_credentials()
{
  # First, get the credentials from the user
  read -r -p "Please enter SVN User Name: " var_svn_user_name
  echo -n "Please enter SVN Password:  " >&2
  read -r -s var_svn_password

  {
    echo ""
    echo "----------------"
    echo "The SVN User Name is:     ${var_svn_user_name}"
    echo "The SVN User Password is: ${var_svn_password}"
  } >&2

  # Next, validate provided credentials
  echo -n "Validating credentials... "
  #var_ret=$(svn list --username "${var_svn_user_name}" --password \
  #        "${var_svn_password}" ${var_url} ${var_cfg} ${var_opt}=${var_val} \
  #        --no-auth-cache --non-interactive 2>&1 | grep "Authentication failed")
  if [[ $var_ret == "" ]]
  then
    echo 'Success'
  else
    echo 'Failed'
  fi
}

Тем не менее, не полагайтесь на вывод, чтобы определить, был он успешным или нет;просто используйте статус выхода.

get_svn_credentials () {
  local user_name password
  # First, get the credentials from the user
  read -r -p "Please enter SVN User Name: " user_name
  read -r -p "Please enter SVN Password:  " -s password

  {
    echo ""
    echo "----------------"
    echo "The SVN User Name is:     ${user_name}"
    echo "The SVN User Password is: ${password}"
  } >&2

  # Next, validate provided credentials
  # Let the exit status of grep -q be the exit status
  # of the function
  printf '%s\n' "Validating credentials... " >&2
  svn list --username "${user_name}" \
           --password "${password}" \
           "${var_url}" ${var_cfg} "${var_opt}=${var_val}" \
          --no-auth-cache --non-interactive 2>&1 |
    grep -q "Authentication failed"
}

main () {
  if get_svn_credentials
  then
    echo "SVN User Name and Password was validated."
  else
    echo "SVN User Name and Password was NOT validated."
  fi
}

main

(Примечание: вы должны , вероятно, заключить в кавычки $var_cfg, но, возможно, это на самом деле список опций. В этом случае вам следуетвместо этого использовать массив, но поскольку по одному только этому коду это невозможно определить, я оставил его без кавычек.)

...