Экран GNU не унаследует мой PATH на 10.5.8

11

Я использую экран ежедневно для своих нужд терминала, и я вполне доволен этим. В последнее время , хотя, я сделал некоторые обновления мои файлы конфигурации Баш , и я заметил , что я устанавливал различные PATHэлементы ( PATH, MANPATH, INFOPATHи т.д.) в 2 -х местах. Я изменил файлы, чтобы они были такими, какими они должны быть, и теперь все мои переменные окружения устанавливаются один раз .bash_profile. В этом и заключается моя проблема.

Очевидно, причина, по которой я устанавливал их в двух местах, была из-за экрана. экран появляется только выполнить .bashrcи не не появляется , чтобы наследовать мои PATHправильно или любую другую среду переменными из моей первоначальной Баш оболочки. Поскольку он только выполняется, .bashrcи я теперь устанавливаю только мои переменные .bash_profile, я получаю неполное PATH.

Мой вопрос в том, как вывести мои переменные окружения на экран без дублирования. Считывание Bashдокументов, похоже, указывает на то, что это может быть оболочка, используемая экраном для входа в систему, то есть интерактивная оболочка без регистрации, но я не мог понять, как заставить экран использовать оболочку определенного типа, только оболочка для использования через -s /bin/bash.

Вы можете просмотреть мои файлы конфигурации на моей странице GitHub . Это коммит, который сломал экран .

РЕДАКТИРОВАТЬ: я использую, Screen version 4.00.03 (FAU) 23-Oct-06и я склонен вызывать егоscreen -h 50000

РЕДАКТИРОВАТЬ: Теперь я был в состоянии проверить это на Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06), и он демонстрирует другое поведение, чем на моем Mac.

Конкретное поведение, которое я сейчас обнаружил, заключается в том, что в Cygwin изменения, которые я делаю PATHв .bash_profile, дублируются при входе в экран, и затем последовательное создание окон экрана не дублирует путь, а создает исходный код .bash_profile.

Чтобы проиллюстрировать поведение, о котором я говорю:

Выход из свежего терминала:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Вывод из первого вызова экрана:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Последующие звонки на C-a c:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Ты можешь видеть

Тим Вишер
источник
Дублирование происходит потому, что у вас есть bash, настроенный на безусловное добавление этих записей, это оболочка 'login', и вы говорите экрану, чтобы вызывать bash как оболочку 'login'. Я переписал свой ответ, чтобы попытаться решить общие проблемы оболочек, экрана и переменных среды.
Крис Джонсен

Ответы:

16

экран и переменные среды

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

Допустим, что ни конфигурация вашей оболочки, ни конфигурация экрана не изменят переменную с именем FOOBAR (скорее всего, в общем). Если вы начнете сеанс с FOOBAR=foo screen, то все оболочки, созданные в этом сеансе, будут иметь переменную среды с именем FOOBAR со значением foo.

Ситуация усложняется для переменных, которые может изменить экран или ваша оболочка.

Отсутствие настроек при использовании экрана

Войти Оболочки

Если вы обнаружите, что в оболочках, запускаемых с экрана , отсутствуют некоторые параметры , это может быть связано с тем, что ваша оболочка настроена только на обновление этих настроек для оболочек «входа». Большинство оболочек понимают специальное соглашение (в C:), **argv == '-'что экран может быть настроен для использования.

Согласно экранной документации :

команда оболочки

Установите команду, которая будет использоваться для создания новой оболочки. Это переопределяет значение переменной окружения $ SHELL. Это полезно, если вы хотите запустить tty-Enhancer, который ожидает выполнения программы, указанной в $ SHELL. Если команда начинается с символа «-», оболочка будет запущена как логин-оболочка.

Чтобы экранные оболочки запускались в качестве оболочек для входа в систему, запускайте экран с помощью screen -s -/bin/bashили добавьте эту строку в свой .screenrc:

shell -/bin/bash

Отрегулируйте путь к любой оболочке, которую вы используете.

Конфигурация экрана

Отсутствует или сброс переменных среды также может быть из - за setenvи unsetenvкоманды в окно файла конфигурации. Вам нужно будет проверить как .screenrc в вашем домашнем каталоге, так и тот файл, который ваша компиляция экрана использует в качестве «системного экрана» (вы можете попробовать команду вроде strings "$(which screen)" | fgrep -i screenrcнайти путь, который был настроен во время компиляции - обычно это / etc / screenrc для экрана, установленного в системе ; при установке дополнений, вероятно, будет использоваться другой путь). Вы можете SCREENRC=/dev/null SYSSCREENRC=/dev/null screenвременно использовать эти файлы настроек, но есть опция времени компиляции, которая препятствует эффективному использованию SYSSCREENRC. (предположительно, чтобы системные администраторы могли принудительно настроить начальную конфигурацию).

Дубликаты настроек при использовании экрана

Весьма распространено добавлять элементы в переменную среды, такую ​​как PATH, в файл (ы) конфигурации оболочки, чтобы обновленное значение было доступно для обычных сеансов оболочки (например, xterm или других окон терминала, сеансов консоли и т. Д.). Если такие элементы добавляются в конфигурации оболочки для каждой оболочки (или, если вы используете -/path/to/shellнастройку, описанную выше, в конфигурации оболочки для входа в систему), то оболочка, запущенная на экране , вероятно, будет иметь несколько копий добавленных элементов.

Одна из стратегий, позволяющая избежать этого, состоит в том, чтобы добавлять все добавления к переменным, таким как PATH, в конфигурацию вашей оболочки для каждого входа в систему и избегать использования параметров -/path/to/shellоболочки с экраном .

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

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

диагностика

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

Проверьте текущее значение в вашей начальной оболочке:

echo "$PATH"

Проверьте, как сама оболочка изменяет значение при создании под-оболочки:

/bin/bash -c 'echo "$PATH"'

Проверьте, как оболочка изменяет значение при создании под-оболочки 'login':

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

Проверьте, как экран изменяет значение:

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log
Крис Джонсен
источник
Это решает часть моей проблемы. К сожалению, это не полный путь. Теперь экран работает нормально, screen -s -/bin/bashно он не работает так, как я ожидал, что он будет работать под управлением Cygwin на моей рабочей машине. На этой машине я запускаю, screen -h 50000и она просто наследует мою, PATHфактически не получая файл снова. Это запускается каждый раз, когда я запускаю новое окно.
Тим Вишер
Среда экранного процесса всегда должна наследоваться любыми его дочерними элементами (за исключением таких вещей, как TERM, которые он может переопределить). Попробуй FOOBAR=baz screenи проверь echo $FOOBARв оболочке windows от screenа screen -s -/bin/bash. Оба варианта должны иметь FOOBAR= baz. Если ваша PATHмодификация, вам придется отслеживать, что это делает. Попробуйте SYSSCREENRC=/dev/null SCREENRC=/dev/null screen, если это позволяет PATH, то это, вероятно, setenv PATHв /etc/screenrcили ~/.screenrc. В противном случае это то, что вы .bashrcделаете.
Крис Джонсен
Я сделал большую переписку / дополнение к моему ответу.
Крис Джонсен
2

В последний раз, когда я видел подобную проблему, я решил ее, используя screen -lпри запуске экрана.

Вы можете использовать -lопцию при вызове screen(переворачивать режим входа на, также контролируется defloginи loginкоманды в .screenrc) , чтобы установить , следует ли экран входа в окно , по умолчанию (добавление / удаление / и т.д. / запись utmp).

Режим входа по умолчанию включен, но его можно изменить во время компиляции. Если экран не скомпилирован с поддержкой utmp, эти команды недоступны.

Мне не нужен -lрежим на экране Debian Lenny по умолчанию (v4.0.3); кажется, он включен по умолчанию. Мои ~/.profileи ~/.bashrcчитают правильно. Как вы вызываете screen? Какую версию ты используешь?

шарлатан
источник
хотя по этой теории, неscreen -ln должен запускать мой , и он все еще запускается. так что попробуйте флаг, но это, вероятно, не правильный ответ. оставлю это здесь на данный момент. ~/.profile-l
шарлатан-кихот
Кажется, что он -lтолько контролирует, screenдобавляет ли запись в utmpфайл, а не вызывает ли он новые оболочки с их собственной -lопцией или использует пользовательский exec- -with--prefix.
Крис Джонсен
2

Проблема заключается в поведении запуска на Leopard. Посмотрите этот отчет об ошибках MacPorts для экрана на Leopard, чтобы понять, почему он никогда не будет исправлен, если вы не можете каким-то образом сделать репортаж о запуске Snow Leopard.

https://trac.macports.org/ticket/18235#comment:26

ClashTheBunny
источник
1

Нет ничего плохого в том, чтобы получить ваш .bashrc из .bash_profile. Если вы используете свой компьютер только локально, ваш .bash_profile в большинстве случаев будет получен только при первоначальном входе в систему (очевидно, что в других случаях он получен).

Я организую свои файлы так, чтобы, если я хочу, чтобы что-то было сделано только при входе в систему, я помещал информацию в .bash_profile, а для всего остального я помещал их в .bashrc. PATH - это одна вещь, которую я помещаю в свой .bashrc, и я поставляю .bashrc в свой .bash_profile.


источник
Не могли бы вы разместить свои файлы .bashrcи .bash_profileфайлы где-нибудь, чтобы я мог их увидеть? Проблема, с которой я столкнулся при выполнении чего-то подобного, заключалась в том, что PATHон увеличивался каждый раз, когда я создавал новый экземпляр экрана, потому что он наследовал старый, PATHа затем снова все добавлял.
Тим Вишер
Извини, Тим, я этого не видел ... Я много чего изменил, чтобы они не имели особого смысла, но это в основном то, что я делаю. # .bash_profile if [-f ~ / .bashrc]; затем . ~ / .bashrc fi Затем я помещаю все остальное в .bashrc, за исключением вещей, которые я хочу запустить при первом входе в систему, которые также идут в .bash_profile. PATH обрабатывается в .bashrc в виде последовательности строк вместо одного определения пути, как в большинстве случаев экспорт PATH = / path / to / binaries1: $ PATH export PATH = / path / to / binaries2: $ PATH
0

Всякий раз , когда у меня есть какая - то проблема , как я создать файл $HOME/.debugи все файлы источников / выполняется во время входа / оболочки вызова (например ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrcи т.д.) У меня есть в первой строке

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

или похожие. Для конкретной отладки вы также можете добавить такие вещи, как

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

Таким образом, вы можете быть на 100% абсолютно уверены, какие файлы используются или нет.

Перенаправление на stderr важно, вы не хотите, чтобы во многих ситуациях что-то портило stdout.

hlovdal
источник
0

Вы можете остаться с .profile, так как система не касается bashrc (например, графического сеанса). Теперь у вас просто есть два разных набора окружения - один из .profile, другой для bash из .bashrc.

Заб
источник