LINUX.ORG.RU

bash-completion Slackware

 , ,


0

1

Добрый день.Slackware 14.2(kde). Подскажите пожалуйста, поставил через slackpkg bash-completion. В инструкции на slackwiki написано что все должно быть огонь и после ребута все заработает. В /etc/profile.d есть скриптик bash-completion.sh который я так понимаю и должен мне подключать complete.В этом самом скриптике в первой строке вот такая штука -

 if [ -n "${BASH_VERSION-}" -a -n "${PS1-}" -a -z "${BASH_COMPLETION_COMPAT_DIR-}" ]; then....

Которая собственно и не отрабатывает, из-за $PS1.

Вопрос: я конечно понимаю что все это можно решить простым вызовом без проверок /usr/share/bash-completion/bash_completion из .bashrc. Но хотелось бы понять почему эта хрень не работает из каропки. А если еще точнее то почему в скриптах $PS1 пустая и где я ее должен глобально определить.

Сценарии в /etc/profile.d/ вызываются из /etc/profile, который, в свою очередь, исполняется только из login shell (подробнее в man bash, INVOCATION); Konsole по умолчанию запускает bash не как login shell, это легко изменить — в его настройках есть соответствующая галка. Либо сделать необходимое в bashrc, глобальном или пользовательском (но помнить, что он не исполняется в login shell).

в скриптах

Сценарии исполняются в неинтерактивной оболочке, перечень исполняемого при старте такой оболочки несколько иной (подробнее в man bash, INVOCATION).

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от kovalev_94

А, это немного не то. Включай активацию bash-completion либо в ~/.bashrc, либо в /etc/bash.bashrc (если для всех сразу надо). Выше правильно сказали про логин-шелл.

anonymous
()

почему в скриптах $PS1 пустая

На всякий случай уточню, если из сказанного выше еще не стало ясно:
test -n "${PS1-}" — это по факту проверка на интерактивность текущей оболочки, основанная на сильно косвенных признаках (отсутствии значения для приглашения ввода (prompt) в $PS1) и, к слову, не очень-то совместимая с другими sh-совместимыми оболочками.
В неинтерактивной оболочке bash-completion не нужен: некому вызывать автодополнение, а значит и не нужно загружать всю эту скриптовую бороду для поддержки автодополнения... Именно эту задачу и решает ... -a -n "${PS1-}" ...

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)

почему в скриптах $PS1 пустая

man bash, INVOCATION

An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.


PS1 не пустая при запуске интерактивной оболочки. А при запуске неинтерактивной оболочки PS1 пустая.

где я ее должен глобально определить

Так задумано. Не должен. Не чините то, что не поломано.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 4)
Ответ на: комментарий от bormant

Спасибо большое за подробные ответы. Но подскажите пожалуйста, как мы можем проверить интерактивность оболочки в скрипте? Ведь код -

test -n "${PS1-}"
у нас в скрипте.... Вообще я посмотрел что при неинтерактивном шелле он читает $BASH_ENV но опять же остался вопрос где он ее устанавливать.

kovalev_94
() автор топика
Ответ на: комментарий от bormant

Вопрос в том почему не в установочнике, ни в инструкции нет ничего про то что надо бы ее устанавливать в bashrc. Или идет расчет что я только в логин шелле работаю? Ну тогда опять же вопрос, почему не добавили этот файл в /etc/profile/

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

Я про то что нафиг они тогда эту проверку в скрипт засунули.

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

Давайте немного подробнее с вопросом, вопрос ваш пока не совсем понятен, а точнее — совсем непонятен.

Зачем в сценарии /etc/profile.d/bash-completion.sh есть проверка
... -a -n «${PS1-}» ...
? Это чтобы выполнять загрузку определений bash-completion только для интерактивной оболочки и НЕ выполнять для неинтерактивной. Сценарий по-умолчанию вызывается из регистрирующей оболочки (/etc/profile НЕрегистрирующей оболочкой не выполняется).

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от kovalev_94

Вас непонятно.
Хотите, чтобы в нерегистрирующей оболочке выполнялась та же настройка окружения, что и в регистрирующей? Выполните:
. /etc/profile
«.» — это часть команды (синоним — source).

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от bormant

Сейчас попробую объяснить. Смотрите bash invocation говорит нам что все сценарии выполняются в неинтерактивном шелле. Для неинтерактивного шелла у нас отсутвует $PS1. Но в файле /etc/profile который загружается только при интерактивном логин шелле мы вызываем файл /etc/profile/bash-completion.sh как сценарий, и по идее он должен выполнятся в неинтерактивном шелле и все время валить проверку на не пустую $PS1

А второй вопрос был несколько тупой, ибо не совсем по адресу - почему при установке пакета, не дописывается нормальный вызов из /etc/profile(bash_completion копируется в /etc/profile.d но /etc/profile не меняется).

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

bash invocation говорит нам что все сценарии выполняются в неинтерактивном шелле

Нет. Там написано другое: если запускается, например, bash сценарий, то оболочка будет неинтерактивной.
Но еще сценарий можно запустить не в новой оболочке, в текущей, при помощи «.» или «source».
/etc/profile — обычный сценарий, выполняет его bash тоже в текущей оболочке. Теперь откройте его и посмотрите, как из него вызываются сценарии из /etc/profile.d/ (почти в самом конце).
Там же ответ и на вопрос «почему не дописывается в /etc/profile».

Разобрались? Вопросы остались?


PS. Обращаю внимание на "." при запуске сценариев.

# Append any additional sh scripts found in /etc/profile.d/:
for profile_script in /etc/profile.d/*.sh ; do
  if [ -x $profile_script ]; then
    . $profile_script
  fi
done
unset profile_script

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от bormant

С source и . разобрались. С /etc/profile который выполняется тоже в текущей оболочке, если честно не совсем, я думал она выполняется при инициализации нового интерактивного шелла( тоесть у нас есть какая то оболочка запущенная и он вызывает новую прочитав перед этим /etc/profile Сценарии /etc/profile.d/* вызываются тупым перебором и проверкой файлов на исполняемость, по крайней мере у меня:


# Append any additional sh scripts found in /etc/profile.d/:
for profile_script in /etc/profile.d/coreutils-dircolors.sh /etc/profile.d/glibc.sh /etc/profile.d/gtk+.sh /etc/profile.d/kde.sh /etc/profile.d/lang.sh /etc/profile.d/libglib2.sh /etc/profile.d/libreoffice.s
if [ -x $profile_script ]; then
. $profile_script
fi
done
unset profile_script

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

С /etc/profile который выполняется тоже в текущей оболочке, если честно не совсем

0. Система запускает новый процесс bash.
1. Процесс bash получает управление, разбирает параметры, определяет, что режим интерактивный.
2. Процесс bash выполняет начальную инициализацию окружения.
3. Процесс bash выполняет /etc/profile внутри себя.
Если бы он позвал «bash /etc/profile», то в этом не было б никакого смысла — новая оболочка запустилась бы, отработала и завершилась, все изменения в окружении умерли бы вместе с ней.
...
N. Вывод приглашения ввода и ожидание команд.
...

bormant ★★★★★
()
Ответ на: комментарий от kovalev_94

у вас такая по умолчанию?

Да. В файле должно быть

# Append any additional sh scripts found in /etc/profile.d/:
for profile_script in /etc/profile.d/*.sh ; do

А если выполнить, например, echo /etc/profile.d/*.sh, то отработает глоббинг и вместо маски будет актуальное содержимое, под эту маску попадающее.

Если less /etc/profile показывает вам что-либо другое, переустановите пакет «etc» и замените /etc/profile:
# slackpkg reinstall etc
# cd /etc
# cat profile.new > profile
# rm *.new profile.d/*.new /var/log/*.new /var/run/*.new


И было бы интересно узнать, как такое получилось.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 5)
Ответ на: комментарий от bormant

Небольшое, но существенное в контексте темы дополнение:

3. Процесс bash выполняет /etc/profile внутри себя.

3. Процесс bash, определив, что он регистрирующая оболочка, выполняет /etc/profile внутри себя.

bormant ★★★★★
()
Ответ на: комментарий от bormant

[code]echo /etc/profile.d/*.sh[/code]

Про echo не знал, обычно делаю такое просто с ls.

Ну да, увидел в profile.backup как у вас написано.

И было бы интересно узнать, как такое получилось.

Да вот хз в какой момент он так поменялся. Может когда какой то пакет ставил, может когда обновлялся...

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

Про echo не знал, обычно делаю такое просто с ls

В примере с echo или ls есть тонкий момент (даже несколько).
Какая команда — не важно, важно то, что шаблон (wildcard) обычно раскрывается оболочкой (globbing), а команда получает уже готовый список, а не шаблон.
И далеко идущие последствия --размер переданных параметров хотя и большой, но не безграничный (если правильно путаю, 32 КБ), поэтому для каталогов с большим числом файлов попытка передать раскрытый шаблон может быть неудачной.
Однако for v in list; do ...; done шаблон из list параметром не передает и этой проблемы не имеет.

В других случаях на помощь приходит xargs.

Пример с «echo *» был приведен в качестве предположения о том, как мог получиться раскрытый список вместо шаблона — кто-то прогнал содержимое файла через, например, переменную bash и записал результат обратно в файл. При этом вдобавок и выражения с переменными должны были попортиться, не только шаблоны...
Поэтому очень интересно, кто же мог так подгадить. Лично с подобным не сталкивался ни разу.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от bormant

Я думаю это Cisco Packet Tracer 7 был. Просто сравнивая оригинал и свой profile разница была только в файлах из /etc/profile.d и пути до Packet Tracer. Вообще не аргумент конечно, но че то такое ощущение что там у них все виндовозники, ибо на на слаку он вообще не встал нормально, а на макоси выжирает под сотню цп.

kovalev_94
() автор топика
Ответ на: комментарий от kovalev_94

сравнивая оригинал и свой profile разница была только в файлах из /etc/profile.d и пути до Packet Tracer

Вот тут как раз непонятно, зачем трогать сам файл /etc/profile, раз уж софтинка кладет свои настройки в /etc/profile.d/нечто.sh, значит она в курсе того, как используется каталог настроек profile.d/, а значит и о том, что /etc/profile в этом случае трогать не нужно...

Пару слов про *.d/.
Поначалу устанавливаемый софт имел привычку лапать общие настройки в /etc/ тем или иным образом, например, при помощи sed и т.п. Минусов у такого подхода было много: 1) меняется дистрибутивный файл, становится сложнее контроль целостности, 2) растет риск несовместимых изменений, 3) убирая свои настройки легко порушить чужие, 4) растет риск ошибочных изменений (прямо как у вас).
В качестве «лекарства» была предложена концепция «каталогов настроек» нечто.d/, куда софт будет класть свои настройки отдельным файлом (файлами), при удалении, соответственно, удалять только своё. Нередко подобный подход сопровождается каталогом нечто.avail/, куда кладут преднастроенные варианты, давая возможность просто скопировать нужное в нечто.d/.
Подобную концепцию восприняло достаточно много софта, прежде всего, с развесистыми файлами конфигурации: SystemV init, xorg, fontconfig, (e)udev, ...

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от bormant

Большое спасибо за информацию, полезно и очень интересно. До этого сталикивался с каталогами *.d/ только в rc.d и nginx.

А поводу Packet Tracer мне все таки кажется они виндовозники)))

Просто я то тоже сильно много софта на систему не ставил, и то почти все от alienBob . Ну а штатные обновления через slackpkg врядли бы такое сделали. Может когда я освою работу с докером проведу эксперимент и проверю точно ли это был PacketTracer.

kovalev_94
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.