В моем .profile
коде я использую следующий код, чтобы гарантировать, что псевдонимы и функции, связанные с Bash, получаются только в том случае, если на самом деле оболочкой входа является Bash :
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
В настоящее время я нахожусь в процессе помещения файлов конфигурации, скриптов и функций моей оболочки под контроль версий. Я также недавно начал процесс удаления случайных Bashisms из сценариев оболочки, которые не извлекают выгоду из специфичных для Bash функций, например, заменяя function funcname()
на funcname()
.
Для моего хранилища файлов оболочки я настроил ловушку перед фиксацией, которая запускает checkbashisms
утилиту из пакета devscripts Debian для каждого sh
файла в хранилище, чтобы не допустить непреднамеренного введения синтаксиса, специфичного для Bash. Тем не менее, это вызывает ошибку для моего .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
Мне было интересно, если есть способ проверить, какая оболочка работает, что не вызовет предупреждение checkbashisms
.
Я проверил список переменных, относящихся к оболочке, перечисленных POSIX, в надежде, что одна из них может использоваться для отображения текущей оболочки. Я также посмотрел на переменные, установленные в интерактивной оболочке Dash, но, опять же, не смог найти подходящего кандидата.
На данный момент я исключен .profile
из обработки checkbashisms
; Это небольшой файл, так что проверить его несложно. Однако, изучив проблему, я все же хотел бы знать, существует ли POSIX-совместимый метод для определения, какая оболочка работает (или, по крайней мере, способ, который не приводит checkbashisms
к сбою).
Дальнейшая справка / разъяснения
Одна из причин, по которой я настраиваю свои файлы конфигурации оболочки под контроль версий, заключается в том, чтобы настроить свою среду на всех системах, в которых я в данный момент регулярно выполняю вход: Cygwin, Ubuntu и CentOS (обе версии 5 и 7, с использованием Active Directory для пользователя. аутентификация). Я чаще всего захожу через X Windows / окружение рабочего стола и SSH для удаленных хостов. Тем не менее, я хотел бы, чтобы это было в будущем и как можно меньше зависело от системных зависимостей и других инструментов.
Я использовал checkbashisms
в качестве простой автоматической проверки правильности синтаксиса моих файлов, связанных с оболочкой. Это не идеальный инструмент, например, я уже применил к нему патч, чтобы он не жаловался на использование command -v
в моих скриптах. В ходе исследования я узнал, что настоящей целью программы является обеспечение соответствия политике Debian, которая, насколько я понимаю, основана на POSIX 2004, а не 2008 (или его редакции 2013 года).
источник
.bash_profile
что источники оба.profile
и (условно).bashrc
.Ответы:
Ваш
код полностью соответствует POSIX и лучший способ проверить, что вы в данный момент работаете
bash
. Конечно,$BASH_VERSION
переменная зависит от bash, но именно поэтому вы ее используете! Чтобы проверить, что ты бежишьbash
!Обратите внимание, что
$BASH_VERSION
будет установлено , будет лиbash
вызываться какbash
илиsh
. После того, как вы заявили, что работаетеbash
, вы можете использовать[ -o posix ]
в качестве индикатора, что оболочка была вызвана какsh
(хотя этот параметр также устанавливается, когда POSIXLY_CORRECT находится в среде илиbash
вызывается с помощью-o posix
, или с SHELLOPTS = posix в среде. Но во всех этих случаяхbash
будет вести себя как будто называется какsh
).Другая переменная, которую вы могли бы использовать вместо,
$BASH_VERSION
и,checkbashism
кажется, не будет жаловаться, если не передана-x
опция is$BASH
. Это также относится и к тому,bash
что вы также можете использовать, чтобы определить, бежите ли выbash
или нет.Я также утверждаю, что это не совсем правильное использование
checkbashisms
.checkbashisms
это инструмент, помогающий вам писать переносимыеsh
скрипты (согласноsh
спецификации в политике Debian, расширенный набор POSIX), он помогает идентифицировать нестандартный синтаксис, введенный людьми, пишущими скрипты в системах, гдеsh
есть символическая ссылкаbash
.A
.profile
интерпретируется различными оболочками, многие из которых не совместимы с POSIX. Как правило, вы не используете вsh
качестве регистрационной оболочки, но скорлупа нравитсяzsh
,fish
илиbash
с более расширенными интерактивными возможностями.bash
иzsh
когда не вызывается какsh
и когда их соответствующий файл сеанса профиля (.bash_profile
,.zprofile
) не соответствует POSIX (особенноzsh
), но все еще читается.profile
.Так что вам нужен не синтаксис POSIX,
.profile
а синтаксис, совместимый с POSIX (дляsh
),bash
иzsh
если вы когда-либо будете использовать эти оболочки (возможно, даже Bourne, поскольку оболочка Bourne также читает,.profile
но обычно не встречается в системах на основе Linux) ).checkbashisms
определенно поможет вам найти ошибки, но может не указывать синтаксис POSIX, который не совместим сzsh
илиbash
.Здесь, если вы хотите использовать
bash
специфичный для вас код (например, обойти этуbash
ошибку, при которой он не читает~/.bashrc
в интерактивных оболочках входа в систему), лучшим подходом было бы~/.bash_profile
сделать это (до или после поиска источников,~/.profile
когда вы помещаете свой общий сеанс). инициализацый).источник
checkbashisms
из-за используемой переменной.$0
для этого конкретного случая?sh
и некоторой другой оболочкой, называемой assh
.dash
или с другой ошибкой вызвана не-bash-оболочкаargv[0] == "bash"
, что вполне законно, если маловероятно.Обычно
$0
для этого используют. На сайте, на который вы ссылаетесь, стоит:источник
$0
имени сценария оболочки, что очистился, забыл, что он также может ссылаться на текущую оболочку. Благодарность!exec
семейства, потому что они позволяют вызывающей программе идентифицировать двоичный файл, который будет запускаться отдельно от строки, передаваемой в качестве аргумента. 0.Обычно переменная окружения SHELL сообщает вам оболочку по умолчанию. Вам не нужно вручную исходить из файла .bashrc (не так, смотрите обновление ниже), bash должен делать это автоматически, просто убедитесь, что он находится в каталоге $ HOME.
Другой вариант - сделать что-то вроде:
это скажет вам команду (без аргументов, = без значения не будет отображать заголовки столбцов) текущего процесса. Пример вывода:
ОБНОВИТЬ:
Я исправлюсь! :)
Файл .bashrc не всегда получен, как упоминалось в комментариях ниже и /programming/415403/whats-the-difference-between-bashrc-bash-profile-and-environment
Таким образом, вы можете переместить ваш .bashrc в .bash_profile и посмотреть, работает ли он без необходимости делать тест. Если нет, у вас есть тест выше.
источник
.bashrc
на самом деле не получены из оболочки входа в систему, но.profile
(если она существует) или.bash_profile
есть.SHELL
не указывается в POSIX и, к сожалению, не является параметромcmd
формата дляps
.ps -o cmd= $$
должен работать практически везде,$SHELL
переменная не имеет значения. Это оболочка пользователя по умолчанию, которая не имеет отношения к тому, какая оболочка запущена в данный момент или какая оболочка выполняет сценарий оболочки.~/.profile
при запуске в качестве оболочек для входа. Так, например, твой$SHELL
мог бытьcsh
и ты бежишьbash -l
. Это запустит bash как оболочку входа в систему, поэтому он будет читать~/.profile
, но вы$SHELL
все равно будете указыватьcsh
. Кроме того,.profile
может быть получен явно другим сценарием. Так как OP идет на максимальную надежность, следует рассмотреть все виды случаев. В любом случае$SHELL
не предоставляет никакой полезной информации о запущенной в данный момент оболочке.SHELL
том, что POSIX не указал: pubs.opengroup.org/onlinepubs/9699919799/basedefs/…В вопросе задается оболочка для входа в систему пользователя, а также текущая оболочка
checkbashisms
. Если предполагается, что это оболочка, в которой пользователь вошел в систему, я бы использовал одну из/etc/passwd
, например:Пользователи могут, конечно, запустить новую оболочку после входа в систему. Конечно, если одна из них bash, а другая нет, тесты переменных среды bash могут не помочь.
Некоторые могут захотеть использовать
getent
не простоpasswd
файл (но это не входит в сферу вопроса).На основании комментария о LDAP и предложения для
logname
этой альтернативной формы можно использовать:Во время тестирования я заметил, что
logname
не нравится его перенаправление ввода (поэтому я оставил выражение разделенным). Быстрая проверка показаgetent
должна работать на упомянутых платформах (хотя это должно было быть предоставлено в оригинальном вопросе):источник
$(logname)
).id
ли переменную, изменяемую пользователем, - другой выбор.$(logname)
, нет$LOGNAME
. Идентификатор пользователя и оболочка входа в систему происходят от имени пользователя, используемого при входе в систему. Вы не можете вернуться от идентификатора пользователя к оболочке входа в систему, кроме как в системах, где для каждого идентификатора пользователя есть только одно имя пользователя. Или, IOW, первичный ключ в базе данных пользователей - это имя пользователя, а не uid.