Сценарий оболочки использует аргументы первого запуска при втором запуске - PullRequest
1 голос
/ 29 июня 2010

Я работаю в Korn Shell и пытаюсь запустить простой скрипт chdb, который я написал. Если запустить без аргументов, он предлагает пользователю список баз данных и ждет выбора. Если вызывается с одним числовым аргументом, он автоматически сделает выбор для пользователя.

Пример:

> . chdb
Select the database sid from the following:
  1) testdb1
  2) testdb2
  3) testdb3

Selection: 2 <-- user entered

Environment is now set up for testdb2.
>. chdb 2
Environment is now set up for testdb2.
>

Моя проблема в том, что когда я запускаю скрипт с аргументом, как указано выше, а затем пытаюсь запустить его снова без аргументов, он все равно использует старые аргументы.

Пример:

> . chdb 2
Environment is now set up for testdb2.
> . chdb
Environment is now set up for testdb2.
>

РЕДАКТИРОВАТЬ: я использую точку, потому что я устанавливаю переменные в среде и не хочу вызывать экземпляр дочерней оболочки, иначе установка базы данных не будет работать. Я чувствую, что это может быть источником моей проблемы, но я не уверен, как обойти это.

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

Ответы [ 4 ]

1 голос
/ 25 мая 2015

Если вы используете скрипт с '.'чтобы установить переменные окружения, тогда любые переменные, которые вы объявляете в этом скрипте, автоматически будут глобальными и передаются в сеанс вызывающей оболочки.

Существует три подхода, позволяющих изолировать ваши переменные и сделать их непостоянными:

1.Инициализировать переменные

Если вы используете одну переменную для захвата выбора пользователя, например, DBSELECTION, независимо от того, переданы ли вы в командной строке или введены в интерактивном режиме, вы можете запустить сценарий, инициализируяпеременная в пустую строку;

DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi

- где "interactiveMode" - ваш определенный процесс получения выбора пользователя.Конечно, имена ваших методов или функций могут отличаться.

2.Unset Variables

Если вы используете временные переменные для регистрации выбора пользователя - как показано выше, DBSELECTION, вы можете захотеть сбросить переменную в конце вашего скрипта;

DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi
unset DBSELECTION

3.Определите локальные, а не глобальные переменные

Если вы используете временные переменные, может быть более целесообразно определять их локально (используя набор типов), а не глобально, чтобы они не сохранялись за пределами функции внутрикоторые они определили.

typeset DBSELECTION=""
if [ "$1ZZZ" != "ZZZ" ] ; then 
    DBSELECTION=$1
else
    interactiveMode
fi

Таким образом, ksh будет обрабатывать переменную вместо вас, а не явно сбрасывать ее самостоятельно.

1 голос
/ 29 июня 2010

Попробовать: после input=$arg, сделать unset arg или цитату if [["$#" -ne "1"]]

0 голосов
/ 30 июня 2010

Я нашел способ справиться с этим. Я добавил set -- в конце моего скрипта, чтобы он сбрасывал все аргументы.

Для тех, у кого есть такая же проблема, set -- очищает все аргументы ($ 1, $ 2, $ 3 и т. Д.). Используйте shift, чтобы удалить только первый ($ 1), или shift num, чтобы сбросить первые num аргументы. Следовательно, shift $# также очистит все аргументы.

0 голосов
/ 30 июня 2010

Также - вы запускаете код 'sourced', что означает, что все переменные окружения, объявленные в скрипте, все еще остаются там, когда вы запустите его снова.

Попробуйте

. / Chdb

вместо

.chdb

...