install.sh 17 KB

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