Код, который не работает в bash, но останавливается с сообщением об ошибке в csh? - PullRequest
3 голосов
/ 22 ноября 2011

Я работаю с кем-то над проектом анализа данных, и мы часто документируем шаги, которые выполняем, помещая их в небольшие сценарии оболочки. Проблема в том, что я использую bash, а другой человек использует csh. Другой человек имеет привычку использовать source для запуска этих сценариев вместо того, чтобы выполнять их напрямую (эта привычка, вероятно, восходит к временам, когда порождение дополнительной оболочки было чрезмерной тратой ресурсов, поэтому она, вероятно, слишком укоренилась, чтобы измениться), и Я хочу, чтобы мои скрипты (которые, конечно, были скриптами bash) просто останавливались с сообщением, напоминающим пользователю, что они должны запускать их с помощью bash вместо csh, когда этот человек получает их из csh. В то же время я хотел бы, чтобы они продолжали функционировать как bash-скрипты.

Итак, есть ли какой-то код, который я могу поместить в начало моих сценариев, который не используется в bash, но сообщит об ошибке и отменит выполнение остальной части файла (но не уничтожит саму оболочку) при получении из cshell?

Ответы [ 2 ]

6 голосов
/ 22 ноября 2011

Это сложнее, чем я думал, из-за древнего аромата переменной замены csh.Однако $?BASH_VERSION расширяется до 0 (не установлено) в csh и до 0BASH_VERSION (или независимо от того, какой была последняя команда RV) в bash.Итак,

test "$?BASH_VERSION" = 0 && exit 1

должно сработать.

1 голос
/ 06 февраля 2014

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

Вы можете использовать скудные навыки разбора строк в csh. Следующее выполняется чисто во всех оболочках, включая KSH, BASH, ZSH, CSH и SH на всех платформах, на которых я его тестировал (Linux, AIX, HP-UX, Solaris):

test '\\' = "\\" && echo "CSH detected"

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

Однако это только половина ответа, что вы хотите сделать, если не хотите просто выйти из сценария, если обнаружена «неправильная» оболочка? Ну, вы, возможно, захотите иметь в своем сценарии партию Bournish sh и партию csh.

Если вы можете ограничить код csh кодом, который не использует одинарные кавычки, везде будет работать следующее:

test '\\' = "\\" && goto csh
# Just skip the block containing the csh code. Again we use csh's meagre string parsing capabilities against it.
false || csh_code_block='
csh:
  ... csh code goes here ...
  exit 0
'
... sh code goes here ...

Если вы не беспокоитесь о csh в HP-UX (что кажется немного лучше, чем другие при разборе), вы можете заменить многострочную команду в одинарных кавычках документом «ЗДЕСЬ» (<<CSH_BLOCK ... CSH_BLOCK). Вы также не можете просто изменить порядок, так как оператору 'goto' не нравится весь синтаксис, который он пропускает.

...