install.sh 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. #!/bin/bash
  2. # --- НАСТРОЙКИ ---
  3. # Цвета для вывода
  4. GREEN="\033[1;32m"
  5. YELLOW="\033[1;33m"
  6. RED="\033[1;31m"
  7. NC="\033[0m" # No Color
  8. # Путь к этому скрипту и его папке
  9. SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
  10. # Имена файлов с пакетами
  11. PACMAN_PKGS="pkglist.txt"
  12. AUR_PKGS="aurlist.txt"
  13. # --- НАСТРОЙКИ СИМЛИНКОВ (Имена папок в репозитории) ---
  14. # Просто добавляйте файлы в эти папки.
  15. # 1. Папка для конфигов в $HOME/.config
  16. # (например, ~/dotfiles/config/bspwm -> ~/.config/bspwm)
  17. CONFIG_DIR_NAME="config"
  18. # 2. Папка для конфигов в $HOME
  19. # (например, ~/dotfiles/home/.zshrc -> ~/.zshrc)
  20. HOME_DIR_NAME="home"
  21. # 3. Папка для системных конфигов (управляется отдельной командой)
  22. # (например, ~/dotfiles/system/etc/vconsole.conf -> /etc/vconsole.conf)
  23. SYSTEM_DIR_NAME="system"
  24. # --- ХЕЛПЕРЫ ---
  25. msg() {
  26. echo -e "${GREEN}[INFO]${NC} $1"
  27. }
  28. warn() {
  29. echo -e "${YELLOW}[WARN]${NC} $1"
  30. }
  31. err() {
  32. echo -e "${RED}[ERROR]${NC} $1"
  33. }
  34. # --- ФУНКЦИИ ---
  35. # 1. Установка YAY (AUR Helper)
  36. install_yay() {
  37. if ! command -v yay &>/dev/null; then
  38. msg "YAY не найден. Установка YAY..."
  39. # Проверяем наличие git и base-devel перед установкой yay
  40. if ! pacman -Q git &>/dev/null || ! pacman -Q base-devel &>/dev/null; then
  41. sudo pacman -S --needed --noconfirm git base-devel
  42. fi
  43. git clone https://aur.archlinux.org/yay.git /tmp/yay
  44. (cd /tmp/yay && makepkg -si --noconfirm)
  45. rm -rf /tmp/yay
  46. msg "YAY установлен."
  47. else
  48. msg "YAY уже установлен."
  49. fi
  50. }
  51. # 2. Установка пакетов (Pacman и YAY)
  52. install_packages() {
  53. msg "Установка пакетов из Pacman ($PACMAN_PKGS)..."
  54. # Читаем файл, убираем inline-комментарии (после #),
  55. # убираем пустые строки, xargs очищает лишние пробелы
  56. # и передает все как отдельные аргументы в pacman.
  57. local pacman_args=$(sed 's/#.*//' "$SCRIPT_DIR/$PACMAN_PKGS" | grep -vE '^\s*$' | xargs)
  58. if [[ ! -z "$pacman_args" ]]; then
  59. sudo pacman -S --needed --noconfirm $pacman_args
  60. else
  61. msg "Список Pacman пуст, пропуск."
  62. fi
  63. msg "Проверка и установка YAY..."
  64. install_yay
  65. msg "Установка пакетов из AUR ($AUR_PKGS)..."
  66. # Аналогично для YAY
  67. local aur_args=$(sed 's/#.*//' "$SCRIPT_DIR/$AUR_PKGS" | grep -vE '^\s*$' | xargs)
  68. if [[ ! -z "$aur_args" ]]; then
  69. yay -S --needed --noconfirm $aur_args
  70. else
  71. msg "Список AUR пуст, пропуск."
  72. fi
  73. msg "Установка пакетов завершена."
  74. }
  75. # 3. Создание символических ссылок (ОБНОВЛЕНО)
  76. link_dotfiles() {
  77. msg "Создание символических ссылок (симлинков)..."
  78. local source_dir=""
  79. local target_dir=""
  80. # --- 1. Линкуем файлы в $HOME (из папки 'home') ---
  81. msg " -> Линковка в $HOME (из '$HOME_DIR_NAME')"
  82. source_dir="$SCRIPT_DIR/$HOME_DIR_NAME"
  83. target_dir="$HOME"
  84. if [ -d "$source_dir" ]; then
  85. # Ищем все файлы и папки на первом уровне в 'home/'
  86. # -mindepth 1 (чтобы не найти саму папку 'home')
  87. # -maxdepth 1 (чтобы найти '.zshrc', 'bin', но не 'bin/скрипт')
  88. for item_path in $(find "$source_dir" -mindepth 1 -maxdepth 1); do
  89. local item_name=$(basename "$item_path")
  90. local source_path="$item_path"
  91. local target_path="$target_dir/$item_name"
  92. # Бэкапим, если в $HOME уже что-то есть (и это не симлинк)
  93. if [ -e "$target_path" ] && [ ! -L "$target_path" ]; then
  94. warn "Файл/папка '$target_path' уже существует. Бэкап в '$target_path.bak'..."
  95. mv "$target_path" "$target_path.bak"
  96. fi
  97. ln -sfn "$source_path" "$target_path"
  98. msg " -> $target_path -> $source_path"
  99. done
  100. else
  101. warn "Папка '$source_dir' не найдена. Пропуск $HOME линков."
  102. fi
  103. # --- 2. Линкуем файлы в $HOME/.config (из папки 'config') ---
  104. msg " -> Линковка в $HOME/.config (из '$CONFIG_DIR_NAME')"
  105. source_dir="$SCRIPT_DIR/$CONFIG_DIR_NAME"
  106. target_dir="$HOME/.config"
  107. # Создаем ~/.config, если его нет (на новой системе)
  108. mkdir -p "$target_dir"
  109. if [ -d "$source_dir" ]; then
  110. # Аналогичная логика для папки 'config'
  111. for item_path in $(find "$source_dir" -mindepth 1 -maxdepth 1); do
  112. local item_name=$(basename "$item_path")
  113. local source_path="$item_path"
  114. local target_path="$target_dir/$item_name"
  115. # Бэкапим, если в ~/.config уже есть такой конфиг (и это не симлинк)
  116. if [ -e "$target_path" ] && [ ! -L "$target_path" ]; then
  117. warn "Файл/папка '$target_path' уже существует. Бэкап в '$target_path.bak'..."
  118. mv "$target_path" "$target_path.bak"
  119. fi
  120. ln -sfn "$source_path" "$target_path"
  121. msg " -> $target_path -> $source_path"
  122. done
  123. else
  124. warn "Папка '$source_dir' не найдена. Пропуск $HOME/.config линков."
  125. fi
  126. msg "Симлинки созданы."
  127. }
  128. # 4. Проверка текущей конфигурации
  129. check_config() {
  130. # ... (проверка пакетов остается без изменений) ...
  131. msg "Проверка установленных пакетов Pacman..."
  132. local missing_pacman=0
  133. while IFS= read -r line || [[ -n "$line" ]]; do
  134. local pkg=$(echo "$line" | sed 's/#.*//' | xargs)
  135. if [[ -z "$pkg" ]]; then continue; fi
  136. if ! pacman -Q "$pkg" &>/dev/null; then
  137. warn " -> Не найден (Pacman): $pkg"
  138. missing_pacman=1
  139. fi
  140. done < "$SCRIPT_DIR/$PACMAN_PKGS"
  141. if [ $missing_pacman -eq 0 ]; then msg "Все пакеты Pacman установлены."; fi
  142. msg "Проверка установленных пакетов AUR..."
  143. local missing_aur=0
  144. while IFS= read -r line || [[ -n "$line" ]]; do
  145. local pkg=$(echo "$line" | sed 's/#.*//' | xargs)
  146. if [[ -z "$pkg" ]]; then continue; fi
  147. if ! pacman -Q "$pkg" &>/dev/null; then
  148. warn " -> Не найден (AUR): $pkg"
  149. missing_aur=1
  150. fi
  151. done < "$SCRIPT_DIR/$AUR_PKGS"
  152. if [ $missing_aur -eq 0 ]; then msg "Все пакеты AUR установлены."; fi
  153. msg "Проверка симлинков..."
  154. # --- 1. Проверка $HOME (из папки 'home') ---
  155. local source_dir="$SCRIPT_DIR/$HOME_DIR_NAME"
  156. if [ -d "$source_dir" ]; then
  157. for item_path in $(find "$source_dir" -mindepth 1 -maxdepth 1); do
  158. local item_name=$(basename "$item_path")
  159. if [ ! -L "$HOME/$item_name" ]; then
  160. warn " -> Симлинк не найден: $HOME/$item_name"
  161. fi
  162. done
  163. fi
  164. # --- 2. Проверка $HOME/.config (из папки 'config') ---
  165. source_dir="$SCRIPT_DIR/$CONFIG_DIR_NAME"
  166. if [ -d "$source_dir" ]; then
  167. for item_path in $(find "$source_dir" -mindepth 1 -maxdepth 1); do
  168. local item_name=$(basename "$item_path")
  169. if [ ! -L "$HOME/.config/$item_name" ]; then
  170. warn " -> Симлинк не найден: $HOME/.config/$item_name"
  171. fi
  172. done
  173. fi
  174. msg "Проверка завершена."
  175. }
  176. # 5. Проверка драйверов
  177. check_drivers() {
  178. msg "Проверка оборудования и рекомендации по драйверам..."
  179. warn "Это только рекомендации! Не устанавливайте автоматически."
  180. # Видеокарта
  181. local vga=$(lspci -k | grep -A 2 -E "(VGA|3D)")
  182. if echo "$vga" | grep -iq "NVIDIA"; then
  183. warn "Найдена карта NVIDIA. Рекомендуемые пакеты:"
  184. warn " -> nvidia (или nvidia-lts, nvidia-dkms)"
  185. warn " -> lib32-nvidia-utils (для 32-bit)"
  186. elif echo "$vga" | grep -iq "Intel"; then
  187. msg "Найдена карта Intel. Рекомендуемые пакеты (обычно уже в списке):"
  188. msg " -> mesa, lib32-mesa, vulkan-intel"
  189. if ! pacman -Q xf86-video-intel &>/dev/null; then
  190. warn " -> xf86-video-intel (старый 2D драйвер, может быть не нужен)"
  191. fi
  192. elif echo "$vga" | grep -iq "AMD"; then
  193. msg "Найдена карта AMD/ATI. Рекомендуемые пакеты (обычно уже в списке):"
  194. msg " -> mesa, lib32-mesa, vulkan-radeon"
  195. fi
  196. # Wi-Fi / Bluetooth
  197. if lspci -k | grep -iq "broadcom"; then
  198. warn "Найден чип Broadcom. Вам может понадобиться:"
  199. warn " -> broadcom-wl-dkms (для Wi-Fi)"
  200. fi
  201. msg "Проверка драйверов завершена."
  202. }
  203. # 6. Интерактивная установка системных конфигов
  204. apply_system_configs() {
  205. msg "--- РЕЖИМ: ПРИМЕНЕНИЕ СИСТЕМНЫХ КОНФИГОВ ---"
  206. local system_source_dir="$SCRIPT_DIR/$SYSTEM_DIR_NAME"
  207. if [ ! -d "$system_source_dir" ]; then
  208. err "Папка '$system_source_dir' не найдена. Создайте ее и поместите туда конфиги."
  209. return 1
  210. fi
  211. # Ищем все *файлы* внутри папки 'system'
  212. find "$system_source_dir" -type f | while read -r source_file; do
  213. # Получаем относительный путь (например, "etc/vconsole.conf")
  214. local rel_path=${source_file#$system_source_dir/}
  215. # Получаем абсолютный целевой путь (например, "/etc/vconsole.conf")
  216. local target_file="/$rel_path"
  217. msg "Найден конфиг: $rel_path"
  218. # 1. Проверяем, существует ли оригинал
  219. if [ ! -f "$target_file" ]; then
  220. warn "Файл '$target_file' не существует. Хотите скопировать новый?"
  221. read -p " [y/N] (Да/Нет): " choice < /dev/tty
  222. if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
  223. # Создаем дирректорию, если нужно
  224. sudo mkdir -p "$(dirname "$target_file")"
  225. sudo cp "$source_file" "$target_file"
  226. msg " -> СКОПИРОВАНО: $target_file"
  227. else
  228. msg " -> Пропущено."
  229. fi
  230. continue # Переходим к следующему файлу
  231. fi
  232. # 2. Оригинал существует, показываем diff
  233. if command -v diff &>/dev/null; then
  234. msg "Разница между вашим конфигом (dotfiles) и системным (/) :"
  235. # diff [оригинал] [новый]
  236. diff -u "$target_file" "$source_file" || true # || true чтобы скрипт не падал, если есть разница
  237. else
  238. warn "Команда 'diff' не найдена. Не могу показать разницу."
  239. fi
  240. # 3. Запрос на замену
  241. warn "Заменить системный файл '$target_file'?"
  242. read -p " [y/N/b] (Да / Нет / Бэкап и замена): " choice < /dev/tty
  243. case "$choice" in
  244. y|Y)
  245. sudo cp "$source_file" "$target_file"
  246. msg " -> ЗАМЕНЕНО: $target_file"
  247. ;;
  248. b|B)
  249. sudo mv "$target_file" "$target_file.bak"
  250. sudo cp "$source_file" "$target_file"
  251. msg " -> БЭКАП СОЗДАН: $target_file.bak"
  252. msg " -> ЗАМЕНЕНО: $target_file"
  253. ;;
  254. *)
  255. msg " -> Пропущено."
  256. ;;
  257. esac
  258. done
  259. msg "--- СИСТЕМНЫЕ КОНФИГИ ОБРАБОТАНЫ ---"
  260. }
  261. # 7. (НОВАЯ ФУНКЦИЯ) Создание стандартных папок пользователя
  262. create_user_dirs() {
  263. msg "Cоздание стандартных папок пользователя"
  264. # Создаем стандартный набор
  265. mkdir -p \
  266. "$HOME/Documents" \
  267. "$HOME/Downloads" \
  268. "$HOME/Pictures"
  269. msg " -> Базовые папки созданы."
  270. }
  271. # --- ГЛАВНЫЙ БЛОК (ВЫБОР РЕЖИМА) ---
  272. show_help() {
  273. echo "Скрипт управления конфигурацией Arch Linux (Dotfiles)"
  274. echo "Использование: $0 [команда]"
  275. echo
  276. echo "Команды:"
  277. echo " install - Установить все пакеты и создать симлинки (полная установка)."
  278. echo " check - Проверить, все ли установлено и настроено."
  279. echo " update - Обновить конфиг из Git и применить изменения (пакеты, симлинки)."
  280. echo " drivers - Проверить оборудование и предложить драйверы."
  281. echo " system - Интерактивно применить системные конфиги из папки '$SYSTEM_DIR_NAME'."
  282. echo " help - Показать это сообщение."
  283. }
  284. # Проверяем, что скрипт не запущен от root
  285. if [ "$EUID" -eq 0 ]; then
  286. err "Не запускайте этот скрипт от имени root (используйте 'sudo' только когда он сам попросит)."
  287. exit 1
  288. fi
  289. # Если нет аргументов, показать помощь
  290. if [ $# -eq 0 ]; then
  291. show_help
  292. exit 0
  293. fi
  294. case "$1" in
  295. install)
  296. msg "--- РЕЖИМ: ПОЛНАЯ УСТАНОВКА ---"
  297. install_packages
  298. link_dotfiles
  299. create_user_dirs # <-- ДОБАВЛЕНО
  300. msg "--- УСТАНОВКА ЗАВЕРШЕНА ---"
  301. msg "Для применения системных конфигов (vconsole.conf и т.д.) запустите: $0 system"
  302. ;;
  303. check)
  304. msg "--- РЕЖИМ: ПРОВЕРКА КОНФИГУРАЦИИ ---"
  305. check_config
  306. ;;
  307. update)
  308. msg "--- РЕЖИМ: ОБНОВЛЕНИЕ КОНФИГУРАЦИИ ---"
  309. msg "1. Получение изменений из Git (git pull)..."
  310. if ! git pull; then
  311. err "Не удалось выполнить 'git pull'. Проверьте подключение и статус репозитория."
  312. exit 1
  313. fi
  314. msg "2. Применение изменений (установка/линковка)..."
  315. install_packages
  316. link_dotfiles
  317. create_user_dirs # <-- ДОБАВЛЕНО
  318. msg "--- ОБНОВЛЕНИЕ ЗАВЕРШЕНО ---"
  319. ;;
  320. drivers)
  321. msg "--- РЕЖИМ: ПРОВЕРКА ДРАЙВЕРОВ ---"
  322. check_drivers
  323. ;;
  324. system)
  325. # (НОВЫЙ РЕЖИМ)
  326. apply_system_configs
  327. ;;
  328. help|*)
  329. show_help
  330. ;;
  331. esac