$? проблема со скриптом tcsh

Меня смущает проблема со сценарием оболочки tcsh. (для работы нет выбора в оболочке, я застрял с ней)

Элементы enableThingN ниже — это переменные среды оболочки, установленные другими вещами перед запуском этого сценария csh с использованием оболочки tcsh. Здесь они вообще не устанавливаются в одном и том же сценарии, а только оцениваются здесь.

Сообщение об ошибке:

enableThing1: Undefined variable.

Код:

if ( ( $?enableThing1  &&  ($enableThing1 == 1) ) || \
     ( $?enableThing2  &&  ($enableThing2 == 1) ) || \
     ( $?enableThing3  &&  ($enableThing3 == 1) ) || \
     ( $?enableThing4  &&  ($enableThing4 == 1) )      ) then

    set someScriptVar  = FALSE
else
    set someScriptVar  = TRUE
endif

Итак, насколько я понимаю, первая часть большого условия if состоит в том, чтобы проверить, определен ли enableThing1 вообще или нет, используя магию $?enableThing1. Если он определен, то идем дальше и проверяем, что значение равно 1 или чему-то еще. Если он не определен, то пропустите часть ==1 проверки той же самой переменной оболочки и перейдите к тому, определен ли enableThing2 вообще или нет, и так далее.

Поскольку кажется, что я проверяю существование и намерен избежать проверки значения, если оно вообще не определено, где я ошибся?

Я искал здесь в stackoverflow и в Google в целом, но результатов мало, и я не получил ответа, например:

https://stackoverflow.com/questions/16975968/what-does-var-mean-in-csh

person billt    schedule 07.02.2019    source источник


Ответы (1)


Оператор if для проверки значения переменной требует, чтобы переменная существовала.

if ( ( $?enableThing1  &&  ($enableThing1 == 1) ) || \
#                             ^ this will fail if the variable is not defined.

Таким образом, условие if превращается в

if ( ( 0  &&  don'tknowaboutthis ) || \

и он падает ровно.

Предполагая, что вам не нужна лестница if и функциональные возможности для добавления в этот список переменных для проверки, вы можете попробовать следующее решение:

#!/bin/csh -f

set enableThings = ( enableThing1 enableThing2 enableThing3 enableThing4 ... )

# setting to false initially
set someScriptVar = FALSE

foreach enableThing ($enableThings)

# since we can't use $'s in $? we'll have to do something like this.
  set testEnableThing = `env | grep $enableThing`

# this part is for checking if it exists or not, and if it's enabled or not
  if (($testEnableThing != "") && (`echo $testEnableThing | cut -d= -f2` == 1 )) then
     #  ^ this is to check if the variable is defined       ^ this is to take the part after the =
#                                                             d stands for delimiter
# for example, the output of testEnableThing, if it exists, would be enableThing1=1
# then we take that and cut it to get the value of the variable, in our example it's 1

# if it exists and is enabled, set your someScriptVar
    set someScriptVar = TRUE
# you can put a break here since it's irrelevant to check 
# for other variables after this becomes true
    break
  endif
end

Это работает, потому что мы работаем только с одной переменной, «testEnableThing», которая всегда определена из-за того, как это работает. Это может быть пустая строка, но она будет определена, так что наш оператор if не сработает.

Надеюсь, это решит это для вас.

person Vineeth    schedule 07.02.2019
comment
Как и в автономном режиме, добавление -w к grep делает его еще лучше, так как произошло неожиданное столкновение имени переменной оболочки без -w, и grep вывел несколько строк для нескольких переменных, которые запутали оператор if и выдали ошибку о синтаксисе if. . Благодарю вас! Извините, что у меня недостаточно очков репутации, чтобы проголосовать за это решение. - person billt; 09.02.2019