-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
init.sh
executable file
·377 lines (336 loc) · 12.2 KB
/
init.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
#!/usr/bin/env sh
# init
# Author: Lucas Larson
#
# Description: bootstrap a new machine
# Assumptions: installation target is one of Arch Linux or Alpine Linux
# Alpine Linux
# wget --continue --server-response 'https://lucaslarson.net/init.sh'
# apk add --verbose "$@"
# Arch Linux
# curl --remote-name --location 'https://lucaslarson.net/init.sh'
# pacman --sync --verbose --noconfirm "$@"
if command -v -- wget >/dev/null 2>&1; then
command wget --continue --server-response 'https://lucaslarson.net/init.sh'
else
command curl --remote-name --location 'https://lucaslarson.net/init.sh'
fi
if command -v -- apk >/dev/null 2>&1; then
alias install='command apk add --verbose'
elif command -v -- pacman >/dev/null 2>&1; then
alias install='command pacman --sync --verbose --noconfirm'
elif command -v -- apt-get >/dev/null 2>&1; then
alias install='command apt-get install --verbose --show-progress --assume-yes'
fi
clear
printf ' .\137\137 .\137\137 \137\137\n' 2>/dev/null
printf ' \174\137\137\174 \137\137\137\137 \174\137\137\174\057 \174\137\n' 2>/dev/null
printf ' \174 \174\057 \134\174 \134 \137\137\134\n' 2>/dev/null
printf ' \174 \174 \174 \134 \174\174 \174\n' 2>/dev/null
printf ' \174\137\137\174\137\137\137\174' 2>/dev/null
printf ' \057\137\137\174\174\137\137\174\n' 2>/dev/null
printf ' \134\057\n\n' 2>/dev/null
printf ' Linux setup\n' 2>/dev/null
command sleep 1
printf ' a Lucas Larson production\n\n' 2>/dev/null
command sleep 1
# start from `$HOME`
cd -- "${HOME-}" ||
exit 1
# unset `$PS4`
# if this quaternary prompt string is already unset, then
# set it to the POSIX default: `+ `
# https://opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
ps4_temporary="${PS4:-+ }"
unset -- PS4
set -o xtrace
# pacman
# https://askubuntu.com/a/459425
command sed -e '1q' /etc/os-release 2>/dev/null | command grep -q -e 'Arch Linux' && {
command pacman --sync --refresh --refresh ||
# https://wiki.archlinux.org/?oldid=667441#Installing_packages
command pacman --sync --refresh --upgrades 2>/dev/null
}
# apk
command -v -- apk >/dev/null 2>&1 || {
# trust apk only if it matches a known checksum
{ set +o xtrace; } 2>/dev/null
printf 'verifying apk tools integrity...\n' 2>/dev/null
set -o xtrace
test "$(command curl --fail --silent --location 'https://web.archive.org/web/20201127185919id_/dl-cdn.alpinelinux.org/alpine/v3.12/main/x86/apk-tools-static-2.10.5-r1.apk' | command cksum)" != '2112918202 1400307'
} || {
# https://web.archive.org/web/20201127045648id_/github.com/ish-app/ish/wiki/Installing-apk-on-the-App-Store-Version#wiki-body
command wget --output-document=- 'https://web.archive.org/web/20201127185919id_/dl-cdn.alpinelinux.org/alpine/v3.12/main/x86/apk-tools-static-2.10.5-r1.apk' |
command tar --extract --gzip 'apk.static'
./apk.static add apk-tools
}
# configure only main and community repositories at first
{
printf 'https://dl-cdn.alpinelinux.org/alpine/latest-stable/main\n'
printf 'https://dl-cdn.alpinelinux.org/alpine/latest-stable/community\n'
} >'/etc/apk/repositories'
# update
{ set +o xtrace; } 2>/dev/null
printf 'updating Alpine Linux repositories...\n' 2>/dev/null
set -o xtrace
command apk update --verbose --progress
command apk upgrade --verbose --progress
# https://wiki.alpinelinux.org/w/index.php?oldid=17773&title=How_to_get_regular_stuff_working#Man_pages
# man-pages adds `man0`, `man2`, man4`, `man6` to `/usr/share/man/`
{ test -d '/usr/share/man/man0' &&
test -d '/usr/share/man/man2' &&
test -d '/usr/share/man/man4' &&
test -d '/usr/share/man/man6'; } || {
{ set +o xtrace; } 2>/dev/null
printf 'installing man pages...\n' 2>/dev/null
set -o xtrace
install man-pages
}
command -v -- mandoc >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing mandoc for man pages...\n' 2>/dev/null
set -o xtrace
install mandoc mandoc-doc
}
command -v -- less >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing less to read man pages...\n' 2>/dev/null
set -o xtrace
install less less-doc
}
# https://wiki.alpinelinux.org/w/index.php?oldid=17773&title=How_to_get_regular_stuff_working#Shell_.40_commandline
# https://web.archive.org/web/20210218201739id_/web.archive.org/screenshot/docs.google.com/document/d/10-8wjANQGbG43XZ0wN57M1RYOLUwu9RZATNe9vJQYKw/mobilebasic
# https://wiki.alpinelinux.org/w/index.php?oldid=18038&title=Alpine_newbie_apk_packages#coreutils_libc_and_utmps_in_alpine
install coreutils coreutils-doc
{ test -x '/usr/bin/coreutils' &&
command find --version >/dev/null 2>&1 | command grep -q -e 'findutils'; } || {
{ set +o xtrace; } 2>/dev/null
printf 'installing Linux utilities...\n' 2>/dev/null
set -o xtrace
}
install util-linux util-linux-doc pciutils pciutils-doc usbutils usbutils-doc coreutils coreutils-doc binutils binutils-doc findutils findutils-doc grep grep-doc wget wget-doc curl curl-doc openssl openssl-doc sudo sudo-doc sed sed-doc attr attr-doc dialog dialog-doc bash bash-doc bash-completion bash-completion-doc readline readline-doc
{
printf 'https://dl-cdn.alpinelinux.org/alpine/edge/main\n'
printf 'https://dl-cdn.alpinelinux.org/alpine/edge/community\n'
printf 'https://dl-cdn.alpinelinux.org/alpine/edge/testing\n'
} >>'/etc/apk/repositories'
command apk update
# ssh
# https://wiki.alpinelinux.org/w/index.php?oldid=13842&title=Setting_up_a_ssh-server#OpenSSH
test -d '/etc/ssh' || {
{ set +o xtrace; } 2>/dev/null
printf 'installing OpenSSH...\n' 2>/dev/null
set -o xtrace
install openssh openssh-doc
}
# gpg
# https://wiki.alpinelinux.org/w/index.php?oldid=17295&title=Setting_up_a_laptop#Creating_GPG_keys
test -x '/usr/bin/gpg2' || {
{ set +o xtrace; } 2>/dev/null
printf 'installing GPG...\n' 2>/dev/null
set -o xtrace
install gnupg gnupg-doc
}
# git
command -v -- git >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing Git...\n' 2>/dev/null
set -o xtrace
install git git-doc
}
# git add --patch
test -x '/usr/libexec/git-core/git-add--interactive' || {
# https://stackoverflow.com/a/57632778
install git-perl
}
# git user
command git config --global --get user.name >/dev/null 2>&1 || {
command git config --global user.name 'Lucas Larson'
}
# git default branch
command git config --global --get init.defaultBranch >/dev/null 2>&1 || {
command git config --global init.defaultBranch 'main'
}
# time zone
{ set +o xtrace; } 2>/dev/null
printf 'updating time zone information...\n' 2>/dev/null
set -o xtrace
install --no-cache tzdata tzdata-doc
test -r '/usr/share/zoneinfo/America/New_York' &&
cp -- '/usr/share/zoneinfo/America/New_York' '/etc/localtime'
printf 'America/New_York\n' >'/etc/timezone'
# python
{ set +o xtrace; } 2>/dev/null
printf 'checking Python installation...\n' 2>/dev/null
set -o xtrace
command -v -- python >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing Python...\n' 2>/dev/null
set -o xtrace
install python3 python3-doc
}
# pip
{ set +o xtrace; } 2>/dev/null
printf 'checking Python package manager installation...\n' 2>/dev/null
set -o xtrace
command -v -- pip >/dev/null 2>&1 && {
{ set +o xtrace; } 2>/dev/null
printf 'updating pip...\n' 2>/dev/null
set -o xtrace
command python3 -m pip install --upgrade pip 2>/dev/null
} || {
{ set +o xtrace; } 2>/dev/null
{
printf 'installing pip...\n'
printf 'verifying integrity of pip bootstrap file...\n'
} 2>/dev/null
set -o xtrace
test "$(command curl --fail --silent --location 'https://web.archive.org/web/20210420182646id_/bootstrap.pypa.io/get-pip.py' | command cksum)" != '545084056 1927630'
} || {
{ set +o xtrace; } 2>/dev/null
printf 'installing pip using bootstrap...\n' 2>/dev/null
set -o xtrace
command curl 'https://web.archive.org/web/20210420182646id_/bootstrap.pypa.io/get-pip.py' -o ./get-pip.py
{ set +o xtrace; } 2>/dev/null
printf 'this may take a while...\n' 2>/dev/null
set -o xtrace
command python3 -v ./get-pip.py
}
# mackup
command -v -- mackup >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing mackup...\n' 2>/dev/null
set -o xtrace
command pip install --upgrade mackup
}
# zsh
command -v -- zsh >/dev/null 2>&1 || {
{ set +o xtrace; } 2>/dev/null
printf 'installing Zsh...\n' 2>/dev/null
set -o xtrace
install zsh zsh-doc
}
# chsh
# part of shadow on Alpine Linux
command -v -- chsh >/dev/null 2>&1 || {
install shadow shadow-doc
}
# Oh My Zsh
command -v -- omz >/dev/null 2>&1 ||
test -d "${ZSH:="${HOME-}"/.oh-my-zsh}" ||
test "$(command curl --fail --silent --location 'https://web.archive.org/web/20210520175616id_/raw.githubusercontent.com/ohmyzsh/ohmyzsh/02d07f3e3dba0d50b1d907a8062bbaca18f88478/tools/install.sh' | command cksum)" != '1976015298 9942' || {
{ set +o xtrace; } 2>/dev/null
printf 'installing Oh My Zsh...\n' 2>/dev/null
if command -v -- wget >/dev/null 2>&1; then
set -o xtrace
sh -c "$(command wget 'https://web.archive.org/web/20210520175616id_/raw.githubusercontent.com/ohmyzsh/ohmyzsh/02d07f3e3dba0d50b1d907a8062bbaca18f88478/tools/install.sh' --output-document=-)" "" --unattended --keep-zshrc
elif command -v -- curl >/dev/null 2>&1; then
set -o xtrace
sh -c "$(curl --location 'https://web.archive.org/web/20210520175616id_/raw.githubusercontent.com/ohmyzsh/ohmyzsh/02d07f3e3dba0d50b1d907a8062bbaca18f88478/tools/install.sh')" --unattended --keep-zshrc
fi
{ set +o xtrace; } 2>/dev/null
}
# update, repair everything again before close
{ set +o xtrace; } 2>/dev/null
printf 'updating...\n' 2>/dev/null
set -o xtrace
command apk update --verbose --verbose --progress
{ set +o xtrace; } 2>/dev/null
printf 'upgrading...\n' 2>/dev/null
set -o xtrace
command apk upgrade --verbose --verbose --progress
{ set +o xtrace; } 2>/dev/null
printf 'repairing and resolving dependencies...\n' 2>/dev/null
set -o xtrace
command apk fix --verbose --verbose --depends --progress
{ set +o xtrace; } 2>/dev/null
printf 'verifying installations...\n' 2>/dev/null
set -o xtrace
command apk verify --verbose --verbose --progress && {
{ set +o xtrace; } 2>/dev/null
printf 'verified\n' 2>/dev/null
set -o xtrace
}
# cleanup
{ set +o xtrace; } 2>/dev/null
printf 'cleaning up temporary installation files and performing housekeeping...\n' 2>/dev/null
set -o xtrace
test -w ./apk.static &&
rm ./apk.static
test -w ./get-pip.py &&
rm ./get-pip.py
test -w ./setup &&
rm ./setup
# message of the day
test -s '/etc/motd' &&
cp -- '/etc/motd' '/etc/motd-'"$(command date '+%Y%m%d_%s')" &&
printf '' >'/etc/motd'
# delete thumbnail cache files
command find -- . \
-type f \
'(' \
-name '.DS_Store' -o \
-name 'Desktop.ini' -o \
-name 'Thumbs.db' -o \
-name 'desktop.ini' -o \
-name 'thumbs.db' \
')' \
-delete 2>/dev/null
# delete empty, writable, zero-length files
# except those within `.git/` directories
# and those with specific names
command find -- . \
-type f \
-writable \
-size 0 \
'(' \
! -path '*.git/*' \
! -path '*example*' \
! -path '*sample*' \
! -path '*template*' \
! -path '*test*' \
! -name "$(printf 'Icon\0xd\0xa')" \
! -name '*LOCK' \
! -name '*empty*' \
! -name '*hushlogin' \
! -name '*ignore' \
! -name '*journal' \
! -name '*lock' \
! -name '*lockfile' \
! -name '.dirstamp' \
! -name '.gitkeep' \
! -name '.gitmodules' \
! -name '.keep' \
! -name '.sudo_as_admin_successful' \
! -name '.watchmanconfig' \
! -name '__init__.py' \
! -name 'favicon.*' \
')' \
-delete 2>/dev/null
# delete empty directories recursively
# but skip Git-specific and `/.well-known/` directories
command find -- . -type d -empty \
! -path '*.git/*' \
! -name '.well-known' \
-delete 2>/dev/null
# if sed installation was successful, and
# if zsh is available, replace bash, ash, and sh with zsh in `/etc/passwd`
command -v -- zsh >/dev/null 2>&1 &&
command grep -E -e '/bin/b?a?sh' '/etc/passwd' 2>&1 &&
cp -- '/etc/passwd' '/etc/passwd-'"$(command date '+%Y%m%d_%s')" &&
# `-E` for extended regex searching for `/bin/ash` and `/bin/sh`
# `-i` for in-place editing
command sed -E -i -e "s|/bin/b?a?sh$|$(command -v -- zsh)|" '/etc/passwd'
# done
{ set +euvx; } 2>/dev/null
printf 'installation complete\n' 2>/dev/null
command sleep 1
printf 'exiting to apply updates...\n' 2>/dev/null
# restore `$PS4`
PS4="${ps4_temporary:-+ }"
unset -- ps4_temporary
{
printf '\n'
printf 'done!\n'
} 2>/dev/null
exit