Я ищу простой и надежный способ получить имя текущей оболочки из скрипта или файла источника ( не из командной строки). Я хотел бы просто сделать, $(basename "$SHELL")
но если моя оболочка входа в систему zsh
и у меня есть следующий код в some_script.sh
this_shell=$( basename "$SHELL" )
echo "The Shell is $this_shell"
echo "The Shell is $0"
и я запускаю его bash some_script.sh
, он по-прежнему перечисляет zsh
вместо того, bash
чтобы использовать интерпретатор /bin/bash
. Я не уверен, почему разработчики оболочек решили показывать оболочку по умолчанию вместо текущей, но, похоже, это то, с чем мы застряли.
Есть и другие слегка похожие вопросы ( здесь и здесь ), но их ответы во многом не отвечают.
- Они часто предполагают, что пользователь пытается выяснить, какую интерактивную оболочку они используют в настоящее время, но это безумие. Я знаю, в какую оболочку я набираю команды - мне нужен код, который можно запустить где угодно, чтобы определить, какую оболочку он использует.
- Они часто дают несколько разных вещей, чтобы попробовать - опять же, как будто вы находитесь в командной строке и можете просто возиться, пока не узнаете, что используете bash - но мне нужна одна вещь, которая была бы надежной во всех контекстах.
- Они часто дают вещи, которые совершенно бесполезны из сценариев, например
echo $0
. Это не так, как показано в сценарии выше. (Да, он работает в командной строке интерактивной оболочки, но почему бы вам никогда не узнать, какую оболочку вы используете?) - Иногда они дают команды, которые (в моих ограниченных тестах) включают в себя правильную информацию, например
ps -p $$
, но не имеют кросс-платформенных, совместимых с оболочкой команд sed / awk, чтобы передать их, чтобы получить только имя оболочки и игнорировать другую информацию, которая появляется для езды. - Они включают в себя вещи, которые будут работать только на пару оболочек, как
$BASH_VERSION
и$ZSH_VERSION
. Я хочу поддержать как много раковин , насколько это возможно, напримерfish
,csh
,tcsh
.
Как мне надежно и точно обнаружить любую текущую оболочку? Я ищу что-то, что будет работать на разных платформах, в скриптах и для максимально возможного количества оболочек 1 .
ОБНОВЛЕНИЕ : Когда я отправил этот вопрос, я ожидал, что в снарядах был встроен какой-то объект, чтобы дать нам эту информацию, что, похоже, не так. Поскольку теперь кажется неизбежным полагаться на что-то за пределами оболочек, я должен более четко указать, что я прошу кросс-платформенное решение (которое, хотя и вытекает из моих возражений на другие ответы выше, может быть легко пропустить, если вы не не читайте вопрос внимательно).
Обновление 2 Если кто-то все еще считает, что это дубликат вопроса, касающегося только Linux, поскольку ответ Стефана не только на Linux, то здесь есть различия между тем, что я прошу, и тем, что он предоставил. (Обратите внимание, что то, что он написал, было гениальным, и я его не сбиваю, но это не решает мою проблему.)
- Я ищу что-то простое и надежное , что
- могут быть добавлены в любое определение сценария или функции (которые будут получены с помощью
.zshrc
или.bash_profile
или любой другой ) в отрасли. - Вы не можете использовать его сценарий как внешнюю утилиту, которая передает имя интерпретатора вызывающему сценарию / функции, поскольку оно всегда будет интерпретироваться интерпретатором по умолчанию и возвращать его. Это затрудняет или делает невозможным использование в моих целях. Если это возможно, это все еще очень, очень сложно, и решение для того, чтобы заставить это работать, не дано в ответе. Поэтому он не ответил на мой вопрос, поэтому он не является дубликатом.
Если вы хотите увидеть что-то, что будет работать, взгляните на ShellDetective на GitHub . Это может облегчить понимание различий между тем, что уже присутствует на SE, и тем, что ищет этот вопрос (и был фактически написан для того, чтобы удовлетворить потребности этого вопроса, которые не были удовлетворены где-либо еще).
(PS Если вы не можете поверить, что для этого есть сценарий использования, представьте себе, какие функции .zshrc
используются .bash_profile
, или в .profile
зависимости от того, какой сервер используется и какие оболочки у него есть. Они получены, поэтому у них нет строки Шебанга. Они наиболее полезны, если они могут работать в любой оболочке, но иногда они должны знать, в какой оболочке они находятся, чтобы знать, как себя вести.)
1 Меня не интересуют «раковины», которые не являются раковинами в каком-либо традиционном смысле этого слова. Меня не волнует какая-то оболочка, которую какой-то парень написал для себя. Я имею дело только с реальными оболочками, которые на самом деле встречаются в дикой природе и которые кто-то может использовать при входе на какой-либо сервер, на котором они не могут просто установить какие-либо оболочки, которые они хотят.
sh -c "…"
, а затем выполнить основную часть работы в синтаксисе оболочки POSIX.fish
и использую для запуска скрипта, вы хотитеfish
илиcsh
?Ответы:
У меня были отличные результаты с этой комбинацией:
На Tru64 (OSF / 1) вывод содержит круглые скобки вокруг оболочки. Нажмите,
tr -d '()'
чтобы удалить их.Появляется на всех оболочках, на Solaris 10 и RHEL 5.7 / 6.4. Не тестировал другие дистрибутивы, такие как Debian, Ubuntu или Mint, но я думаю, они все должны работать одинаково; Я также понятия не имею, будет ли работать FreeBSD.
источник
Так что я все еще пытаюсь уточнить это, но я думаю, у меня есть идея, которая будет работать. Как вы заметили, то, что вы пытаетесь сделать, если не невозможно, то чрезвычайно сложно сделать во всех оболочках (каждый вариант, который вы добавляете в полиглот, увеличивает сложность с большей линейной скоростью). вы могли бы сделать это, если бы вы разбились на Bourne (sh, ash, dash, bash, ksh, pdksh, zsh и т. д.) и оболочки в стиле c (csh, tcsh, fish и т. д.), но различия между
csh
вариантами представляют различные интересные вызовы.Итак, давайте изменим и напишем нашу процедуру обнаружения на известном языке (bash со строкой shebang, C, perl, python и т. Д.) И определим имя исполняемого файла родителя. затем мы можем использовать два трюка, чтобы вернуть информацию родителю, а именно: возвращаемое значение (я) и одно слово, записанное для стандартного вывода. На sh спустившихся оболочках мы возвращали бы 0 и записывали имя оболочки, так как все они имеют хорошую обработку обратного удара. в семействе оболочек C мы можем начать увеличивать возвращаемое значение для каждого набора несовместимостей, который нам нужно обойти. Возвращаемые значения более двухсот указали бы на ошибки, начиная со всего, что кажется нормальным, но я просто не могу сказать, кто мой родитель на двухстах.
Внутренняя программа на Linux выглядит просто (
/proc/ppid/exe
это полдела). Я почти уверен, что это можно сделать на bsd с опциями ps, но на данный момент у меня нет работающей системы bsd для тестирования, и моему компьютеру Mac нужен новый жесткий диск (и в любом случае его всего 10.4). Хотя это значительно уменьшает проблемы с синтаксисом оболочки, он представляет другой набор проблем совместимости. Я все еще думаю, что у него есть возможности.источник
sh -c "..."
, который он взял из другого вопроса . (Извините: я сначала пропустил ваш ответ, потому что не увидел в нем никакого кода, а только вернулся и прочитал его позже.)case $shell in sh)...
(это только синтаксис Bourne) илиswitch ($shell)
(только csh).test "$shell" = "sh" && do-something
работает вcsh
/sh
/rc
/es
, но неfish
.../dev/null
. Но у меня есть решение, которое я опубликую, как только у меня все заработает.попробуйте что-нибудь подобное
источник
csh
иtcsh
.fish
, но толькоfish
, к сожалению:ps h -p %self -o args='' | cut -f1 -d' '
. Это создает проблему с курицей и яйцом ... вы должны знать, что вы находитесьfish
, чтобы выполнитьfish
версию кода ...set shell_bin=`ps -p $$ -o args='' | cut -f1 -d' '`
- будет работать с CSH, но не с другимиcsh
/tcsh
, то эта часть:ps -p $$ -o args='' | cut -f1 -d' '
, которая возвращается-sh
наcsh
и-csh
наtcsh
.Я считаю, что вы не всегда можете получить имя текущей оболочки , и я думаю, вы должны знать об ограничениях того, что возможно.
В дистрибутивах Linux большинство пользователей используют в
bash
качестве логина и интерактивной оболочки (такbash
как это оболочка по умолчанию в большинстве дистрибутивов). Некоторые пользователи будут устанавливать свою оболочку дляzsh
,csh
(и варианты) илиfish
.(Как и другие комментарии и ответы объяснить, найти надежную оболочку из
bash
,zsh
,tcsh
,fish
уже вызова)Но некоторые странные пользователи могут установить их оболочку входа в нечто совершенно другое - интерпретатор Лиспа,
scsh
,es
, некоторый язык сценариев а - ля Python или OCaml, или Perl, и т.д. ...- и это их свобода сделать это. Возможно, некоторые люди кодируют свою собственную оболочку и используют ее в интерактивном режиме. Даже если вы нашли их странную оболочку, вы не сможете ничего с ней поделать (поэтому я считаю, что вам не следует пытаться получить имя оболочки).Поэтому я предполагаю, что вы кодируете какой-то исходный файл (возможно, генерирующий один) для настройки некоторого программного обеспечения. Так что просто объясните, что вы делаете, и напишите для общего случая
bash
(и, возможно,zsh
&tcsh
) ....источник
использовать ниже на свой страх и риск
источник
-f
readlink
-f
как доступную опцию, принимая вformat
качестве аргумента.readlink
не работает на моем puredarwin vm, так что я не знаю, что там происходит.