Стартиране на Bash в детайли

Ако сте намерили тази страница в търсене, вероятно се опитвате да разрешите някакъв проблем със стартирането на bash.

Възможно е във вашата среда да не е зададена променлива на средата и да не разбирате защо. Може да сте добавили нещо в различни начален файлове на bash или в профили, или случайно във всички файлове, докато не сработи.

Във всеки случай, целта на това бележка е да изложи по най-простия начин процедурата за стартиране на bash, за да можете да се справите с проблемите.

Диаграма

Тази блок-схема обобщава всички процеси при стартиране на bash.

Стартиране на Bash в детайли

Сега нека се спрем по-подробно на всяка част.

Login Shell?

Първо трябва да определите дали се намирате в команден shell за вход (login shell) или не.

Shell за вход е първият shell, в който влизате при влизане в системата за интерактивна сесия. Shell за вход не изисква въвеждане на потребителско име и парола. Можете да принудите стартирането на shell за вход, добавяйки флага --login при повикването на bash, например:

bash --login

Shell за вход настройва основната среда при първото стартиране на shell bash.

Интерактивен?

След това определяте дали shell е интерактивен или не.

Можете да проверите наличието на променлива PS1 (тя задава функцията за въвеждане на команди):

if [ "${PS1-}" ]; then
  echo interactive
else
  echo non-interactive
fi

Или да видите дали е зададен параметър -i, с помощта на специална променлива дефис - в bash, например:

$ echo $-

Ако в изхода има символ i, то shell е интерактивен.

В shell за вход?

Ако сте в shell за вход, то bash търси файл /etc/profile и го стартира, ако съществува.

След това търси всички от тези три файла в следния ред:

~/.bash_profile
~/.bash_login
~/.profile

Когато намери един, го стартира и пропуска другите.

В интерактивен shell?

Ако сте в интерактивен shell без вход в системата (non-login shell), се предполага, че вече сте били в shell за вход, средата е настроена и ще бъде наследена.

В този случай се изпълняват следните два файла по ред, ако съществуват:

/etc/bash.bashrc
~/.bashrc

Няма вариант?

Ако не сте нито в shell за вход, нито в интерактивен shell, то вашата среда наистина ще бъде празна. Това предизвиква значителна объркване (вижте по-долу за cron задания).

В този случай bash проверява променливата BASH_ENV на вашата среда и създава съответния файл, посочен там.

Типични трудности и емпирични правила

Cron задачи

В 95% от случаите, проблемите с стартирането на bash свързани с това, че cron задачата не работи, както е очаквано.

Тази проклета задача работи безупречно, когато я стартирам от командния ред, но пропада, когато се изпълнява в crontab..

Тук две основни причини:

  • Cron задачите не са интерактивни.
  • За разлика от скриптовете в командния ред, cron задачите не наследяват средата на оболката.

Обикновено не забелязвате или не ви интересува, че скриптът на оболката не е интерактивен, тъй като средата се наследява от интерактивната оболка. Това означава, че всички PATH и alias са настроени по начина, по който очаквате.

Затова често е необходимо да зададете конкретен PATH за cron задачата, както е показано тук:

* * * * * PATH=${PATH}:/path/to/my/program/folder myprogram

Скриптове, които се извикват взаимно

Още един често срещан проблем е, когато скриптовете погрешно са настроени да се извикват взаимно. Например, /etc/profile се обръща към ~/.bashrc.

Обикновено се случва така, когато някой е опитал да поправи грешка и изглежда, че всичко е заработило. За съжаление, когато трябва да разделите тези различни типове сесии, възникват нови проблеми.

Docker образ в пясъчника

За да експериментирам с изпълнението на оболката, създадох Docker образ, който може да се използва за отстраняване на проблеми в безопасна среда.

Стартиране:

$ docker run -n bs -d imiell/bash_startup
$ docker exec -ti bs bash

Dockerfile се намира тук.

За задължителен вход и симулиране на входна обвивка:

$ bash --login

За проверка на набор от променливи BASH_ENV:

$ env | grep BASH_ENV

За отстраняване на грешки crontab на всеки минутен интервал да се изпълнява прост скрипт (в /root/ascript):

$ crontab -l
$ cat /var/log/script.log

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster