Независимый от оболочки способ установки переменной среды - PullRequest
0 голосов
/ 25 мая 2018

Мне нужно сделать скрипт, который может изменять переменную окружения вызывающей оболочки.Чтобы позволить сценарию изменять переменную среды, я использую source <script>, и я хочу, чтобы и bash, и tcsh могли использовать один и тот же сценарий.

Я поражаюсь тем фактом, что tcsh и bash имеют разныеif синтаксис, поэтому я даже не могу переключаться между ними внутри скрипта.Каков наилучший способ справиться с установкой переменной среды?

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Хорошо, ты меня понял .Я провел некоторые эксперименты, и вы могли бы сделать это с помощью одного сценария.( Обновление: Я немного усложнил оригинал, вот гораздо лучшее решение, которое также работает в zsh.)

То, что вы пытаетесь создать, это bash / tcsh polyglot (на данный момент мы предполагаем, что вы не хотите поддерживать другие оболочки).Я положу здесь фактический полиглот, затем некоторые пояснения и предостережения:

if ( : != : ) then
    echo "In a POSIX shell or zsh or ksh"
else
    echo "In tcsh"
    alias fi :
endif
fi

Первая строка действительно интересна в этом полиглоте.

В POSIX sh она создаетsubshell для запуска команды : с двумя аргументами, == и :.: всегда возвращает true, поэтому выполняется первая ветвь оператора if.(Обычно точка с запятой используется после условия в операторе if, но на самом деле работает близкая точка, поскольку оба являются управляющими операторами , которые можно использовать для завершения простой команды - условие в операторе if на самом деле представляет собой список , но оно вырождается в простую команду , как описано в руководстве по Bash.)

в tcsh, он сравнивает строку : со строкой : - поскольку они равны, и мы проверяли на неравенство, он выполняет вторую ветвь.

Последняя строка второй (tcsh) ветки простогарантирует, что tcsh не будет жаловаться, что заключительный fi не является командой.В первом ответвлении нет необходимости в подобном псевдониме, поскольку endif все еще находится во втором ответвлении оператора if в отношении оболочки POSIX.


Что касается предостереженийвы несколько ограничены в том, что вы можете сделать в разделе оболочки POSIX: например, вы не можете определить какие-либо функции с синтаксисом POSIX (foo() {...}), так как tcsh будет жаловаться на скобки, хотя синтаксис Bash(function foo {...}) работает.Я предполагаю, что есть аналогичные ограничения в разделе tcsh.

Этот полиглот также не работает в рыбе, хотя он работает в zsh.(Вот почему условие : != :, а не что-то вроде : == '' - в zsh == раскрывает путь к команде =, которая не существует.) Кажется, она также работает в ksh (хотяв этот момент он превращается в меньше полиглота, больше в программу "is this shell csh" ...)

0 голосов
/ 25 мая 2018

Ненавижу писать ответ, который мало чем расширяет комментарий, сделанный @ Josh к исходному вопросу.Но я считаю важным отметить, что вам нужно учитывать не только оболочки POSIX 1003, такие как bash, и классические оболочки, такие как csh / tcsh.Вам также необходимо рассмотреть современные альтернативы, такие как fish , которые не совместимы ни с одной из этих оболочек.

Как заметил @Josh, решение заключается в использовании кода «bridge» для каждой из вызывающих оболочеккоторый отображает информацию в синтаксис, соответствующий для вызывающей оболочки.

...