Переменная сценария Bash, а не строка - PullRequest
0 голосов
/ 10 сентября 2011
#!/bin/bash

testFunction () {
read -p "Question" $1
echo $1
}

testFunction foo

Мое намерение - прочитать, чтобы назначить пользовательский ввод переменной в аргументе, а затем вывести его, однако вместо того, чтобы повторить пользовательский ввод, echos foo.

Я понимаю, что, чтобы обойти это, я могу использовать Переадресация Bash примерно так:

#!/bin/bash

testFunction () {
read -p "Question" $1
echo ${!1}
}

testFunction foo

Однако я бы предпочел не использовать этот метод, поскольку не все языки имеют переменную косвенность (и я скоро перейду на новый язык). Есть ли другой способ заставить его выглядеть на foo, как если бы это была переменная? Спасибо.

Ответы [ 3 ]

2 голосов
/ 10 сентября 2011

На любом языке, который имеет eval -подобную конструкцию, можно интерпретировать строку как имя переменной. В Баш:

eval echo \$$foo

В Python:

from __future__ import print_function
eval ( "print (" + foo + ")" )

В большинстве языков, в которых отсутствует eval, это невозможно.

0 голосов
/ 10 сентября 2011

Вы можете сделать это с помощью eval

testFunction () {
    eval 'read -p "Enter Y or N: " '$1
    eval 'echo $'$1
}

testFunction foo

Но eval не является инструментом, который следует использовать легкомысленно. То, что ты делаешь, вероятно, сумасшедшее. Вы должны использовать такой подход

testFunction () {
    read -p "Enter Y or N: " bar
    case "$bar" in
        [YyNn]) return 0 ;;
    esac
    return 1
}

testFunction && foo=valid

Таким образом, вам не нужно перепроверять $foo позже, его значение является ответом на вопрос «Был ли ввод действительным?»

Но, может быть, позже вы захотите сделать что-то другое, основываясь на том, сказал ли пользователь y или n, что, как я подозреваю, и является причиной бессмысленности «давайте динамически создадим переменную из функции». В этом случае вы можете сделать что-то вроде

testFunction () {
    read -p "Enter Yes or No: " bar
    case "$bar" in
        [Yy][Ee][Ss]|[Yy]) printf y ;;
        [Nn][Oo]|[Nn]) printf n ;;
    esac
}

foo=$(testFunction)

Это функционально аналогично версии eval, но гарантирует, что вы получаете только известные значения в foo. Позже вы можете проверить значение в foo.

if [ -z "$foo" ] ; then
        echo invalid input
elif [ "$foo" = "y" ] ; then
        echo answered yes
elif [ "$foo" = "n" ] ; then
        echo answered no 
fi

И вы можете сохранить этот код простым, потому что все возможные значения уже известны.

0 голосов
/ 10 сентября 2011

это то, что я бы сделал (основываясь на вашем комментарии):

testFunction () {
  read -p "yes or no? [YynN] "  bla
  if [ "$bla" = 'Y' -o "$bla" = 'y' ]; then
      return 0
  fi
  return 1
}

if testFunction; then
  echo "it was yes"
fi

или

testFunction () {
  read -p "yes or no? [YynN] "  bla
  if [ "$bla" = 'Y' -o "$bla" = 'y' ]; then
      echo 1
  else
      echo 0
  fi
}

foo=`testFunction`
echo $foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...