This repo contains software to build linux from scratch and package it into rpm files.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

458 lines
15 KiB

  1. #!/bin/bash
  2. #-----------------------------------------------------------------------------
  3. # Title: ch6.sh
  4. # Date: 2020-05-31
  5. # Version: 2.0
  6. # Author: chris@cromer.cl
  7. # Options:
  8. #-----------------------------------------------------------------------------
  9. # Copyright 2020 Chris Cromer
  10. # Copyright 2019 Baho Utot
  11. #-----------------------------------------------------------------------------
  12. # This program is free software: you can redistribute it and/or modify
  13. # it under the terms of the GNU General Public License as published by
  14. # the Free Software Foundation, either version 3 of the License, or
  15. # (at your option) any later version.
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. # GNU General Public License for more details.
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  22. #-----------------------------------------------------------------------------
  23. set -o errexit # exit if error...insurance ;)
  24. set -o nounset # exit if variable not initalized
  25. set +h # disable hashall
  26. #-----------------------------------------------------------------------------
  27. # Master variables
  28. PRGNAME=${0##*/} # script name minus the path
  29. TOPDIR=${PWD} # parent directory
  30. PARENT=/usr/src/LFS-RPM # rpm build directory
  31. LOGS=LOGS # build logs directory
  32. INFOS=INFO # rpm info log directory
  33. SPECS=SPECS # rpm spec file directory
  34. PROVIDES=PROVIDES # rpm provides log directory
  35. REQUIRES=REQUIRES # rpm requires log directory
  36. RPMS=RPMS # rpm binary package directory
  37. LOGPATH=${TOPDIR}/LOGS # path to log directory
  38. LC_ALL=POSIX
  39. PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin
  40. export LC_ALL PATH
  41. #-----------------------------------------------------------------------------
  42. # GLOBALS
  43. RPM_NAME=""
  44. RPM_VERSION=""
  45. RPM_RELEASE=""
  46. RPM_SPEC=""
  47. RPM_INSTALLED=""
  48. RPM_ARCH=""
  49. RPM_BINARY=""
  50. RPM_PACKAGE=""
  51. RPM_EXISTS=""
  52. RPM_TARBALLS=""
  53. RPM_MD5SUMS=""
  54. #-----------------------------------------------------------------------------
  55. # Common support functions
  56. function die {
  57. local _red="\\033[1;31m"
  58. local _normal="\\033[0;39m"
  59. [ -n "$*" ] && printf "${_red}$*${_normal}\n"
  60. false
  61. exit 1
  62. }
  63. function msg {
  64. printf "%s\n" "${1}"
  65. return
  66. }
  67. function msg_line {
  68. printf "%s" "${1}"
  69. return
  70. }
  71. function msg_failure {
  72. local _red="\\033[1;31m"
  73. local _normal="\\033[0;39m"
  74. printf "${_red}%s${_normal}\n" "FAILURE"
  75. exit 2
  76. }
  77. function msg_success {
  78. local _green="\\033[1;32m"
  79. local _normal="\\033[0;39m"
  80. printf "${_green}%s${_normal}\n" "SUCCESS"
  81. return
  82. }
  83. function msg_log {
  84. printf "\n%s\n\n" "${1}" >> ${_logfile} 2>&1
  85. return
  86. }
  87. function end_run {
  88. local _green="\\033[1;32m"
  89. local _normal="\\033[0;39m"
  90. printf "${_green}%s${_normal}\n" "Run Complete"
  91. return
  92. }
  93. #-----------------------------------------------------------------------------
  94. # Functions
  95. function _build {
  96. local i=""
  97. local _log="${LOGS}/${RPM_NAME}"
  98. > ${_log}
  99. > ${INFOS}/${RPM_NAME}
  100. > ${PROVIDES}/${RPM_NAME}
  101. > ${REQUIRES}/${RPM_NAME}
  102. rm -rf BUILD BUILDROOT
  103. msg_line "Building: ${RPM_NAME}: "
  104. _md5sum
  105. rpmbuild -ba ${RPM_SPEC} >> ${_log} 2>&1 && msg_success || msg_failure
  106. _status
  107. [ "F" == ${RPM_EXISTS} ] && die "ERROR: Binary Missing: ${RPM_BINARY}"
  108. rpm -qilp ${RPMS}/${RPM_ARCH}/${RPM_BINARY} > ${INFOS}/${RPM_NAME} 2>&1 || true
  109. rpm -qp --provides ${RPMS}/${RPM_ARCH}/${RPM_BINARY} > ${PROVIDES}/${RPM_NAME} 2>&1 || true
  110. rpm -qp --requires ${RPMS}/${RPM_ARCH}/${RPM_BINARY} > ${REQUIRES}/${RPM_NAME} 2>&1 || true
  111. return
  112. }
  113. function _params {
  114. local i=""
  115. RPM_NAME=""
  116. RPM_VERSION=""
  117. RPM_RELEASE=""
  118. RPM_SPEC=""
  119. RPM_INSTALLED=""
  120. RPM_ARCH=""
  121. RPM_BINARY=""
  122. RPM_PACKAGE=""
  123. RPM_EXISTS=""
  124. RPM_TARBALLS=""
  125. RPM_MD5SUMS=""
  126. RPM_SPEC=${1}
  127. RPM_ARCH=$(rpm --eval %_arch)
  128. if [ -e ${RPM_SPEC} ]; then
  129. while read i; do
  130. i=$(echo ${i} | tr -d '[:cntrl:][:space:]')
  131. case ${i} in
  132. Name:*) RPM_NAME=${i##Name:} ;;
  133. Version:*) RPM_VERSION=${i##Version:} ;;
  134. Release:*) RPM_RELEASE=${i##Release:} ;;
  135. ?TARBALL:*) RPM_TARBALLS+="${i##?TARBALL:} " ;;
  136. ?MD5SUM:*) RPM_MD5SUMS+="${i##?MD5SUM:} " ;;
  137. *) ;;
  138. esac
  139. done < ${RPM_SPEC}
  140. # remove trailing whitespace
  141. RPM_TARBALLS=${RPM_TARBALLS## }
  142. RPM_MD5SUMS=${RPM_MD5SUMS## }
  143. else
  144. die "ERROR: ${RPM_SPEC}: does not exist"
  145. fi
  146. RPM_BINARY="${RPM_NAME}-${RPM_VERSION}-${RPM_RELEASE}.${RPM_ARCH}.rpm"
  147. RPM_PACKAGE=${RPM_BINARY%.*}
  148. _status
  149. return
  150. }
  151. function _install {
  152. local _log="${LOGS}/${RPM_NAME}"
  153. _status
  154. [ "F" == ${RPM_EXISTS} ] && die "ERROR: Binary Missing: ${RPM_BINARY}"
  155. [ "T" == ${RPM_INSTALLED} ] && return
  156. msg_line "Installing: ${RPM_BINARY}: "
  157. rpm -Uvh --nodeps "${RPMS}/${RPM_ARCH}/${RPM_BINARY}" >> "${_log}" 2>&1 && msg_success || msg_failure
  158. return
  159. }
  160. function _status {
  161. [ -e "${RPMS}/${RPM_ARCH}/${RPM_BINARY}" ] && RPM_EXISTS="T" || RPM_EXISTS="F"
  162. [ "${RPM_PACKAGE}" == "$(rpm -q "$RPM_PACKAGE")" ] && RPM_INSTALLED="T" || RPM_INSTALLED="F"
  163. return
  164. }
  165. function _print {
  166. msg "Status for ${RPM_BINARY}"
  167. msg "Spec--------> ${RPM_SPEC}"
  168. msg "Name--------> ${RPM_NAME}"
  169. msg "Version-----> ${RPM_VERSION}"
  170. msg "Release-----> ${RPM_RELEASE}"
  171. msg "Arch--------> ${RPM_ARCH}"
  172. msg "Package-----> ${RPM_PACKAGE}"
  173. msg "Binary------> ${RPM_BINARY}"
  174. msg "Exists------> ${RPM_EXISTS}"
  175. msg "Installed---> ${RPM_INSTALLED}"
  176. for i in ${RPM_TARBALLS}; do msg "Tarball-----> ${i}";done
  177. for i in ${RPM_MD5SUMS}; do msg "MD5SUM------> ${i}";done
  178. return
  179. }
  180. function _md5sum {
  181. local i=""
  182. [ -z "${RPM_TARBALLS}" ] && return
  183. > SOURCES/"MD5SUM"
  184. for i in ${RPM_MD5SUMS}; do printf "%s\n" "$(echo ${i} | tr ";" " ")" >> SOURCES/"MD5SUM";done
  185. md5sum -c SOURCES/"MD5SUM" > /dev/null 2>&1 || die "Source checksum error: ${RPM_SPEC}"
  186. return
  187. }
  188. function _symlinks {
  189. msg_line "Installing Essential Files and Symlinks: "
  190. _log="${LOGS}/symlinks"
  191. > ${_log}
  192. ln -vsf /tools/bin/{bash,cat,chmod,dd,echo,ln,mkdir,pwd,rm,stty,touch} /bin >> "${_log}" 2>&1
  193. ln -vsf /tools/bin/{env,install,perl,printf} /usr/bin >> "${_log}" 2>&1
  194. ln -vsf /tools/lib/libgcc_s.so{,.1} /usr/lib >> "${_log}" 2>&1
  195. ln -vsf /tools/lib/libstdc++.{a,so{,.6}} /usr/lib >> "${_log}" 2>&1
  196. ln -vsf bash /bin/sh >> "${_log}" 2>&1
  197. msg_success
  198. return
  199. }
  200. function _glibc {
  201. ln -sf ../lib/ld-linux-x86-64.so.2 /lib64
  202. ln -sf ../lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
  203. _build
  204. _install
  205. /sbin/locale-gen
  206. return
  207. }
  208. function _adjust {
  209. msg_line " Adjusting tool chain: "
  210. _log="${LOGS}/adjust"
  211. > "${_log}"
  212. mv -v /tools/bin/{ld,ld-old} >> "${_log}" 2>&1
  213. mv -v /tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old} >> "${_log}" 2>&1
  214. mv -v /tools/bin/{ld-new,ld} >> "${_log}" 2>&1
  215. ln -sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld >> "${_log}" 2>&1
  216. gcc -dumpspecs | sed -e 's@/tools@@g' -e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' -e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > `dirname $(gcc --print-libgcc-file-name)`/specs
  217. touch ${_log}
  218. _log="${LOGS}/adjust.test"
  219. msg_line "Testing tool chain: "
  220. > "${_log}"
  221. echo 'int main(){}' > dummy.c
  222. cc dummy.c -v -Wl,--verbose &> dummy.log
  223. msg " " >> "${_log}" 2>&1
  224. msg "Test: [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]" >> "${_log}" 2>&1
  225. readelf -l a.out | grep ': /lib' >> "${_log}" 2>&1
  226. msg " " >> "${_log}" 2>&1
  227. msg "Test: /usr/lib/../lib/crt1.o succeeded" >> "${_log}" 2>&1
  228. msg "Test: /usr/lib/../lib/crti.o succeeded" >> "${_log}" 2>&1
  229. msg "Test: /usr/lib/../lib/crtn.o succeeded" >> "${_log}" 2>&1
  230. grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log >> "${_log}" 2>&1
  231. msg " " >> "${_log}" 2>&1
  232. msg "Test: #include <...> search starts here:" >> "${_log}" 2>&1
  233. msg "Test: /usr/include" >> "${_log}" 2>&1
  234. grep -B1 '^ /usr/include' dummy.log>> "${_log}" 2>&1
  235. msg " " >> "${_log}" 2>&1
  236. msg "Test: SEARCH_DIR("/usr/lib")" >> "${_log}" 2>&1
  237. msg "Test: SEARCH_DIR("/lib")" >> "${_log}" 2>&1
  238. grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g' >> "${_log}" 2>&1
  239. msg " " >> "${_log}" 2>&1
  240. msg "Test: attempt to open /lib/libc.so.6 succeeded" >> "${_log}" 2>&1
  241. grep "/lib.*/libc.so.6 " dummy.log >> "${_log}" 2>&1
  242. msg " " >> "${_log}" 2>&1
  243. msg "Test: found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2" >> "${_log}" 2>&1
  244. grep found dummy.log >> "${_log}" 2>&1
  245. msg " " >> "${_log}" 2>&1
  246. rm -v dummy.c a.out dummy.log >> "${_log}" 2>&1
  247. msg_success
  248. touch ${_log}
  249. return
  250. }
  251. function _gcc {
  252. _build
  253. _install
  254. _log="${LOGS}/gcc.test"
  255. msg_line " Testing ${i}: "
  256. _log="${LOGS}/gcc.test"
  257. > "${_log}"
  258. echo 'int main(){}' > dummy.c
  259. cc dummy.c -v -Wl,--verbose &> dummy.log
  260. msg " " >> "${_log}" 2>&1
  261. readelf -l a.out | grep ': /lib' >> "${_log}" 2>&1
  262. msg "Test:" >> "${_log}" 2>&1
  263. msg "[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]" >> "${_log}" 2>&1
  264. msg " " >> "${_log}" 2>&1
  265. grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log >> "${_log}" 2>&1
  266. msg "Test:" >> "${_log}" 2>&1
  267. msg "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib/crt1.o succeeded" >> "${_log}" 2>&1
  268. msg "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib/crti.o succeeded" >> "${_log}" 2>&1
  269. msg "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib/crtn.o succeeded" >> "${_log}" 2>&1
  270. msg " " >> "${_log}" 2>&1
  271. grep -B4 '^ /usr/include' dummy.log >> "${_log}" 2>&1
  272. msg "Test:" >> "${_log}" 2>&1
  273. msg "#include <...> search starts here:" >> "${_log}" 2>&1
  274. msg "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include" >> "${_log}" 2>&1
  275. msg "/usr/local/include" >> "${_log}" 2>&1
  276. msg "/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/include-fixed" >> "${_log}" 2>&1
  277. msg "/usr/include" >> "${_log}" 2>&1
  278. msg " " >> "${_log}" 2>&1
  279. grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g' >> "${_log}" 2>&1
  280. msg "Test:" >> "${_log}" 2>&1
  281. msg "SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")" >> "${_log}" 2>&1
  282. msg "SEARCH_DIR("/usr/local/lib64")" >> "${_log}" 2>&1
  283. msg "SEARCH_DIR("/lib64")" >> "${_log}" 2>&1
  284. msg "SEARCH_DIR("/usr/lib64")" >> "${_log}" 2>&1
  285. msg "SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")" >> "${_log}" 2>&1
  286. msg "SEARCH_DIR("/usr/local/lib")" >> "${_log}" 2>&1
  287. msg "SEARCH_DIR("/lib")" >> "${_log}" 2>&1
  288. msg "SEARCH_DIR("/usr/lib");" >> "${_log}" 2>&1
  289. msg " " >> "${_log}" 2>&1
  290. grep "/lib.*/libc.so.6 " dummy.log >> "${_log}" 2>&1
  291. msg "Test:" >> "${_log}" 2>&1
  292. msg "attempt to open /lib/libc.so.6 succeeded" >> "${_log}" 2>&1
  293. msg " " >> "${_log}" 2>&1
  294. grep found dummy.log >> "${_log}" 2>&1
  295. msg "Test:" >> "${_log}" 2>&1
  296. msg "found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2" >> "${_log}" 2>&1
  297. msg " " >> "${_log}" 2>&1
  298. rm -v dummy.c a.out dummy.log >> "${_log}" 2>&1
  299. msg_success
  300. return
  301. }
  302. #-----------------------------------------------------------------------------
  303. # Main line
  304. # Create directories if needed
  305. [ -e "${LOGS}" ] || install -vdm 755 "${LOGS}"
  306. [ -e "${INFOS}" ] || install -vdm 755 "${INFOS}"
  307. [ -e "${PROVIDES}" ] || install -vdm 755 "${PROVIDES}"
  308. [ -e "${REQUIRES}" ] || install -vdm 755 "${REQUIRES}"
  309. [ -e "${RPMS}" ] || install -vdm 755 "${RPMS}"
  310. LIST+="filesystem " # Creating Directories
  311. LIST+="symlinks " # Creating Essential Files and Symlinks
  312. LIST+="linux-api-headers " # Linux-5.5.3 API Headers
  313. LIST+="man-pages " # Man-pages-5.05
  314. LIST+="glibc " # Glibc-2.31
  315. LIST+="tzdata " # Adding time zone data
  316. LIST+="adjust " # Adjusting the Toolchain
  317. LIST+="zlib " # Zlib-1.2.11
  318. LIST+="bzip2 " # Bzip2-1.0.8
  319. LIST+="xz " # Xz-5.2.4
  320. LIST+="file " # File-5.38
  321. LIST+="readline " # Readline-8.0
  322. LIST+="m4 " # M4-1.4.18
  323. LIST+="bc " # Bc-2.5.3
  324. LIST+="binutils " # Binutils-2.34
  325. LIST+="gmp " # GMP-6.2.0
  326. LIST+="mpfr " # MPFR-4.0.2
  327. LIST+="mpc " # MPC-1.1.0
  328. LIST+="attr " # Attr-2.4.48
  329. LIST+="acl " # Acl-2.2.53
  330. LIST+="shadow " # Shadow-4.8.1
  331. LIST+="gcc " # GCC-9.2.0
  332. LIST+="pkg-config " # Pkg-config-0.29.2
  333. LIST+="ncurses " # Ncurses-6.2
  334. LIST+="libcap " # Libcap-2.31
  335. LIST+="sed " # Sed-4.8
  336. LIST+="psmisc " # Psmisc-23.2
  337. LIST+="iana-etc " # Iana-Etc-2.30
  338. LIST+="bison " # Bison-3.5.2
  339. LIST+="flex " # Flex-2.6.4
  340. LIST+="grep " # Grep-3.4
  341. LIST+="bash " # Bash-5.0
  342. LIST+="libtool " # Libtool-2.4.6
  343. LIST+="gdbm " # GDBM-1.18.1
  344. LIST+="gperf " # Gperf-3.1
  345. LIST+="expat " # Expat-2.2.9
  346. LIST+="inetutils " # Inetutils-1.9.4
  347. LIST+="perl " # Perl-5.30.1
  348. LIST+="XML-Parser " # XML::Parser-2.46
  349. LIST+="intltool " # Intltool-0.51.0
  350. LIST+="autoconf " # Autoconf-2.69
  351. LIST+="automake " # Automake-1.16.1
  352. LIST+="kmod " # Kmod-26
  353. LIST+="gettext " # Gettext-0.20.1
  354. LIST+="libelf " # Libelf from Elfutils-0.178
  355. LIST+="libffi " # Libffi-3.3
  356. LIST+="openssl " # OpenSSL-1.1.1d
  357. LIST+="python3 " # Python-3.8.1
  358. LIST+="ninja " # Ninja-1.10.0
  359. LIST+="meson " # Meson-0.53.1
  360. LIST+="coreutils " # Coreutils-8.31
  361. LIST+="check " # Check-0.14.0
  362. LIST+="diffutils " # Diffutils-3.7
  363. LIST+="gawk " # Gawk-5.0.1
  364. LIST+="findutils " # Findutils-4.7.0
  365. LIST+="groff " # Groff-1.22.4
  366. LIST+="grub " # GRUB-2.04
  367. LIST+="less " # Less-551
  368. LIST+="gzip " # Gzip-1.10
  369. LIST+="zstd " # Zstd-1.4.4
  370. LIST+="iproute2 " # IPRoute2-5.5.0
  371. LIST+="kbd " # Kbd-2.2.0
  372. LIST+="libpipeline " # Libpipeline-1.5.2
  373. LIST+="make " # Make-4.3
  374. LIST+="patch " # Patch-2.7.6
  375. LIST+="man-db " # Man-DB-2.9.0
  376. LIST+="tar " # Tar-1.32
  377. LIST+="texinfo " # Texinfo-6.7
  378. LIST+="vim " # Vim-8.2.0190
  379. LIST+="procps-ng " # Procps-ng-3.3.15
  380. LIST+="util-linux " # Util-linux-2.35.1
  381. LIST+="e2fsprogs " # E2fsprogs-1.45.5
  382. LIST+="sysklogd " # Sysklogd-1.5.1
  383. LIST+="sysvinit " # Sysvinit-2.96
  384. LIST+="eudev " # Eudev-3.2.9
  385. # Chapter 7
  386. LIST+="lfs-bootscripts " # lfs-bootscripts
  387. LIST+="cpio " # cpio
  388. LIST+="mkinitramfs " # mkinitramfs
  389. LIST+="linux " # Linux-5.5.3
  390. # ADDONS
  391. LIST+="popt " # popt
  392. LIST+="rpm " # rpm
  393. LIST+="wget " # wget
  394. LIST+="linux-firmware " # linux-firmware
  395. LIST+="base " # lfs base packages meta package
  396. for i in ${LIST};do
  397. case ${i} in
  398. symlinks) _log="${LOGS}/symlinks"
  399. if [ -e ${_log} ]; then
  400. msg "Skipping: Installing Essential Files and Symlinks"
  401. else
  402. _symlinks
  403. fi
  404. ;;
  405. glibc) _params "${SPECS}/${i}.spec"
  406. if [ "T" = "${RPM_EXISTS}" ]; then
  407. msg "Skipping: ${i}"
  408. else
  409. _glibc
  410. fi
  411. ;;
  412. adjust) _log="${LOGS}/adjust"
  413. if [ -e ${_log} ]; then
  414. msg "Skipping: Adjusting tool chain"
  415. else
  416. _adjust
  417. fi
  418. ;;
  419. gcc) _params "${SPECS}/${i}.spec"
  420. if [ "T" = "${RPM_EXISTS}" ]; then
  421. msg "Skipping: ${i}"
  422. else
  423. _gcc
  424. fi
  425. ;;
  426. *) _params "${SPECS}/${i}.spec"
  427. if [ "T" = "${RPM_EXISTS}" ]; then
  428. msg "Skipping: ${i}"
  429. else
  430. _build
  431. _install
  432. fi
  433. ;;
  434. esac
  435. done
  436. # update ld cache, generate locales and set user/group files
  437. unset LIST
  438. LIST+="/sbin/ldconfig "
  439. LIST+="/sbin/locale-gen "
  440. LIST+="/usr/sbin/pwconv "
  441. LIST+="/usr/sbin/grpconv "
  442. for i in ${LIST}; do msg_line "${i}: ";eval " ${i}";msg_success;done
  443. # Configure
  444. unset LIST
  445. LIST+="/etc/sysconfig/clock "
  446. LIST+="/etc/passwd "
  447. LIST+="/etc/hosts "
  448. LIST+="/etc/hostname "
  449. LIST+="/etc/fstab "
  450. LIST+="/etc/sysconfig/ifconfig.eth0 "
  451. LIST+="/etc/resolv.conf "
  452. LIST+="/etc/lsb-release "
  453. LIST+="/etc/sysconfig/rc.site "
  454. for i in ${LIST}; do vim "${i}";done
  455. end_run