2016-08-24 4 views
0

Я хотел бы проверить, содержит ли имя переменной, заданной как аргумент функции, определенную строку, и выполняет разные действия, если это делает/не делает.Bash определить, если имя переменной содержит строку

Вот очень общее описание того, что я хочу добиться:

#!/bin/bash 

varA="a" 
varB="b" 
varC="c" 
varD="d" 
varE="e" 
varF="f" 

function1() 
{ 
     if name of argument $1 does not contain "A"; then 
       echo "no A in $1" 
       further actions done using the value of varA and others... 
     elif name of argument $1 contains "A"; then 
       echo "A in $1" 
       further actions done using the value of varA and others... 
     fi 
} 

function1 $varA $varB $varC 
function1 $varD $varE $varF  

И при запуске это даст

A in varA 
no A in varD 

Я видел, при этом некоторые исследования, что имя переменной может будем называть $ {! var @}, так что вот код, который я пробовал:

1 #!/bin/bash 
    2 
    3 varA="a" 
    4 varB="b" 
    5 varC="c" 
    6 varD="d" 
    7 varE="e" 
    8 varF="f" 
    9 
10 function1() 
11 { 
12   if [[ "${[email protected]}" != *"A" ]]; then 
13     echo "no A in $1" 
14   elif [[ "${[email protected]}" == *"A" ]]; then 
15     echo "A in $1" 
16   fi 
17 } 
18 
19 function1 $varA $varB $varC 
20 function1 $varD $varE $varF 

Но при запуске В этом сценарии приводятся следующие сообщения об ошибках:

./testx.sh: line 12: ${[email protected]}: bad substitution 
./testx.sh: line 12: ${[email protected]}: bad substitution 

Любая помощь будет очень признательна! Спасибо

+1

Я не думаю, что это возможно с позиционными аргументами. Когда функция вызывается, переменные заменяются значениями, поэтому для ссылки на нее нет имени переменной. – karakfa

+0

Вызов фактически 'function1 $ varA $ varB $ varC' (см. Мой второй код), и я не использую значения переменных здесь, но в реальном скрипте, над которым я работаю, я хочу использовать их значения для выполните другие действия в функции. – arielle

+0

@arielle: ОК. В этом случае это невозможно. Обратите внимание, что '$ {! Prefix @}' "Расширяется до имен переменных, имена которых начинаются с' prefix'; то есть эквивалент файла glob 'prefix *', но над именами переменных оболочки. 'prefix' - это всего лишь строка символов. – rici

ответ

1

Если вы хотите "проверить, есть ли имя переменной", то дайте это функции:

function1 varA 

Не содержимое переменной:

function1 $varA    # INCORRECT 

Затем, вы можете проверить имя переменной внутри функции:

if [[ $1 == *A* ]]; then 

Сценарий может быть такой:

#!/bin/bash 

function1() 
{ 
     if [[ $1 == *A* ]]; then 
       echo "A in $1" 
     else 
       echo "no A in $1" 
     fi 
} 

function1 varA varB varC 
function1 varD varE varF 

ЕСЛИ вам нужно «значение var» внутри функции, тогда просто используйте это:

value=${!1} 

Это называется «косвенное расширение» внутри man bash.

После этого value будет содержать копию переменной, названной в $1.

Чтобы изменить значение переменной, указываемой $1, используйте:

declare $1=newvalue 

Или, совсем небезопасно, если значение $ 1 может быть установлен внешним пользователем:

eval $1=newvalue 

Использование ${!var*} (или ${[email protected]}) - это список всех переменных, которые используют имя, которое начинаются с var. Не ссылаться на определенную переменную.

$ eval var{A..F}=1    # create the list of variables 
$ echo ${!var*}     # use the expansion to list variables 
varA varB varC varD varE varF 

Расширение ${!1*} должен был список переменных, которые начинаются с 1. Эти имена переменных недопустимы (кроме как позиционные параметры) в bash. То есть: имена переменных не могут начинаться с числа.

Это расширение является (поэтому) ошибкой и сообщается об этом как bash.

+0

Это имеет большой смысл! Спасибо, что нашли время, чтобы объяснить это :) – arielle

1

Вы должны были делать

function1 "${!var*}" 

и внутри функции

if [[ "$1" == *"A"* ]] 
then 
    echo "At least one variable name has patttern A" 
fi 
+0

, но в моем реальном сценарии я хочу использовать значение первого аргумента для выполнения большего количества действий внутри функции, а не только от ее имени, будет ли она работать? – arielle

+0

Может быть невозможно с позиционными аргументами @arielle. :( – sjsam

+2

Я не знал синтаксиса '' $ {! Var *} "', чтобы найти все определенные переменные, начиная с 'var'. Спасибо! – anishsane

0

Помните, скрипт вы ищете проверки только для первой переменной вызова функции (то есть $ 1). Так что призыв к function1 $varA $varB $varC будет проверять только varA

Приведенный ниже код будет делать работу, которую вы ожидаете под псевдо код, который вы написали:

#!/bin/bash 

varA="checkAinvariable" 
varB="b" 
varC="c" 
varD="d" 
varE="e" 
varF="f" 

function1() 
{ 
     if [[ "$1" != *"A"* ]]; then 
       echo "no A in $1" 
     elif [[ "$1" == *"A"* ]]; then 
       echo "A in $1" 
     fi 
} 

function1 $varA $varB $varC 
function1 $varD $varE $varF 

выход будет:

A in checkAinvariable 
no A in d 
+1

Операция op говорит 'имя переменной, заданной как аргумент функции, содержит определенную строку'. Это имя не значение pal! – sjsam