Новая сессия tmux только исходники .zshrc, и не берёт $PATH, определённый в .profile

Чтобы иметь дело с произвольными именами файлов (включая те, которые содержат символы новой строки), обычный трюк заключается в поиске файлов внутри . //. вместо . . Поскольку // обычно не может возникнуть при обходе дерева каталогов, вы уверены, что // сигнализирует о начале нового имени файла в find (или здесь lsattr -R ) вывод.

lsattr -R .//. | awk '
  function process() {
    i = index(record, " ")
    if (i && index(substr(record,1,i), "i"))
      print substr(record, i+4)
  }
  {
    if (/\/\//) {
      process()
      record=$0
    } else {
      record = record "\n" $0
    }
  }
  END{process()}'

Обратите внимание, что вывод по-прежнему будет разделен новой строкой. Если вам нужно его обработать, вам придется его адаптировать. Например, вы можете добавить -v ORS = '\ 0' , чтобы передать его в GNU xargs -r0 .

Также обратите внимание, что lsattr -R (по крайней мере 1.42.13) не может сообщать флаги файлов, путь которых больше, чем PATH_MAX (обычно 4096), поэтому кто-то может скрыть такой неизменяемый файл, переместив его родительский каталог (или любой из компонентов пути, которые к нему ведут, кроме самого себя, поскольку он неизменяемый) в очень глубокий каталог.

Чтобы обойти эту проблему, можно использовать find с -execdir :

find . -execdir sh -c '
  a=$(lsattr -d "$1") &&
    case ${a%% *} in
      (*i*) ;;
      (*) false
    esac' sh {} \; -print0

Теперь, с -print0 , это можно обработать постобработку, но если вы собираетесь делать что-либо с этими путями, обратите внимание, что любой системный вызов на пути к файлам, больший, чем PATH_MAX , все равно завершится ошибкой, и компоненты каталога могут быть переименованы в интервале.

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

  • путь lsattr -R. просматривает дерево каталогов, это зависит от состояния гонки. Можно заставить его спускаться в каталоги за пределами дерева каталогов, маршрутизируемых по адресу . путем замены некоторых каталогов символическими ссылками в нужный момент.
  • даже lsattr -d файл имеет состояние гонки. Эти атрибуты применимы только к обычным файлам или каталогам.Итак, lsattr сначала выполняет lstat () , чтобы проверить правильность типа файла, а затем выполняет open () , а затем ioctl () для получения атрибутов. Но он вызывает open () без O_NOFOLLOW (или O_NOCTTY). Кто-то может заменить файл символической ссылкой на / dev / watchdog , например, между lstat () и open () и вызвать систему перезагрузить. Он должен выполнить open (O_PATH | O_NOFOLLOW) , за которым следует fstat () , openat () и ioctl () , чтобы избежать условия гонки.

2
20.10.2018, 10:34
1 ответ

Описанное вами поведение является ожидаемым. Переменные среды определены в .profile, которые считываются при входе в систему. Запуск нового сеанса tmux не приводит к входу в систему. Tmux по умолчанию запускает оболочку входа в систему, но вы отключили ее в конфигурации, поэтому Окна tmux просто наследуют внешнюю среду.

Если вы поместите source.profileв свой .zshrc, это переопределит любую среду, в которой работает оболочка. Это означает, что вы не можете запускать оболочку в среде, отличной от среды по умолчанию, например. попробовать что-то с другим PATH.

Просто удалите source.profileиз .zshrc. У вас будет среда по умолчанию, установленная во время входа в систему во всех оболочках.

Если ваша оболочка для входа в систему — zsh, обратите внимание, что во время входа в систему она читает .zprofile, а не .profile. Это отличается от bash, который читается как .profile, если .bash_profileотсутствует. Zsh работает по-другому, потому что его синтаксис отличается от sh, поэтому он не может читать .profileнапрямую. Если вы хотите иметь .profile, который работает под sh для входа в систему с графическим интерфейсом, а также использовать тот же файл для входа в текстовый режим,и вы установили zsh в качестве оболочки входа в систему, затем используйте следующую строку в качестве~/.zprofile:

emulate sh -c 'source ~/.profile'

Если tmux настроен на запуск оболочки входа в систему, то все окна tmux будут переопределять окружающую среду, а не наследовать ее. Это означает, что если вы определяете новые переменные вне tmux, они все равно будут в сеансе tmux, но если вы измените значения уже определенных переменных, ваши изменения будут потеряны внутри tmux. В общем, поведение tmux по умолчанию не имеет особого смысла. Избежать этого — точка линии set-option -g default-command $SHELLв ~/.tmux.conf.

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

set-option -g default-command env -i USER="$USER" LOGNAME="$LOGNAME" $SHELL

И помните, что если ваша оболочка для входа в систему — zsh, она читается как .zprofile, а не .profile.

3
27.01.2020, 21:58

Теги

Похожие вопросы