learn_bash_from_session_data 1.0.10 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/enrichment_builtins.py +1266 -0
- package/scripts/enrichment_coreutils.py +1499 -0
- package/scripts/enrichment_netproc.py +2270 -0
- package/scripts/enrichment_netsys.py +1601 -0
- package/scripts/enrichment_pkgcomp.py +2185 -0
- package/scripts/enrichment_textdev.py +2016 -0
- package/scripts/html_generator.py +144 -1
- package/scripts/knowledge_base.py +11521 -5648
- package/scripts/main.py +1 -1
- package/scripts/merge_enrichment.py +272 -0
|
@@ -0,0 +1,2185 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enrichment data for Package Management, Compression, Git tools, and Miscellaneous commands.
|
|
3
|
+
|
|
4
|
+
This module provides additional metadata (use_cases, gotchas, man_url, related, difficulty,
|
|
5
|
+
and extra_flags) for commands that exist in COMMAND_DB but have thin entries missing these
|
|
6
|
+
fields. Merge this data into COMMAND_DB to complete the knowledge base.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Dict, Any
|
|
10
|
+
|
|
11
|
+
ENRICHMENT_DATA: Dict[str, Dict[str, Any]] = {
|
|
12
|
+
|
|
13
|
+
# =========================================================================
|
|
14
|
+
# PACKAGE MANAGEMENT -- System-level
|
|
15
|
+
# =========================================================================
|
|
16
|
+
|
|
17
|
+
"apt": {
|
|
18
|
+
"man_url": "https://manpages.debian.org/bookworm/apt/apt.8.en.html",
|
|
19
|
+
"use_cases": [
|
|
20
|
+
"Update package list and upgrade all packages: apt update && apt upgrade -y",
|
|
21
|
+
"Search for packages matching a keyword: apt search nginx",
|
|
22
|
+
"Show detailed information about a package before installing: apt show package-name",
|
|
23
|
+
"List all installed packages for auditing: apt list --installed",
|
|
24
|
+
"Remove a package and its configuration files: apt purge package-name",
|
|
25
|
+
],
|
|
26
|
+
"gotchas": [
|
|
27
|
+
"apt is designed for interactive terminal use; scripts should use apt-get for a stable CLI interface that will not change output format between releases",
|
|
28
|
+
"Running apt without sudo gives permission errors -- most operations require root",
|
|
29
|
+
"apt update only refreshes the package index; it does not install anything -- you must follow with apt upgrade to actually apply updates",
|
|
30
|
+
"apt autoremove can remove packages that other software still depends on if dependency metadata is stale -- review the list before confirming",
|
|
31
|
+
],
|
|
32
|
+
"related": ["apt-get", "apt-cache", "dpkg", "snap"],
|
|
33
|
+
"difficulty": "beginner",
|
|
34
|
+
"extra_flags": {
|
|
35
|
+
"--no-install-recommends": "Do not install recommended packages as dependencies",
|
|
36
|
+
"--fix-broken": "Attempt to fix broken dependencies",
|
|
37
|
+
"-f": "Alias for --fix-broken",
|
|
38
|
+
"--dry-run": "Simulate the operation without making changes",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
"apt-get": {
|
|
43
|
+
"man_url": "https://manpages.debian.org/bookworm/apt/apt-get.8.en.html",
|
|
44
|
+
"use_cases": [
|
|
45
|
+
"Install a package non-interactively in a script: apt-get install -y nginx",
|
|
46
|
+
"Upgrade all packages without removing anything: apt-get upgrade -y",
|
|
47
|
+
"Full distribution upgrade that handles dependency changes: apt-get dist-upgrade",
|
|
48
|
+
"Download package source code for inspection: apt-get source package-name",
|
|
49
|
+
"Clean downloaded package cache to free disk space: apt-get clean",
|
|
50
|
+
],
|
|
51
|
+
"gotchas": [
|
|
52
|
+
"apt-get install will not upgrade already-installed packages to the latest version unless you explicitly pass --only-upgrade or run apt-get upgrade first",
|
|
53
|
+
"apt-get dist-upgrade may remove packages to resolve dependency conflicts -- always review what it proposes before confirming",
|
|
54
|
+
"The -y flag auto-confirms prompts, which is useful in scripts but dangerous if you have not reviewed the planned changes first",
|
|
55
|
+
],
|
|
56
|
+
"related": ["apt", "apt-cache", "dpkg", "aptitude"],
|
|
57
|
+
"difficulty": "beginner",
|
|
58
|
+
"extra_flags": {
|
|
59
|
+
"--only-upgrade": "Only upgrade already-installed packages, do not install new ones",
|
|
60
|
+
"--no-install-recommends": "Do not install recommended packages",
|
|
61
|
+
"--reinstall": "Reinstall packages that are already installed",
|
|
62
|
+
"-d": "Download only, do not install or unpack",
|
|
63
|
+
"--purge": "Remove packages and their configuration files",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"apt-cache": {
|
|
68
|
+
"man_url": "https://manpages.debian.org/bookworm/apt/apt-cache.8.en.html",
|
|
69
|
+
"use_cases": [
|
|
70
|
+
"Search for available packages by keyword: apt-cache search web server",
|
|
71
|
+
"Show all available versions of a package: apt-cache showpkg nginx",
|
|
72
|
+
"Display dependencies of a package before installing: apt-cache depends nginx",
|
|
73
|
+
"Find which packages depend on a given package: apt-cache rdepends libssl3",
|
|
74
|
+
"Display package metadata including description and size: apt-cache show nginx",
|
|
75
|
+
],
|
|
76
|
+
"gotchas": [
|
|
77
|
+
"apt-cache searches the local package index, not the remote repositories -- run apt update first to get current results",
|
|
78
|
+
"apt-cache search uses regex by default, so special characters like + in package names (e.g., g++) need escaping",
|
|
79
|
+
],
|
|
80
|
+
"related": ["apt", "apt-get", "dpkg", "aptitude"],
|
|
81
|
+
"difficulty": "beginner",
|
|
82
|
+
"extra_flags": {
|
|
83
|
+
"policy": "Show installed and candidate versions plus repository priority",
|
|
84
|
+
"madison": "Show available versions in a tabular format",
|
|
85
|
+
"--names-only": "Search only package names, not descriptions",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
"dpkg": {
|
|
90
|
+
"man_url": "https://man7.org/linux/man-pages/man1/dpkg.1.html",
|
|
91
|
+
"use_cases": [
|
|
92
|
+
"Install a locally downloaded .deb file: dpkg -i package.deb",
|
|
93
|
+
"List all installed packages matching a pattern: dpkg -l 'nginx*'",
|
|
94
|
+
"Find which package owns a specific file: dpkg -S /usr/bin/python3",
|
|
95
|
+
"Show contents of a .deb file without installing: dpkg -c package.deb",
|
|
96
|
+
"Reconfigure a package after installation: dpkg-reconfigure tzdata",
|
|
97
|
+
],
|
|
98
|
+
"gotchas": [
|
|
99
|
+
"dpkg does not resolve dependencies automatically -- if a .deb requires missing packages, dpkg -i will fail and you must run apt-get install -f to fix the broken state",
|
|
100
|
+
"dpkg --purge removes configuration files too, while dpkg -r leaves them behind -- use --purge only when you want a clean removal",
|
|
101
|
+
"dpkg -l output truncates long package names by default -- pipe through 'dpkg -l | cat' or set COLUMNS=200 for full output",
|
|
102
|
+
],
|
|
103
|
+
"related": ["apt", "apt-get", "apt-cache"],
|
|
104
|
+
"difficulty": "intermediate",
|
|
105
|
+
"extra_flags": {
|
|
106
|
+
"-i": "Install a .deb package file",
|
|
107
|
+
"-r": "Remove an installed package (leave config files)",
|
|
108
|
+
"-P": "Purge: remove package and configuration files",
|
|
109
|
+
"-l": "List packages matching a pattern",
|
|
110
|
+
"-L": "List files installed by a package",
|
|
111
|
+
"-S": "Search for a package that owns the given file path",
|
|
112
|
+
"-s": "Display status and details of an installed package",
|
|
113
|
+
"-c": "List contents of a .deb archive file",
|
|
114
|
+
"--configure": "Configure an unpacked but not yet configured package",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
"snap": {
|
|
119
|
+
"man_url": "https://snapcraft.io/docs",
|
|
120
|
+
"use_cases": [
|
|
121
|
+
"Install an application as a snap: snap install vlc",
|
|
122
|
+
"List all installed snaps and their versions: snap list",
|
|
123
|
+
"Update all installed snaps to latest versions: snap refresh",
|
|
124
|
+
"Remove a snap application: snap remove vlc",
|
|
125
|
+
"Revert a snap to its previous version after a bad update: snap revert vlc",
|
|
126
|
+
],
|
|
127
|
+
"gotchas": [
|
|
128
|
+
"Snaps auto-update in the background, which can restart running applications unexpectedly -- use snap refresh --hold to pause updates",
|
|
129
|
+
"Snaps run in a sandboxed environment and may not have access to all system files -- use snap connect to grant additional permissions",
|
|
130
|
+
"Snap applications may start slower than native packages because they mount a squashfs image on each launch",
|
|
131
|
+
"The snap store is Canonical-controlled; not all snaps are open-source even if the snap format is",
|
|
132
|
+
],
|
|
133
|
+
"related": ["flatpak", "apt", "apt-get"],
|
|
134
|
+
"difficulty": "beginner",
|
|
135
|
+
"extra_flags": {
|
|
136
|
+
"info": "Show detailed information about a snap",
|
|
137
|
+
"find": "Search for snaps in the store",
|
|
138
|
+
"--classic": "Install with classic confinement (full system access)",
|
|
139
|
+
"--channel": "Install from a specific channel (stable, beta, edge)",
|
|
140
|
+
"connections": "Show interface connections for a snap",
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
"flatpak": {
|
|
145
|
+
"man_url": "https://www.man7.org/linux/man-pages/man1/flatpak.1.html",
|
|
146
|
+
"use_cases": [
|
|
147
|
+
"Install an application from Flathub: flatpak install flathub org.gimp.GIMP",
|
|
148
|
+
"Run an installed Flatpak application: flatpak run org.gimp.GIMP",
|
|
149
|
+
"Update all installed Flatpak applications: flatpak update",
|
|
150
|
+
"List installed applications and runtimes: flatpak list",
|
|
151
|
+
"Add the Flathub repository: flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo",
|
|
152
|
+
],
|
|
153
|
+
"gotchas": [
|
|
154
|
+
"Flatpak uses application IDs (reverse DNS like org.gimp.GIMP) not simple names -- you must know or search for the full ID",
|
|
155
|
+
"Flatpak apps are sandboxed and may not see your home directory or USB drives -- use Flatseal or flatpak override to manage permissions",
|
|
156
|
+
"Runtimes take significant disk space since each app bundles its own dependencies -- use flatpak uninstall --unused to remove orphaned runtimes",
|
|
157
|
+
],
|
|
158
|
+
"related": ["snap", "apt", "apt-get"],
|
|
159
|
+
"difficulty": "beginner",
|
|
160
|
+
"extra_flags": {
|
|
161
|
+
"search": "Search for available applications by keyword",
|
|
162
|
+
"uninstall": "Remove an installed application",
|
|
163
|
+
"override": "Override application permissions",
|
|
164
|
+
"--user": "Perform the operation for the current user only",
|
|
165
|
+
"--system": "Perform the operation system-wide",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
"yum": {
|
|
170
|
+
"man_url": "https://man7.org/linux/man-pages/man8/yum.8.html",
|
|
171
|
+
"use_cases": [
|
|
172
|
+
"Install a package with automatic dependency resolution: yum install httpd",
|
|
173
|
+
"Update all packages on the system: yum update -y",
|
|
174
|
+
"Search for a package by keyword: yum search web server",
|
|
175
|
+
"List available updates: yum check-update",
|
|
176
|
+
"View transaction history to audit changes: yum history",
|
|
177
|
+
],
|
|
178
|
+
"gotchas": [
|
|
179
|
+
"yum is replaced by dnf on Fedora 22+ and RHEL 8+ -- on newer systems 'yum' is often just a symlink to dnf",
|
|
180
|
+
"yum localinstall is deprecated; use yum install ./package.rpm instead to install local RPM files",
|
|
181
|
+
"yum update will update the kernel too -- use yum update --exclude=kernel* to skip kernel updates if needed",
|
|
182
|
+
],
|
|
183
|
+
"related": ["dnf", "rpm", "zypper"],
|
|
184
|
+
"difficulty": "beginner",
|
|
185
|
+
"extra_flags": {
|
|
186
|
+
"info": "Show detailed information about a package",
|
|
187
|
+
"provides": "Find which package provides a given file or capability",
|
|
188
|
+
"groupinstall": "Install a group of related packages",
|
|
189
|
+
"clean all": "Remove all cached package data",
|
|
190
|
+
"history": "View or undo past transactions",
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
"dnf": {
|
|
195
|
+
"man_url": "https://man7.org/linux/man-pages/man8/dnf.8.html",
|
|
196
|
+
"use_cases": [
|
|
197
|
+
"Install a package on Fedora or RHEL: dnf install nginx",
|
|
198
|
+
"Upgrade all packages on the system: dnf upgrade --refresh",
|
|
199
|
+
"Search for packages by keyword: dnf search text editor",
|
|
200
|
+
"List all installed packages: dnf list installed",
|
|
201
|
+
"Remove unneeded dependency packages: dnf autoremove",
|
|
202
|
+
],
|
|
203
|
+
"gotchas": [
|
|
204
|
+
"dnf upgrade is the modern replacement for yum update -- dnf update exists as an alias but upgrade is the canonical command",
|
|
205
|
+
"dnf module commands manage modular content streams (e.g., different Node.js versions) -- forgetting to enable a module stream before installing can give you an unexpected version",
|
|
206
|
+
"dnf history undo can roll back a transaction but may fail if other packages now depend on what was installed",
|
|
207
|
+
],
|
|
208
|
+
"related": ["yum", "rpm", "zypper"],
|
|
209
|
+
"difficulty": "beginner",
|
|
210
|
+
"extra_flags": {
|
|
211
|
+
"provides": "Find which package provides a file or capability",
|
|
212
|
+
"repolist": "List enabled repositories",
|
|
213
|
+
"module": "Manage modular content streams",
|
|
214
|
+
"group": "Manage package groups",
|
|
215
|
+
"--refresh": "Force refresh of repository metadata before operating",
|
|
216
|
+
"--best": "Try to install the best available version of packages",
|
|
217
|
+
"downgrade": "Downgrade a package to an earlier available version",
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
"rpm": {
|
|
222
|
+
"man_url": "https://man7.org/linux/man-pages/man8/rpm.8.html",
|
|
223
|
+
"use_cases": [
|
|
224
|
+
"Install an RPM package file: rpm -ivh package.rpm",
|
|
225
|
+
"Query all installed packages: rpm -qa",
|
|
226
|
+
"Find which package owns a file: rpm -qf /usr/bin/vim",
|
|
227
|
+
"List all files in an installed package: rpm -ql nginx",
|
|
228
|
+
"Verify integrity of installed package files: rpm -V nginx",
|
|
229
|
+
],
|
|
230
|
+
"gotchas": [
|
|
231
|
+
"rpm does not resolve dependencies -- installing with rpm -i will fail if dependencies are missing; use dnf or yum for dependency resolution",
|
|
232
|
+
"rpm -U (upgrade) removes the old version before installing the new one -- for the kernel, use rpm -i instead so you keep the old kernel as a fallback",
|
|
233
|
+
"rpm -e (erase) will refuse to remove a package if others depend on it -- use --nodeps to force removal, but this can break the system",
|
|
234
|
+
],
|
|
235
|
+
"related": ["dnf", "yum", "zypper", "rpmbuild"],
|
|
236
|
+
"difficulty": "intermediate",
|
|
237
|
+
"extra_flags": {
|
|
238
|
+
"-i": "Install a package",
|
|
239
|
+
"-U": "Upgrade (or install if not present)",
|
|
240
|
+
"-e": "Erase (remove) a package",
|
|
241
|
+
"-q": "Query mode",
|
|
242
|
+
"-qa": "Query all installed packages",
|
|
243
|
+
"-qf": "Query which package owns a file",
|
|
244
|
+
"-ql": "Query list of files in a package",
|
|
245
|
+
"-V": "Verify installed package against RPM database",
|
|
246
|
+
"-K": "Check package signature and integrity",
|
|
247
|
+
"--import": "Import a GPG public key for package verification",
|
|
248
|
+
"-ivh": "Install with verbose output and progress hash marks",
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
"zypper": {
|
|
253
|
+
"man_url": "https://en.opensuse.org/SDB:Zypper_manual",
|
|
254
|
+
"use_cases": [
|
|
255
|
+
"Install a package on openSUSE: zypper install nginx",
|
|
256
|
+
"Refresh all repositories: zypper refresh",
|
|
257
|
+
"Update all installed packages: zypper update",
|
|
258
|
+
"Search for packages by pattern: zypper search pattern",
|
|
259
|
+
"Perform a full distribution upgrade: zypper dist-upgrade",
|
|
260
|
+
],
|
|
261
|
+
"gotchas": [
|
|
262
|
+
"zypper dist-upgrade (dup) can change vendors and remove packages -- always review the proposed changes and use --dry-run first",
|
|
263
|
+
"zypper locks can prevent packages from being updated -- use zypper locks list to see if any are blocking upgrades",
|
|
264
|
+
"Unlike apt, zypper refresh must be run manually to update repository metadata before searching or installing",
|
|
265
|
+
],
|
|
266
|
+
"related": ["rpm", "dnf", "yum"],
|
|
267
|
+
"difficulty": "intermediate",
|
|
268
|
+
"extra_flags": {
|
|
269
|
+
"lr": "List all configured repositories",
|
|
270
|
+
"ar": "Add a new repository",
|
|
271
|
+
"rr": "Remove a repository",
|
|
272
|
+
"patch": "Install available patches",
|
|
273
|
+
"se": "Shorthand for search",
|
|
274
|
+
"in": "Shorthand for install",
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
"pacman": {
|
|
279
|
+
"man_url": "https://man.archlinux.org/man/pacman.8",
|
|
280
|
+
"use_cases": [
|
|
281
|
+
"Synchronize package databases and upgrade system: pacman -Syu",
|
|
282
|
+
"Install a package from the repositories: pacman -S nginx",
|
|
283
|
+
"Search for a package by name: pacman -Ss web server",
|
|
284
|
+
"Remove a package and its orphaned dependencies: pacman -Rns package-name",
|
|
285
|
+
"Query which package owns a file: pacman -Qo /usr/bin/vim",
|
|
286
|
+
],
|
|
287
|
+
"gotchas": [
|
|
288
|
+
"Arch is a rolling release -- always run pacman -Syu (full sync) rather than pacman -Sy package, which can cause partial upgrades and break the system",
|
|
289
|
+
"pacman -R will not remove dependencies that were pulled in; use -Rns to also remove orphaned dependencies and config backups",
|
|
290
|
+
"Package signing is enforced by default; if you get signature errors, update the keyring first with pacman -S archlinux-keyring",
|
|
291
|
+
],
|
|
292
|
+
"related": ["yay", "paru", "makepkg"],
|
|
293
|
+
"difficulty": "intermediate",
|
|
294
|
+
"extra_flags": {
|
|
295
|
+
"-S": "Synchronize: install or upgrade packages from repositories",
|
|
296
|
+
"-R": "Remove an installed package",
|
|
297
|
+
"-Q": "Query the local installed package database",
|
|
298
|
+
"-Syu": "Full system upgrade (sync databases + upgrade)",
|
|
299
|
+
"-Ss": "Search remote repositories for a package",
|
|
300
|
+
"-Qs": "Search locally installed packages",
|
|
301
|
+
"-Qi": "Show detailed info about an installed package",
|
|
302
|
+
"-Qo": "Query which package owns a given file",
|
|
303
|
+
"-Sc": "Clean old packages from the cache",
|
|
304
|
+
"-U": "Install a local package file (.pkg.tar.zst)",
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
"yay": {
|
|
309
|
+
"man_url": "https://github.com/Jguer/yay",
|
|
310
|
+
"use_cases": [
|
|
311
|
+
"Install a package from AUR or official repos: yay -S package-name",
|
|
312
|
+
"Full system upgrade including AUR packages: yay -Syu",
|
|
313
|
+
"Search for packages across repos and AUR: yay search-term",
|
|
314
|
+
"Upgrade only AUR packages: yay -Sua",
|
|
315
|
+
"Remove a package: yay -R package-name",
|
|
316
|
+
],
|
|
317
|
+
"gotchas": [
|
|
318
|
+
"AUR packages are user-submitted and not officially reviewed -- always inspect the PKGBUILD before installing to avoid malicious code",
|
|
319
|
+
"yay builds AUR packages from source, which can take significant time and disk space for large projects",
|
|
320
|
+
"Running yay without arguments triggers a full -Syu upgrade, which may not be intended",
|
|
321
|
+
],
|
|
322
|
+
"related": ["pacman", "paru", "makepkg"],
|
|
323
|
+
"difficulty": "intermediate",
|
|
324
|
+
"extra_flags": {
|
|
325
|
+
"--gendb": "Generate a development package database for devel updates",
|
|
326
|
+
"--devel": "Check development packages for updates using git",
|
|
327
|
+
"--cleanafter": "Remove build files after installation",
|
|
328
|
+
"--editmenu": "Show a menu to edit PKGBUILDs before building",
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
"paru": {
|
|
333
|
+
"man_url": "https://github.com/Morganamilo/paru",
|
|
334
|
+
"use_cases": [
|
|
335
|
+
"Install a package from AUR or official repos: paru -S package-name",
|
|
336
|
+
"Full system upgrade including AUR packages: paru (defaults to -Syu)",
|
|
337
|
+
"Search for packages interactively: paru search-term",
|
|
338
|
+
"View and edit PKGBUILD before installing: paru -S --review package-name",
|
|
339
|
+
"Clean unneeded build dependencies: paru -c",
|
|
340
|
+
],
|
|
341
|
+
"gotchas": [
|
|
342
|
+
"paru opens the PKGBUILD for review by default before building, which is safer but slower -- set SkipReview in paru.conf to disable",
|
|
343
|
+
"Like yay, running paru without arguments performs a full system upgrade (-Syu)",
|
|
344
|
+
"paru is written in Rust and must be built from source via makepkg since it is an AUR package itself",
|
|
345
|
+
],
|
|
346
|
+
"related": ["pacman", "yay", "makepkg"],
|
|
347
|
+
"difficulty": "intermediate",
|
|
348
|
+
"extra_flags": {
|
|
349
|
+
"--review": "Review PKGBUILD and related files before building",
|
|
350
|
+
"--skipreview": "Skip PKGBUILD review",
|
|
351
|
+
"--devel": "Update VCS (git/svn) packages",
|
|
352
|
+
"--removemake": "Remove makedepends after installation",
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
# =========================================================================
|
|
357
|
+
# PACKAGE MANAGEMENT -- macOS / BSD
|
|
358
|
+
# =========================================================================
|
|
359
|
+
|
|
360
|
+
"brew": {
|
|
361
|
+
"man_url": "https://docs.brew.sh/Manpage",
|
|
362
|
+
"use_cases": [
|
|
363
|
+
"Install a command-line tool: brew install wget",
|
|
364
|
+
"Install a macOS GUI application: brew install --cask firefox",
|
|
365
|
+
"Update Homebrew and upgrade all packages: brew update && brew upgrade",
|
|
366
|
+
"Search for available packages: brew search keyword",
|
|
367
|
+
"List installed packages and check for issues: brew list && brew doctor",
|
|
368
|
+
"Pin a formula to prevent it from being upgraded: brew pin postgresql",
|
|
369
|
+
],
|
|
370
|
+
"gotchas": [
|
|
371
|
+
"brew update refreshes the formula index; brew upgrade actually installs newer versions -- mixing them up leads to confusion",
|
|
372
|
+
"Homebrew installs into /opt/homebrew on Apple Silicon and /usr/local on Intel Macs -- scripts referencing hardcoded paths may break across architectures",
|
|
373
|
+
"brew doctor reports potential issues and should be run when things break -- it catches common problems like outdated Xcode CLT",
|
|
374
|
+
"Cask apps (--cask) are macOS .app bundles, not CLI tools -- they go to /Applications and may require manual updates",
|
|
375
|
+
],
|
|
376
|
+
"related": ["port", "apt", "dnf"],
|
|
377
|
+
"difficulty": "beginner",
|
|
378
|
+
"extra_flags": {
|
|
379
|
+
"install": "Install a formula or cask",
|
|
380
|
+
"uninstall": "Remove an installed formula or cask",
|
|
381
|
+
"upgrade": "Upgrade outdated formulae and casks",
|
|
382
|
+
"update": "Fetch the newest version of Homebrew and all formulae",
|
|
383
|
+
"search": "Search for formulae and casks",
|
|
384
|
+
"info": "Display information about a formula or cask",
|
|
385
|
+
"doctor": "Check your system for potential problems",
|
|
386
|
+
"list": "List all installed formulae and casks",
|
|
387
|
+
"pin": "Pin a formula to prevent upgrades",
|
|
388
|
+
"unpin": "Unpin a formula to allow upgrades",
|
|
389
|
+
"cleanup": "Remove old versions of installed formulae",
|
|
390
|
+
"tap": "Add a third-party repository of formulae",
|
|
391
|
+
"services": "Manage background services with macOS launchd",
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
"port": {
|
|
396
|
+
"man_url": "https://man.macports.org/port.1.html",
|
|
397
|
+
"use_cases": [
|
|
398
|
+
"Install a package on macOS via MacPorts: sudo port install wget",
|
|
399
|
+
"Update the port tree and upgrade installed packages: sudo port selfupdate && sudo port upgrade outdated",
|
|
400
|
+
"Search for available ports: port search keyword",
|
|
401
|
+
"List installed ports: port installed",
|
|
402
|
+
"Remove inactive (old) versions of ports: sudo port uninstall inactive",
|
|
403
|
+
],
|
|
404
|
+
"gotchas": [
|
|
405
|
+
"MacPorts installs everything under /opt/local, which means you need to add /opt/local/bin to PATH to find installed commands",
|
|
406
|
+
"MacPorts compiles from source by default, which can be slow -- Homebrew uses prebuilt bottles and is often faster for common packages",
|
|
407
|
+
"Mixing MacPorts and Homebrew on the same system can cause path conflicts and library version mismatches",
|
|
408
|
+
],
|
|
409
|
+
"related": ["brew", "apt", "dpkg"],
|
|
410
|
+
"difficulty": "intermediate",
|
|
411
|
+
"extra_flags": {
|
|
412
|
+
"selfupdate": "Update MacPorts itself and the port tree",
|
|
413
|
+
"upgrade": "Upgrade installed ports to latest versions",
|
|
414
|
+
"outdated": "List ports that have available upgrades",
|
|
415
|
+
"contents": "List files installed by a port",
|
|
416
|
+
"variants": "Show available build variants for a port",
|
|
417
|
+
"deps": "Show dependencies of a port",
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
"pkg": {
|
|
422
|
+
"man_url": "https://man.freebsd.org/cgi/man.cgi?query=pkg&sektion=8",
|
|
423
|
+
"use_cases": [
|
|
424
|
+
"Install a package on FreeBSD: pkg install nginx",
|
|
425
|
+
"Update the package repository catalog: pkg update",
|
|
426
|
+
"Upgrade all installed packages: pkg upgrade",
|
|
427
|
+
"Search for packages by name: pkg search keyword",
|
|
428
|
+
"Remove a package and its unused dependencies: pkg delete -a package-name && pkg autoremove",
|
|
429
|
+
],
|
|
430
|
+
"gotchas": [
|
|
431
|
+
"On a fresh FreeBSD install, pkg must be bootstrapped on first run -- it will prompt to install itself",
|
|
432
|
+
"pkg lock can prevent accidental upgrades of critical packages but can also block security updates if forgotten",
|
|
433
|
+
],
|
|
434
|
+
"related": ["apt", "dnf", "pacman"],
|
|
435
|
+
"difficulty": "intermediate",
|
|
436
|
+
"extra_flags": {
|
|
437
|
+
"info": "Display information about an installed package",
|
|
438
|
+
"audit": "Check installed packages for known vulnerabilities",
|
|
439
|
+
"autoremove": "Remove automatically installed orphan packages",
|
|
440
|
+
"lock": "Lock a package to prevent upgrades",
|
|
441
|
+
"which": "Find which package installed a given file",
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
|
|
445
|
+
"apk": {
|
|
446
|
+
"man_url": "https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper",
|
|
447
|
+
"use_cases": [
|
|
448
|
+
"Install a package in an Alpine Docker container: apk add --no-cache curl",
|
|
449
|
+
"Update package index and upgrade all packages: apk update && apk upgrade",
|
|
450
|
+
"Search for available packages: apk search nginx",
|
|
451
|
+
"Show info about a package: apk info -a nginx",
|
|
452
|
+
"Remove a package: apk del nginx",
|
|
453
|
+
],
|
|
454
|
+
"gotchas": [
|
|
455
|
+
"Always use --no-cache in Dockerfiles to avoid storing the package index in the image layer, keeping images small",
|
|
456
|
+
"Alpine uses musl libc instead of glibc, so some precompiled binaries from other distros will not work -- you may need to compile from source",
|
|
457
|
+
"apk has no separate update+install step like apt; apk add always fetches the latest index unless you explicitly separate it",
|
|
458
|
+
],
|
|
459
|
+
"related": ["apt", "dnf", "pacman"],
|
|
460
|
+
"difficulty": "beginner",
|
|
461
|
+
"extra_flags": {
|
|
462
|
+
"--no-cache": "Do not use or update the local package cache",
|
|
463
|
+
"-s": "Simulate the operation without making changes",
|
|
464
|
+
"--virtual": "Create a virtual package for easy grouped removal",
|
|
465
|
+
"-U": "Update repository indexes before operating",
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
# =========================================================================
|
|
470
|
+
# PACKAGE MANAGEMENT -- JavaScript / Node.js
|
|
471
|
+
# =========================================================================
|
|
472
|
+
|
|
473
|
+
"npm": {
|
|
474
|
+
"man_url": "https://docs.npmjs.com/cli",
|
|
475
|
+
"use_cases": [
|
|
476
|
+
"Initialize a new project with npm init -y and install dependencies with npm install express",
|
|
477
|
+
"Run project scripts defined in package.json like npm test or npm run build",
|
|
478
|
+
"Audit dependencies for known vulnerabilities with npm audit and fix them with npm audit fix",
|
|
479
|
+
"Publish a package to the npm registry: npm publish",
|
|
480
|
+
"View outdated dependencies: npm outdated",
|
|
481
|
+
],
|
|
482
|
+
"gotchas": [
|
|
483
|
+
"npm install without --save-dev puts everything in dependencies -- use --save-dev for test/build tools to keep production installs lean",
|
|
484
|
+
"Running npm install without a lockfile or with different npm versions can produce different dependency trees -- always commit package-lock.json",
|
|
485
|
+
"Global installs (npm install -g) can cause permission errors on Linux/macOS if Node was installed via system package manager -- use nvm or configure npm prefix",
|
|
486
|
+
"npm run silently swallows exit codes by default in some cases -- use npm run --if-present for optional scripts",
|
|
487
|
+
],
|
|
488
|
+
"related": ["npx", "yarn", "pnpm", "bun"],
|
|
489
|
+
"difficulty": "beginner",
|
|
490
|
+
"extra_flags": {
|
|
491
|
+
"ci": "Clean install from lockfile only, ideal for CI/CD pipelines",
|
|
492
|
+
"outdated": "Check for outdated packages",
|
|
493
|
+
"audit": "Run a security audit of installed dependencies",
|
|
494
|
+
"link": "Symlink a local package for development testing",
|
|
495
|
+
"pack": "Create a tarball of the package without publishing",
|
|
496
|
+
"exec": "Run a command from a local or remote npm package",
|
|
497
|
+
"--legacy-peer-deps": "Ignore peerDependency conflicts during install",
|
|
498
|
+
"--omit=dev": "Skip devDependencies during install (replaces --production)",
|
|
499
|
+
"cache clean --force": "Clear the npm cache when troubleshooting installs",
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
"npx": {
|
|
504
|
+
"man_url": "https://docs.npmjs.com/cli/commands/npx",
|
|
505
|
+
"use_cases": [
|
|
506
|
+
"Run a package without installing it globally: npx create-react-app my-app",
|
|
507
|
+
"Execute a specific version of a tool: npx node@18 --version",
|
|
508
|
+
"Run a locally installed binary: npx jest --coverage",
|
|
509
|
+
"Initialize a project with a scaffolding tool: npx degit user/repo my-project",
|
|
510
|
+
],
|
|
511
|
+
"gotchas": [
|
|
512
|
+
"npx downloads packages to a temporary cache and executes them -- this means it may run arbitrary code from npm; always verify what you are running",
|
|
513
|
+
"If the package is not installed locally, npx prompts for confirmation (use -y to auto-confirm or --no to reject)",
|
|
514
|
+
"npx resolves commands from local node_modules/.bin first, then global, then downloads -- behavior can be surprising if a local version differs from what you expect",
|
|
515
|
+
],
|
|
516
|
+
"related": ["npm", "yarn", "pnpm", "bun"],
|
|
517
|
+
"difficulty": "beginner",
|
|
518
|
+
"extra_flags": {
|
|
519
|
+
"-p": "Specify additional packages to install alongside the command",
|
|
520
|
+
"--no": "Refuse to install any packages not already present",
|
|
521
|
+
"-c": "Execute a string as a shell command with the package available",
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
"yarn": {
|
|
526
|
+
"man_url": "https://yarnpkg.com/getting-started",
|
|
527
|
+
"use_cases": [
|
|
528
|
+
"Install all project dependencies: yarn install",
|
|
529
|
+
"Add a new package to the project: yarn add express",
|
|
530
|
+
"Add a development dependency: yarn add --dev typescript",
|
|
531
|
+
"Run a script defined in package.json: yarn run build",
|
|
532
|
+
"Upgrade all dependencies to latest: yarn upgrade-interactive",
|
|
533
|
+
],
|
|
534
|
+
"gotchas": [
|
|
535
|
+
"Yarn Classic (v1) and Yarn Berry (v2+) have significantly different behaviors -- Berry uses Plug'n'Play by default which eliminates node_modules and may break tools expecting it",
|
|
536
|
+
"yarn install --frozen-lockfile should be used in CI to fail fast if the lockfile is out of date rather than silently updating it",
|
|
537
|
+
"Mixing yarn and npm in the same project creates conflicting lockfiles (yarn.lock vs package-lock.json) -- pick one and stick with it",
|
|
538
|
+
"Yarn workspaces require proper configuration in package.json; forgetting to declare a workspace means its dependencies are not hoisted",
|
|
539
|
+
],
|
|
540
|
+
"related": ["npm", "pnpm", "bun", "npx"],
|
|
541
|
+
"difficulty": "beginner",
|
|
542
|
+
"extra_flags": {
|
|
543
|
+
"why": "Show why a package is installed (dependency chain)",
|
|
544
|
+
"workspace": "Run a command in a specific workspace",
|
|
545
|
+
"dlx": "Download and execute a package (like npx) in Yarn Berry",
|
|
546
|
+
"dedupe": "Deduplicate dependencies in the lockfile",
|
|
547
|
+
"info": "Show information about a package",
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
|
|
551
|
+
"pnpm": {
|
|
552
|
+
"man_url": "https://pnpm.io/cli/add",
|
|
553
|
+
"use_cases": [
|
|
554
|
+
"Install all project dependencies: pnpm install",
|
|
555
|
+
"Add a new dependency: pnpm add express",
|
|
556
|
+
"Add a development dependency: pnpm add -D typescript",
|
|
557
|
+
"Run a script from package.json: pnpm run build",
|
|
558
|
+
"Install dependencies in a monorepo workspace: pnpm install --filter @my-org/package-name",
|
|
559
|
+
],
|
|
560
|
+
"gotchas": [
|
|
561
|
+
"pnpm uses a content-addressable store and hard links, so node_modules has a different structure than npm -- some tools that walk node_modules directly may not work",
|
|
562
|
+
"pnpm is strict about peer dependencies by default, which catches real issues but can be annoying when libraries have sloppy peer dependency declarations -- use --shamefully-hoist as a last resort",
|
|
563
|
+
"pnpm does not hoist packages to the root node_modules by default, so accessing undeclared dependencies fails immediately -- this is by design to enforce correctness",
|
|
564
|
+
],
|
|
565
|
+
"related": ["npm", "yarn", "bun", "npx"],
|
|
566
|
+
"difficulty": "intermediate",
|
|
567
|
+
"extra_flags": {
|
|
568
|
+
"--filter": "Run commands for specific packages in a monorepo",
|
|
569
|
+
"--shamefully-hoist": "Hoist all packages to root (compatibility escape hatch)",
|
|
570
|
+
"--frozen-lockfile": "Fail if lockfile needs updating (CI mode)",
|
|
571
|
+
"store prune": "Remove unused packages from the content-addressable store",
|
|
572
|
+
"dlx": "Download and execute a package (like npx)",
|
|
573
|
+
"why": "Show why a package is installed",
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
|
|
577
|
+
"bun": {
|
|
578
|
+
"man_url": "https://bun.sh/docs",
|
|
579
|
+
"use_cases": [
|
|
580
|
+
"Install all project dependencies (fast): bun install",
|
|
581
|
+
"Add a dependency: bun add express",
|
|
582
|
+
"Run a TypeScript file directly without compilation: bun run index.ts",
|
|
583
|
+
"Run tests with the built-in test runner: bun test",
|
|
584
|
+
"Initialize a new project: bun init",
|
|
585
|
+
],
|
|
586
|
+
"gotchas": [
|
|
587
|
+
"Bun is not 100% Node.js compatible -- some Node.js APIs and native modules may behave differently or be missing; check compatibility before migrating production code",
|
|
588
|
+
"Bun uses its own bun.lockb binary lockfile which is not interchangeable with package-lock.json or yarn.lock",
|
|
589
|
+
"bun run interprets .ts files natively, so TypeScript errors may appear that tsc would catch differently -- Bun transpiles rather than type-checks",
|
|
590
|
+
],
|
|
591
|
+
"related": ["npm", "yarn", "pnpm", "npx"],
|
|
592
|
+
"difficulty": "beginner",
|
|
593
|
+
"extra_flags": {
|
|
594
|
+
"add": "Add a dependency to the project",
|
|
595
|
+
"remove": "Remove a dependency from the project",
|
|
596
|
+
"update": "Update dependencies to the latest compatible versions",
|
|
597
|
+
"link": "Link a local package for development",
|
|
598
|
+
"pm": "Package manager subcommands (cache, ls, hash)",
|
|
599
|
+
"x": "Execute a package (like npx)",
|
|
600
|
+
"--hot": "Enable hot reloading for development server",
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
# =========================================================================
|
|
605
|
+
# PACKAGE MANAGEMENT -- Python
|
|
606
|
+
# =========================================================================
|
|
607
|
+
|
|
608
|
+
"pip": {
|
|
609
|
+
"man_url": "https://pip.pypa.io/en/stable/",
|
|
610
|
+
"use_cases": [
|
|
611
|
+
"Install a package with pip install requests and pin versions with pip install requests==2.31.0",
|
|
612
|
+
"Export current environment dependencies with pip freeze > requirements.txt for reproducibility",
|
|
613
|
+
"Install all project dependencies from a requirements file with pip install -r requirements.txt",
|
|
614
|
+
"Install a package in editable mode for development: pip install -e .",
|
|
615
|
+
"Check for outdated packages: pip list --outdated",
|
|
616
|
+
],
|
|
617
|
+
"gotchas": [
|
|
618
|
+
"Installing without a virtual environment modifies system Python packages and can break OS tools -- always use python -m venv or conda first",
|
|
619
|
+
"pip install upgrades are not automatic -- use pip install --upgrade package to get the latest version; pip install alone skips already-installed packages",
|
|
620
|
+
"pip does not have a true dependency resolver lock file -- use pip-tools, poetry, or uv for reproducible builds",
|
|
621
|
+
"pip install --user is the fallback when you cannot use a virtual environment, but it puts packages in ~/.local which can cause version conflicts",
|
|
622
|
+
],
|
|
623
|
+
"related": ["pip3", "pipx", "conda", "poetry", "uv"],
|
|
624
|
+
"difficulty": "beginner",
|
|
625
|
+
"extra_flags": {
|
|
626
|
+
"--user": "Install to the user site-packages directory",
|
|
627
|
+
"--no-deps": "Do not install package dependencies",
|
|
628
|
+
"--pre": "Include pre-release and development versions",
|
|
629
|
+
"--index-url": "Use a custom package index URL",
|
|
630
|
+
"--trusted-host": "Trust a host for package downloads (skip SSL)",
|
|
631
|
+
"show": "Show information about installed packages",
|
|
632
|
+
"check": "Verify installed packages have compatible dependencies",
|
|
633
|
+
"download": "Download packages without installing",
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
|
|
637
|
+
"pip3": {
|
|
638
|
+
"man_url": "https://pip.pypa.io/en/stable/",
|
|
639
|
+
"use_cases": [
|
|
640
|
+
"Explicitly use Python 3 pip when both Python 2 and 3 are installed: pip3 install flask",
|
|
641
|
+
"Install packages in the user directory: pip3 install --user package-name",
|
|
642
|
+
"Upgrade pip itself: pip3 install --upgrade pip",
|
|
643
|
+
],
|
|
644
|
+
"gotchas": [
|
|
645
|
+
"On most modern systems, pip and pip3 are the same command since Python 2 is EOL -- but on older systems they may point to different Python versions",
|
|
646
|
+
"Use python3 -m pip instead of pip3 for clarity about which Python interpreter is being used, especially in scripts",
|
|
647
|
+
],
|
|
648
|
+
"related": ["pip", "pipx", "python3"],
|
|
649
|
+
"difficulty": "beginner",
|
|
650
|
+
"extra_flags": {},
|
|
651
|
+
},
|
|
652
|
+
|
|
653
|
+
"pipx": {
|
|
654
|
+
"man_url": "https://pipx.pypa.io/stable/",
|
|
655
|
+
"use_cases": [
|
|
656
|
+
"Install a Python CLI tool in its own isolated environment: pipx install black",
|
|
657
|
+
"Run a tool once without installing: pipx run cowsay hello",
|
|
658
|
+
"Upgrade an installed tool: pipx upgrade black",
|
|
659
|
+
"List all pipx-installed applications: pipx list",
|
|
660
|
+
"Inject an extra package into a tool's isolated environment: pipx inject black click",
|
|
661
|
+
],
|
|
662
|
+
"gotchas": [
|
|
663
|
+
"pipx is for end-user applications (CLI tools), not libraries -- if you need a library in your project, use pip inside a virtual environment instead",
|
|
664
|
+
"pipx creates one virtual environment per tool, so disk usage can add up with many tools installed",
|
|
665
|
+
"pipx uses the Python version it was installed with -- if you need a tool to use a specific Python, pass --python python3.12",
|
|
666
|
+
],
|
|
667
|
+
"related": ["pip", "pip3", "uv"],
|
|
668
|
+
"difficulty": "beginner",
|
|
669
|
+
"extra_flags": {
|
|
670
|
+
"ensurepath": "Add pipx binary directory to PATH if not already present",
|
|
671
|
+
"inject": "Add additional packages into an existing pipx application's environment",
|
|
672
|
+
"reinstall-all": "Reinstall all pipx-managed packages (useful after Python upgrade)",
|
|
673
|
+
"--python": "Specify which Python interpreter to use for the virtual environment",
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
|
|
677
|
+
"conda": {
|
|
678
|
+
"man_url": "https://docs.conda.io/projects/conda/en/stable/",
|
|
679
|
+
"use_cases": [
|
|
680
|
+
"Create a new environment with specific Python version: conda create -n myenv python=3.11",
|
|
681
|
+
"Activate an environment: conda activate myenv",
|
|
682
|
+
"Install a package: conda install numpy",
|
|
683
|
+
"Export an environment for reproducibility: conda env export > environment.yml",
|
|
684
|
+
"Recreate an environment from a file: conda env create -f environment.yml",
|
|
685
|
+
],
|
|
686
|
+
"gotchas": [
|
|
687
|
+
"Mixing pip and conda in the same environment can break dependency resolution -- install everything with conda first, then use pip only for packages not in conda channels",
|
|
688
|
+
"conda environments can be large (gigabytes) because conda installs compiled binaries for everything including the Python interpreter itself",
|
|
689
|
+
"The default channel may have older versions -- use conda-forge channel (conda install -c conda-forge package) for more up-to-date packages",
|
|
690
|
+
"conda activate does not work in shell scripts by default -- you must run 'eval \"$(conda shell.bash hook)\"' first or use conda run",
|
|
691
|
+
],
|
|
692
|
+
"related": ["pip", "poetry", "uv", "mamba"],
|
|
693
|
+
"difficulty": "intermediate",
|
|
694
|
+
"extra_flags": {
|
|
695
|
+
"create": "Create a new environment",
|
|
696
|
+
"activate": "Activate an environment",
|
|
697
|
+
"deactivate": "Deactivate the current environment",
|
|
698
|
+
"env list": "List all environments",
|
|
699
|
+
"env remove": "Delete an environment",
|
|
700
|
+
"clean": "Remove unused packages and caches",
|
|
701
|
+
"-c": "Specify a channel to search for packages",
|
|
702
|
+
"--override-channels": "Ignore default channels",
|
|
703
|
+
"config": "Manage conda configuration",
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
|
|
707
|
+
"poetry": {
|
|
708
|
+
"man_url": "https://python-poetry.org/docs/",
|
|
709
|
+
"use_cases": [
|
|
710
|
+
"Create a new Python project with pyproject.toml: poetry new my-project",
|
|
711
|
+
"Add a dependency: poetry add requests",
|
|
712
|
+
"Add a development dependency: poetry add --group dev pytest",
|
|
713
|
+
"Install all dependencies from the lock file: poetry install",
|
|
714
|
+
"Build and publish a package to PyPI: poetry build && poetry publish",
|
|
715
|
+
],
|
|
716
|
+
"gotchas": [
|
|
717
|
+
"Poetry manages its own virtual environments and may create them in unexpected locations -- use poetry env info to find the active environment path",
|
|
718
|
+
"poetry install recreates the virtual environment from poetry.lock, not pyproject.toml -- run poetry lock first if you edited pyproject.toml manually",
|
|
719
|
+
"Poetry does not interoperate well with conda environments -- use one or the other, not both",
|
|
720
|
+
"The poetry shell command spawns a new subshell rather than activating in-place like conda activate",
|
|
721
|
+
],
|
|
722
|
+
"related": ["pip", "pipx", "conda", "uv"],
|
|
723
|
+
"difficulty": "intermediate",
|
|
724
|
+
"extra_flags": {
|
|
725
|
+
"lock": "Generate the poetry.lock file without installing",
|
|
726
|
+
"show": "Show information about installed packages",
|
|
727
|
+
"run": "Run a command within the project's virtual environment",
|
|
728
|
+
"shell": "Spawn a shell within the project's virtual environment",
|
|
729
|
+
"env": "Manage the project's virtual environment",
|
|
730
|
+
"export": "Export the lock file to other formats (e.g., requirements.txt)",
|
|
731
|
+
"self update": "Update Poetry itself to the latest version",
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
|
|
735
|
+
"uv": {
|
|
736
|
+
"man_url": "https://docs.astral.sh/uv/",
|
|
737
|
+
"use_cases": [
|
|
738
|
+
"Create a virtual environment and install packages extremely fast: uv venv && uv pip install flask",
|
|
739
|
+
"Install packages from requirements.txt: uv pip install -r requirements.txt",
|
|
740
|
+
"Create a new Python project: uv init my-project",
|
|
741
|
+
"Run a Python script with automatic dependency resolution: uv run script.py",
|
|
742
|
+
"Install and manage Python versions: uv python install 3.12",
|
|
743
|
+
],
|
|
744
|
+
"gotchas": [
|
|
745
|
+
"uv is written in Rust and is 10-100x faster than pip, but it is a newer tool and may have edge cases with complex dependency trees",
|
|
746
|
+
"uv pip compile generates locked requirements from pyproject.toml, similar to pip-tools -- but the output format may differ slightly",
|
|
747
|
+
"uv automatically downloads Python versions if needed, which is convenient but may be unexpected in air-gapped environments",
|
|
748
|
+
],
|
|
749
|
+
"related": ["pip", "poetry", "pipx", "conda"],
|
|
750
|
+
"difficulty": "beginner",
|
|
751
|
+
"extra_flags": {
|
|
752
|
+
"venv": "Create a virtual environment",
|
|
753
|
+
"pip install": "Install packages (pip-compatible interface)",
|
|
754
|
+
"pip compile": "Compile requirements.in to requirements.txt",
|
|
755
|
+
"pip sync": "Sync environment to match requirements exactly",
|
|
756
|
+
"run": "Run a command or script in a project environment",
|
|
757
|
+
"add": "Add a dependency to the project",
|
|
758
|
+
"lock": "Generate a lockfile for the project",
|
|
759
|
+
"python": "Manage Python installations",
|
|
760
|
+
"tool": "Install and run Python CLI tools (like pipx)",
|
|
761
|
+
},
|
|
762
|
+
},
|
|
763
|
+
|
|
764
|
+
# =========================================================================
|
|
765
|
+
# PACKAGE MANAGEMENT -- Rust
|
|
766
|
+
# =========================================================================
|
|
767
|
+
|
|
768
|
+
"cargo": {
|
|
769
|
+
"man_url": "https://doc.rust-lang.org/cargo/",
|
|
770
|
+
"use_cases": [
|
|
771
|
+
"Create a new Rust project: cargo new my-project",
|
|
772
|
+
"Build the project in debug mode: cargo build",
|
|
773
|
+
"Build an optimized release binary: cargo build --release",
|
|
774
|
+
"Run tests: cargo test",
|
|
775
|
+
"Add a dependency from crates.io: cargo add serde",
|
|
776
|
+
"Check code without producing a binary (fast feedback): cargo check",
|
|
777
|
+
"Generate and open documentation: cargo doc --open",
|
|
778
|
+
],
|
|
779
|
+
"gotchas": [
|
|
780
|
+
"cargo build defaults to debug mode with no optimizations -- always use --release for production builds or benchmarks",
|
|
781
|
+
"Cargo.lock should be committed for binaries but not for libraries -- libraries let downstream consumers resolve versions",
|
|
782
|
+
"cargo update updates Cargo.lock to latest compatible versions but does not change Cargo.toml version constraints",
|
|
783
|
+
"Large dependency trees can make initial builds slow -- use cargo check instead of cargo build during development for faster feedback",
|
|
784
|
+
],
|
|
785
|
+
"related": ["rustup", "rustc"],
|
|
786
|
+
"difficulty": "intermediate",
|
|
787
|
+
"extra_flags": {
|
|
788
|
+
"new": "Create a new Cargo project (binary or library)",
|
|
789
|
+
"init": "Initialize Cargo in an existing directory",
|
|
790
|
+
"build": "Compile the current project",
|
|
791
|
+
"run": "Build and execute the binary",
|
|
792
|
+
"test": "Run the test suite",
|
|
793
|
+
"check": "Analyze code without producing binary output",
|
|
794
|
+
"clippy": "Run the Clippy linter for idiomatic Rust suggestions",
|
|
795
|
+
"fmt": "Format source code according to Rust style guidelines",
|
|
796
|
+
"doc": "Generate HTML documentation for the project",
|
|
797
|
+
"add": "Add a dependency to Cargo.toml",
|
|
798
|
+
"remove": "Remove a dependency from Cargo.toml",
|
|
799
|
+
"publish": "Publish the crate to crates.io",
|
|
800
|
+
"bench": "Run benchmarks",
|
|
801
|
+
"update": "Update Cargo.lock to latest compatible versions",
|
|
802
|
+
"--workspace": "Operate on all workspace members",
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
|
|
806
|
+
"rustup": {
|
|
807
|
+
"man_url": "https://rust-lang.github.io/rustup/",
|
|
808
|
+
"use_cases": [
|
|
809
|
+
"Install the stable Rust toolchain: rustup install stable",
|
|
810
|
+
"Switch to the nightly toolchain: rustup default nightly",
|
|
811
|
+
"Add a compilation target for cross-compiling: rustup target add wasm32-unknown-unknown",
|
|
812
|
+
"Update all installed toolchains: rustup update",
|
|
813
|
+
"Install a specific component like Clippy: rustup component add clippy",
|
|
814
|
+
],
|
|
815
|
+
"gotchas": [
|
|
816
|
+
"rustup override set nightly applies only to the current directory -- it does not change your global default",
|
|
817
|
+
"Nightly toolchains can break between days -- use rustup run nightly-2024-01-15 to pin a specific date",
|
|
818
|
+
"rustup self update updates rustup itself, while rustup update updates the Rust toolchains -- they are different operations",
|
|
819
|
+
],
|
|
820
|
+
"related": ["cargo", "rustc"],
|
|
821
|
+
"difficulty": "intermediate",
|
|
822
|
+
"extra_flags": {
|
|
823
|
+
"show": "Show the active and installed toolchains",
|
|
824
|
+
"default": "Set the default toolchain",
|
|
825
|
+
"override": "Set a directory-level toolchain override",
|
|
826
|
+
"target": "Manage compilation targets",
|
|
827
|
+
"component": "Manage toolchain components (clippy, rustfmt, etc.)",
|
|
828
|
+
"self update": "Update rustup itself",
|
|
829
|
+
"toolchain": "Manage installed toolchains",
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
|
|
833
|
+
# =========================================================================
|
|
834
|
+
# PACKAGE MANAGEMENT -- Ruby
|
|
835
|
+
# =========================================================================
|
|
836
|
+
|
|
837
|
+
"gem": {
|
|
838
|
+
"man_url": "https://guides.rubygems.org/rubygems-basics/",
|
|
839
|
+
"use_cases": [
|
|
840
|
+
"Install a Ruby gem: gem install rails",
|
|
841
|
+
"List installed gems: gem list",
|
|
842
|
+
"Update a specific gem: gem update nokogiri",
|
|
843
|
+
"Search for available gems: gem search json",
|
|
844
|
+
"Uninstall a gem: gem uninstall rails",
|
|
845
|
+
],
|
|
846
|
+
"gotchas": [
|
|
847
|
+
"Installing gems without a version manager (rbenv, rvm) can pollute the system Ruby and require sudo -- always use a Ruby version manager",
|
|
848
|
+
"gem install does not respect Gemfile constraints -- use bundle install for project-level dependency management",
|
|
849
|
+
"Some gems require native C extensions and need build tools (gcc, make) and system libraries to compile during installation",
|
|
850
|
+
],
|
|
851
|
+
"related": ["bundle", "ruby", "rbenv"],
|
|
852
|
+
"difficulty": "beginner",
|
|
853
|
+
"extra_flags": {
|
|
854
|
+
"-v": "Install a specific version of a gem",
|
|
855
|
+
"--no-document": "Skip generating documentation during install (faster)",
|
|
856
|
+
"environment": "Show RubyGems environment info (paths, config)",
|
|
857
|
+
"pristine": "Restore installed gems to their original state",
|
|
858
|
+
"cleanup": "Remove old versions of installed gems",
|
|
859
|
+
},
|
|
860
|
+
},
|
|
861
|
+
|
|
862
|
+
"bundle": {
|
|
863
|
+
"man_url": "https://bundler.io/man/bundle.1.html",
|
|
864
|
+
"use_cases": [
|
|
865
|
+
"Install all gems listed in the Gemfile: bundle install",
|
|
866
|
+
"Execute a command in the context of the bundle: bundle exec rails server",
|
|
867
|
+
"Update all gems to latest allowed versions: bundle update",
|
|
868
|
+
"Add a gem to the Gemfile and install it: bundle add nokogiri",
|
|
869
|
+
"Generate a Gemfile.lock for reproducible installs: bundle lock",
|
|
870
|
+
],
|
|
871
|
+
"gotchas": [
|
|
872
|
+
"Always use bundle exec to run project commands (e.g., bundle exec rake) to ensure the correct gem versions are loaded from Gemfile.lock",
|
|
873
|
+
"bundle install in deployment mode (--deployment) installs to vendor/bundle and is strict about the lockfile -- this is what CI/CD should use",
|
|
874
|
+
"Gemfile.lock must be committed to version control for applications (not for libraries) to ensure reproducible builds",
|
|
875
|
+
],
|
|
876
|
+
"related": ["gem", "ruby", "rbenv"],
|
|
877
|
+
"difficulty": "intermediate",
|
|
878
|
+
"extra_flags": {
|
|
879
|
+
"exec": "Run a command using the gems in the Gemfile",
|
|
880
|
+
"--deployment": "Install in deployment mode (strict lockfile, vendor directory)",
|
|
881
|
+
"--without": "Exclude gem groups from installation",
|
|
882
|
+
"--jobs": "Number of parallel gem installation jobs",
|
|
883
|
+
"--path": "Install gems to a specific directory",
|
|
884
|
+
"config": "Manage bundler configuration",
|
|
885
|
+
"outdated": "List gems with newer versions available",
|
|
886
|
+
},
|
|
887
|
+
},
|
|
888
|
+
|
|
889
|
+
# =========================================================================
|
|
890
|
+
# PACKAGE MANAGEMENT -- PHP
|
|
891
|
+
# =========================================================================
|
|
892
|
+
|
|
893
|
+
"composer": {
|
|
894
|
+
"man_url": "https://getcomposer.org/doc/",
|
|
895
|
+
"use_cases": [
|
|
896
|
+
"Install all dependencies from composer.json: composer install",
|
|
897
|
+
"Add a package: composer require monolog/monolog",
|
|
898
|
+
"Add a development dependency: composer require --dev phpunit/phpunit",
|
|
899
|
+
"Update all dependencies: composer update",
|
|
900
|
+
"Create a new project from a package: composer create-project laravel/laravel my-app",
|
|
901
|
+
],
|
|
902
|
+
"gotchas": [
|
|
903
|
+
"composer install installs from composer.lock (reproducible); composer update resolves new versions and rewrites the lock file -- do not use update in production deployments",
|
|
904
|
+
"Composer installs packages to vendor/ and generates an autoloader -- always include vendor/autoload.php in your code",
|
|
905
|
+
"Running Composer as root is discouraged and will display a warning -- it can lead to file permission issues",
|
|
906
|
+
],
|
|
907
|
+
"related": ["php", "pecl"],
|
|
908
|
+
"difficulty": "intermediate",
|
|
909
|
+
"extra_flags": {
|
|
910
|
+
"require": "Add a package to composer.json and install it",
|
|
911
|
+
"remove": "Remove a package from composer.json",
|
|
912
|
+
"dump-autoload": "Regenerate the autoloader files",
|
|
913
|
+
"show": "Show information about installed packages",
|
|
914
|
+
"outdated": "List packages with available updates",
|
|
915
|
+
"--no-dev": "Skip installing packages from require-dev",
|
|
916
|
+
"--optimize-autoloader": "Generate optimized autoloader for production",
|
|
917
|
+
"global": "Run commands in the global composer directory",
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
|
|
921
|
+
# =========================================================================
|
|
922
|
+
# PACKAGE MANAGEMENT -- Go
|
|
923
|
+
# =========================================================================
|
|
924
|
+
|
|
925
|
+
"go": {
|
|
926
|
+
"man_url": "https://pkg.go.dev/cmd/go",
|
|
927
|
+
"use_cases": [
|
|
928
|
+
"Initialize a new Go module: go mod init github.com/user/project",
|
|
929
|
+
"Build and run a Go program: go run main.go",
|
|
930
|
+
"Run all tests in the project: go test ./...",
|
|
931
|
+
"Add a dependency: go get github.com/gin-gonic/gin",
|
|
932
|
+
"Tidy up unused dependencies: go mod tidy",
|
|
933
|
+
"Build a static binary: CGO_ENABLED=0 go build -o myapp",
|
|
934
|
+
],
|
|
935
|
+
"gotchas": [
|
|
936
|
+
"go get now only updates go.mod -- use go install to install executables; go get no longer builds and installs binaries",
|
|
937
|
+
"go mod tidy can remove indirect dependencies that are actually needed -- always run tests after tidying",
|
|
938
|
+
"Go module proxy (GOPROXY) caches modules and can serve stale versions -- set GONOSUMCHECK or GOFLAGS=-mod=mod when debugging dependency issues",
|
|
939
|
+
],
|
|
940
|
+
"related": ["gofmt", "golint", "delve"],
|
|
941
|
+
"difficulty": "intermediate",
|
|
942
|
+
"extra_flags": {
|
|
943
|
+
"mod init": "Initialize a new Go module in the current directory",
|
|
944
|
+
"mod tidy": "Add missing and remove unused dependencies",
|
|
945
|
+
"install": "Compile and install a Go executable to GOPATH/bin",
|
|
946
|
+
"vet": "Report suspicious constructs in Go code",
|
|
947
|
+
"generate": "Run code generation directives in source files",
|
|
948
|
+
"work": "Manage Go workspaces for multi-module development",
|
|
949
|
+
"-ldflags": "Pass flags to the linker (e.g., to set version at build time)",
|
|
950
|
+
"-trimpath": "Remove filesystem paths from compiled binary",
|
|
951
|
+
},
|
|
952
|
+
},
|
|
953
|
+
|
|
954
|
+
# =========================================================================
|
|
955
|
+
# PACKAGE MANAGEMENT -- .NET
|
|
956
|
+
# =========================================================================
|
|
957
|
+
|
|
958
|
+
"nuget": {
|
|
959
|
+
"man_url": "https://learn.microsoft.com/en-us/nuget/reference/nuget-exe-cli-reference",
|
|
960
|
+
"use_cases": [
|
|
961
|
+
"Restore packages for a .NET project: nuget restore solution.sln",
|
|
962
|
+
"Install a package to a project: nuget install Newtonsoft.Json",
|
|
963
|
+
"Pack a project into a .nupkg file: nuget pack MyProject.nuspec",
|
|
964
|
+
"Push a package to the NuGet gallery: nuget push package.nupkg -Source nuget.org",
|
|
965
|
+
"List package sources: nuget sources list",
|
|
966
|
+
],
|
|
967
|
+
"gotchas": [
|
|
968
|
+
"For .NET Core and .NET 5+ projects, prefer dotnet nuget commands over nuget.exe -- nuget.exe is primarily for .NET Framework projects",
|
|
969
|
+
"nuget.exe is Windows-only by default; on macOS/Linux use dotnet CLI or Mono-based nuget",
|
|
970
|
+
"NuGet package restore can fail in CI if the package source is not configured -- ensure nuget.config is committed with the project",
|
|
971
|
+
],
|
|
972
|
+
"related": ["dotnet", "msbuild"],
|
|
973
|
+
"difficulty": "intermediate",
|
|
974
|
+
"extra_flags": {
|
|
975
|
+
"restore": "Restore packages for a solution or project",
|
|
976
|
+
"pack": "Create a NuGet package from a project or nuspec",
|
|
977
|
+
"push": "Publish a package to a NuGet server",
|
|
978
|
+
"sources": "Manage NuGet package sources",
|
|
979
|
+
"config": "Get or set NuGet configuration values",
|
|
980
|
+
"-Source": "Specify the package source URL",
|
|
981
|
+
"-ApiKey": "API key for publishing packages",
|
|
982
|
+
},
|
|
983
|
+
},
|
|
984
|
+
|
|
985
|
+
"dotnet": {
|
|
986
|
+
"man_url": "https://learn.microsoft.com/en-us/dotnet/core/tools/",
|
|
987
|
+
"use_cases": [
|
|
988
|
+
"Create a new project from a template: dotnet new webapi -n MyApi",
|
|
989
|
+
"Build the project: dotnet build",
|
|
990
|
+
"Run the application: dotnet run",
|
|
991
|
+
"Run tests: dotnet test",
|
|
992
|
+
"Publish a self-contained application: dotnet publish -c Release --self-contained",
|
|
993
|
+
"Add a NuGet package: dotnet add package Newtonsoft.Json",
|
|
994
|
+
],
|
|
995
|
+
"gotchas": [
|
|
996
|
+
"dotnet run compiles and runs in debug mode by default -- use -c Release for production-like performance during development testing",
|
|
997
|
+
"dotnet restore is run implicitly by build, run, and test -- explicit restore is only needed in CI environments with --no-restore later",
|
|
998
|
+
"Self-contained deployments (--self-contained) bundle the runtime and can be very large; use trimming (--self-contained -p:PublishTrimmed=true) to reduce size",
|
|
999
|
+
],
|
|
1000
|
+
"related": ["nuget", "msbuild"],
|
|
1001
|
+
"difficulty": "intermediate",
|
|
1002
|
+
"extra_flags": {
|
|
1003
|
+
"new": "Create a new project, solution, or file from a template",
|
|
1004
|
+
"restore": "Restore NuGet dependencies",
|
|
1005
|
+
"publish": "Publish the application for deployment",
|
|
1006
|
+
"add package": "Add a NuGet package reference to the project",
|
|
1007
|
+
"add reference": "Add a project-to-project reference",
|
|
1008
|
+
"tool install": "Install a .NET global or local tool",
|
|
1009
|
+
"ef": "Entity Framework Core CLI commands (migrations, database)",
|
|
1010
|
+
"--runtime": "Specify the target runtime identifier (e.g., linux-x64)",
|
|
1011
|
+
"watch": "Watch for file changes and rerun the command",
|
|
1012
|
+
},
|
|
1013
|
+
},
|
|
1014
|
+
|
|
1015
|
+
# =========================================================================
|
|
1016
|
+
# PACKAGE MANAGEMENT -- Java / JVM
|
|
1017
|
+
# =========================================================================
|
|
1018
|
+
|
|
1019
|
+
"mvn": {
|
|
1020
|
+
"man_url": "https://maven.apache.org/run.html",
|
|
1021
|
+
"use_cases": [
|
|
1022
|
+
"Compile the project: mvn compile",
|
|
1023
|
+
"Run tests: mvn test",
|
|
1024
|
+
"Package the project as a JAR or WAR: mvn package",
|
|
1025
|
+
"Install the artifact to the local Maven repository: mvn install",
|
|
1026
|
+
"Clean build artifacts and rebuild: mvn clean install",
|
|
1027
|
+
"Generate a project from an archetype: mvn archetype:generate",
|
|
1028
|
+
],
|
|
1029
|
+
"gotchas": [
|
|
1030
|
+
"Maven downloads the entire internet on first run (all dependencies) -- use mvn dependency:go-offline to pre-download for air-gapped builds",
|
|
1031
|
+
"mvn install puts artifacts in ~/.m2/repository which can grow very large over time -- periodically clean it manually",
|
|
1032
|
+
"Maven's verbose output makes errors hard to find -- use mvn -q for quiet mode or pipe through grep to find ERROR lines",
|
|
1033
|
+
"The pom.xml is XML and easy to make syntax errors in -- use mvn validate to check for basic POM errors",
|
|
1034
|
+
],
|
|
1035
|
+
"related": ["gradle", "java", "javac"],
|
|
1036
|
+
"difficulty": "intermediate",
|
|
1037
|
+
"extra_flags": {
|
|
1038
|
+
"clean": "Delete the target directory with build artifacts",
|
|
1039
|
+
"verify": "Run integration tests",
|
|
1040
|
+
"deploy": "Copy the artifact to a remote repository",
|
|
1041
|
+
"-DskipTests": "Skip running tests during build",
|
|
1042
|
+
"-pl": "Build specific modules in a multi-module project",
|
|
1043
|
+
"-am": "Also build dependent modules",
|
|
1044
|
+
"-U": "Force update of snapshots from remote repositories",
|
|
1045
|
+
"-o": "Work offline (use only local repository)",
|
|
1046
|
+
"-B": "Run in non-interactive batch mode",
|
|
1047
|
+
"-X": "Enable debug output for troubleshooting",
|
|
1048
|
+
},
|
|
1049
|
+
},
|
|
1050
|
+
|
|
1051
|
+
"gradle": {
|
|
1052
|
+
"man_url": "https://docs.gradle.org/current/userguide/command_line_interface.html",
|
|
1053
|
+
"use_cases": [
|
|
1054
|
+
"Build the project: gradle build",
|
|
1055
|
+
"Run tests: gradle test",
|
|
1056
|
+
"Run the application: gradle run",
|
|
1057
|
+
"Clean build artifacts and rebuild: gradle clean build",
|
|
1058
|
+
"List available tasks: gradle tasks",
|
|
1059
|
+
"Build multiple subprojects in parallel: gradle build --parallel",
|
|
1060
|
+
],
|
|
1061
|
+
"gotchas": [
|
|
1062
|
+
"Use the Gradle wrapper (./gradlew) instead of the system gradle command to ensure the correct Gradle version for each project",
|
|
1063
|
+
"Gradle's daemon stays in memory between builds for speed but can consume significant RAM -- use gradle --stop to kill it",
|
|
1064
|
+
"Gradle uses Groovy DSL (build.gradle) or Kotlin DSL (build.gradle.kts) -- they are not interchangeable and have different syntax",
|
|
1065
|
+
"The --continuous flag watches for file changes and re-runs tasks automatically, but it can miss changes in some edge cases",
|
|
1066
|
+
],
|
|
1067
|
+
"related": ["mvn", "java", "javac"],
|
|
1068
|
+
"difficulty": "intermediate",
|
|
1069
|
+
"extra_flags": {
|
|
1070
|
+
"tasks": "List all available tasks in the project",
|
|
1071
|
+
"dependencies": "Display dependency tree",
|
|
1072
|
+
"--daemon": "Run using the Gradle daemon (default)",
|
|
1073
|
+
"--no-daemon": "Run without the Gradle daemon",
|
|
1074
|
+
"--stop": "Stop the Gradle daemon",
|
|
1075
|
+
"--refresh-dependencies": "Force refresh of all dependencies",
|
|
1076
|
+
"--scan": "Create a build scan for debugging build issues",
|
|
1077
|
+
"-x": "Exclude a task from execution",
|
|
1078
|
+
"--stacktrace": "Print full stack trace on error",
|
|
1079
|
+
},
|
|
1080
|
+
},
|
|
1081
|
+
|
|
1082
|
+
# =========================================================================
|
|
1083
|
+
# COMPRESSION COMMANDS
|
|
1084
|
+
# =========================================================================
|
|
1085
|
+
|
|
1086
|
+
"gzip": {
|
|
1087
|
+
"man_url": "https://www.gnu.org/software/gzip/manual/gzip.html",
|
|
1088
|
+
"use_cases": [
|
|
1089
|
+
"Compress a file (replaces original with .gz): gzip file.txt",
|
|
1090
|
+
"Compress while keeping the original: gzip -k file.txt",
|
|
1091
|
+
"Compress with best compression ratio: gzip -9 file.txt",
|
|
1092
|
+
"Decompress a .gz file: gzip -d file.txt.gz",
|
|
1093
|
+
"Compress all files in a directory recursively: gzip -r directory/",
|
|
1094
|
+
"View compression ratio without decompressing: gzip -l file.txt.gz",
|
|
1095
|
+
],
|
|
1096
|
+
"gotchas": [
|
|
1097
|
+
"gzip replaces the original file by default -- use -k to keep the original, or redirect: gzip -c file > file.gz",
|
|
1098
|
+
"gzip only compresses single files; it does not create archives of multiple files -- use tar czf for multiple files",
|
|
1099
|
+
"gzip compression level (-1 to -9) trades speed for compression ratio; the default -6 is usually a good balance",
|
|
1100
|
+
],
|
|
1101
|
+
"related": ["gunzip", "zcat", "bzip2", "xz", "zstd"],
|
|
1102
|
+
"difficulty": "beginner",
|
|
1103
|
+
"extra_flags": {
|
|
1104
|
+
"-c": "Write to stdout, keep original files",
|
|
1105
|
+
"-r": "Recursively compress files in a directory",
|
|
1106
|
+
"-l": "List compression statistics",
|
|
1107
|
+
"-t": "Test compressed file integrity",
|
|
1108
|
+
"-f": "Force compression even if output file exists",
|
|
1109
|
+
"-1": "Fastest compression (least compression ratio)",
|
|
1110
|
+
"-6": "Default compression level (balanced)",
|
|
1111
|
+
},
|
|
1112
|
+
},
|
|
1113
|
+
|
|
1114
|
+
"gunzip": {
|
|
1115
|
+
"man_url": "https://www.gnu.org/software/gzip/manual/gzip.html",
|
|
1116
|
+
"use_cases": [
|
|
1117
|
+
"Decompress a .gz file: gunzip file.txt.gz",
|
|
1118
|
+
"Decompress and keep the original .gz file: gunzip -k file.txt.gz",
|
|
1119
|
+
"View compression statistics without decompressing: gunzip -l file.gz",
|
|
1120
|
+
"Test file integrity: gunzip -t file.gz",
|
|
1121
|
+
],
|
|
1122
|
+
"gotchas": [
|
|
1123
|
+
"gunzip is equivalent to gzip -d -- they are the same program; use whichever is more readable in your context",
|
|
1124
|
+
"gunzip deletes the .gz file after decompression by default -- use -k to keep both files",
|
|
1125
|
+
"If the output file already exists, gunzip will refuse to overwrite unless -f is passed",
|
|
1126
|
+
],
|
|
1127
|
+
"related": ["gzip", "zcat", "bzip2", "xz"],
|
|
1128
|
+
"difficulty": "beginner",
|
|
1129
|
+
"extra_flags": {},
|
|
1130
|
+
},
|
|
1131
|
+
|
|
1132
|
+
"bzip2": {
|
|
1133
|
+
"man_url": "https://sourceware.org/bzip2/manual/manual.html",
|
|
1134
|
+
"use_cases": [
|
|
1135
|
+
"Compress a file with higher ratio than gzip: bzip2 file.txt",
|
|
1136
|
+
"Compress while keeping the original: bzip2 -k file.txt",
|
|
1137
|
+
"Decompress a .bz2 file: bzip2 -d file.txt.bz2",
|
|
1138
|
+
"Test integrity of a compressed file: bzip2 -t file.bz2",
|
|
1139
|
+
],
|
|
1140
|
+
"gotchas": [
|
|
1141
|
+
"bzip2 is significantly slower than gzip for both compression and decompression -- use it only when the better compression ratio matters",
|
|
1142
|
+
"bzip2 replaces the original file by default, just like gzip -- use -k to keep the original",
|
|
1143
|
+
"bzip2 does not support compression levels like gzip; its block size (-1 through -9) controls memory usage, not compression quality in the same way",
|
|
1144
|
+
],
|
|
1145
|
+
"related": ["bunzip2", "bzcat", "gzip", "xz", "zstd"],
|
|
1146
|
+
"difficulty": "beginner",
|
|
1147
|
+
"extra_flags": {
|
|
1148
|
+
"-c": "Write to stdout, keep original files",
|
|
1149
|
+
"-v": "Verbose: show compression ratio for each file",
|
|
1150
|
+
"-f": "Force overwrite of output files",
|
|
1151
|
+
"-s": "Reduce memory usage at the cost of compression ratio",
|
|
1152
|
+
},
|
|
1153
|
+
},
|
|
1154
|
+
|
|
1155
|
+
"bunzip2": {
|
|
1156
|
+
"man_url": "https://sourceware.org/bzip2/manual/manual.html",
|
|
1157
|
+
"use_cases": [
|
|
1158
|
+
"Decompress a .bz2 file: bunzip2 file.txt.bz2",
|
|
1159
|
+
"Decompress and keep the original: bunzip2 -k file.txt.bz2",
|
|
1160
|
+
"Decompress to stdout for piping: bunzip2 -c file.bz2 | grep pattern",
|
|
1161
|
+
],
|
|
1162
|
+
"gotchas": [
|
|
1163
|
+
"bunzip2 is equivalent to bzip2 -d -- they are the same program",
|
|
1164
|
+
"bunzip2 removes the .bz2 file after decompression by default -- use -k to keep it",
|
|
1165
|
+
],
|
|
1166
|
+
"related": ["bzip2", "bzcat", "gunzip", "unxz"],
|
|
1167
|
+
"difficulty": "beginner",
|
|
1168
|
+
"extra_flags": {},
|
|
1169
|
+
},
|
|
1170
|
+
|
|
1171
|
+
"xz": {
|
|
1172
|
+
"man_url": "https://man7.org/linux/man-pages/man1/xz.1.html",
|
|
1173
|
+
"use_cases": [
|
|
1174
|
+
"Compress a file with very high compression ratio: xz file.txt",
|
|
1175
|
+
"Compress while keeping the original: xz -k file.txt",
|
|
1176
|
+
"Decompress an .xz file: xz -d file.txt.xz",
|
|
1177
|
+
"Use multiple CPU cores for compression: xz -T0 file.txt",
|
|
1178
|
+
"Compress with maximum ratio: xz -9 file.txt",
|
|
1179
|
+
],
|
|
1180
|
+
"gotchas": [
|
|
1181
|
+
"xz achieves the best compression ratio of common tools but is much slower than gzip or zstd -- use it for archival, not real-time compression",
|
|
1182
|
+
"xz -9 uses significant memory (up to ~674 MB) -- on low-memory systems, use -6 or lower",
|
|
1183
|
+
"xz replaces the original file by default -- use -k to keep the original",
|
|
1184
|
+
"Threaded compression (-T0) produces different output than single-threaded, so checksums will differ for the same input",
|
|
1185
|
+
],
|
|
1186
|
+
"related": ["unxz", "xzcat", "gzip", "bzip2", "zstd"],
|
|
1187
|
+
"difficulty": "beginner",
|
|
1188
|
+
"extra_flags": {
|
|
1189
|
+
"-T": "Set number of compression threads (0 = auto-detect CPU count)",
|
|
1190
|
+
"-c": "Write to stdout, keep original files",
|
|
1191
|
+
"-l": "List information about .xz files",
|
|
1192
|
+
"-t": "Test compressed file integrity",
|
|
1193
|
+
"-e": "Use extreme compression (slower but slightly smaller)",
|
|
1194
|
+
},
|
|
1195
|
+
},
|
|
1196
|
+
|
|
1197
|
+
"unxz": {
|
|
1198
|
+
"man_url": "https://man7.org/linux/man-pages/man1/xz.1.html",
|
|
1199
|
+
"use_cases": [
|
|
1200
|
+
"Decompress an .xz file: unxz file.txt.xz",
|
|
1201
|
+
"Decompress while keeping the original: unxz -k file.txt.xz",
|
|
1202
|
+
],
|
|
1203
|
+
"gotchas": [
|
|
1204
|
+
"unxz is equivalent to xz --decompress -- they are the same program",
|
|
1205
|
+
"unxz removes the .xz file after decompression by default",
|
|
1206
|
+
],
|
|
1207
|
+
"related": ["xz", "xzcat", "gunzip", "bunzip2"],
|
|
1208
|
+
"difficulty": "beginner",
|
|
1209
|
+
"extra_flags": {},
|
|
1210
|
+
},
|
|
1211
|
+
|
|
1212
|
+
"zip": {
|
|
1213
|
+
"man_url": "https://linux.die.net/man/1/zip",
|
|
1214
|
+
"use_cases": [
|
|
1215
|
+
"Create a zip archive from multiple files: zip archive.zip file1.txt file2.txt",
|
|
1216
|
+
"Recursively zip a directory: zip -r archive.zip directory/",
|
|
1217
|
+
"Add files to an existing zip archive: zip archive.zip newfile.txt",
|
|
1218
|
+
"Create a password-protected zip: zip -e secure.zip secrets.txt",
|
|
1219
|
+
"Exclude specific patterns: zip -r archive.zip dir/ -x '*.log'",
|
|
1220
|
+
],
|
|
1221
|
+
"gotchas": [
|
|
1222
|
+
"zip does not compress as well as gzip, bzip2, or xz for individual files -- its advantage is the archive format that Windows and macOS natively support",
|
|
1223
|
+
"zip -r is required for directories; without -r, zip only adds files in the current directory level",
|
|
1224
|
+
"zip encryption (-e) uses the legacy ZipCrypto algorithm which is weak -- use 7z or gpg for real security",
|
|
1225
|
+
"File permissions and symlinks may not be preserved in zip archives across different operating systems",
|
|
1226
|
+
],
|
|
1227
|
+
"related": ["unzip", "tar", "gzip", "7z"],
|
|
1228
|
+
"difficulty": "beginner",
|
|
1229
|
+
"extra_flags": {
|
|
1230
|
+
"-j": "Junk (do not record) directory names -- store just the filenames",
|
|
1231
|
+
"-u": "Update existing entries only if newer",
|
|
1232
|
+
"-d": "Delete entries from a zip archive",
|
|
1233
|
+
"-x": "Exclude files matching the given patterns",
|
|
1234
|
+
"-q": "Quiet mode (suppress output)",
|
|
1235
|
+
"-0": "Store only (no compression)",
|
|
1236
|
+
"-T": "Test archive integrity after creation",
|
|
1237
|
+
"-s": "Create a split archive with specified size",
|
|
1238
|
+
},
|
|
1239
|
+
},
|
|
1240
|
+
|
|
1241
|
+
"unzip": {
|
|
1242
|
+
"man_url": "https://linux.die.net/man/1/unzip",
|
|
1243
|
+
"use_cases": [
|
|
1244
|
+
"Extract all files from a zip archive: unzip archive.zip",
|
|
1245
|
+
"Extract to a specific directory: unzip archive.zip -d /tmp/output",
|
|
1246
|
+
"List contents of a zip without extracting: unzip -l archive.zip",
|
|
1247
|
+
"Extract only specific files: unzip archive.zip '*.txt'",
|
|
1248
|
+
"Test archive integrity: unzip -t archive.zip",
|
|
1249
|
+
],
|
|
1250
|
+
"gotchas": [
|
|
1251
|
+
"unzip extracts to the current directory by default, which can be messy -- always use -d to specify a target directory",
|
|
1252
|
+
"unzip will prompt before overwriting existing files unless -o (overwrite) is passed",
|
|
1253
|
+
"Zip archives created on Windows may have filenames in non-UTF-8 encoding, causing garbled names on Linux -- use unzip -O CP437 as a workaround",
|
|
1254
|
+
"unzip cannot handle .gz or .tar.gz files -- those require gunzip or tar xzf respectively",
|
|
1255
|
+
],
|
|
1256
|
+
"related": ["zip", "tar", "7z"],
|
|
1257
|
+
"difficulty": "beginner",
|
|
1258
|
+
"extra_flags": {
|
|
1259
|
+
"-q": "Quiet mode (suppress output except errors)",
|
|
1260
|
+
"-n": "Never overwrite existing files",
|
|
1261
|
+
"-j": "Junk paths (extract flat without directory structure)",
|
|
1262
|
+
"-p": "Extract to stdout (for piping)",
|
|
1263
|
+
"-Z": "Display archive information in zipinfo format",
|
|
1264
|
+
},
|
|
1265
|
+
},
|
|
1266
|
+
|
|
1267
|
+
"7z": {
|
|
1268
|
+
"man_url": "https://linux.die.net/man/1/7z",
|
|
1269
|
+
"use_cases": [
|
|
1270
|
+
"Create a 7z archive: 7z a archive.7z file1.txt file2.txt",
|
|
1271
|
+
"Extract a 7z archive: 7z x archive.7z",
|
|
1272
|
+
"List contents of an archive: 7z l archive.7z",
|
|
1273
|
+
"Create a password-protected archive: 7z a -p archive.7z sensitive/",
|
|
1274
|
+
"Create a zip-format archive with 7z: 7z a archive.zip directory/",
|
|
1275
|
+
],
|
|
1276
|
+
"gotchas": [
|
|
1277
|
+
"7z achieves the best compression but is slower than gzip or zstd -- use it for archival and distribution, not real-time compression",
|
|
1278
|
+
"7z e extracts files flat (no directory structure); use 7z x to preserve the directory tree",
|
|
1279
|
+
"The 7z format does not preserve Unix file permissions or ownership -- use tar inside 7z for Unix systems",
|
|
1280
|
+
"Different 7z packages exist on Linux: p7zip-full provides 7z, while p7zip provides only 7za (fewer formats)",
|
|
1281
|
+
],
|
|
1282
|
+
"related": ["7za", "zip", "unzip", "tar"],
|
|
1283
|
+
"difficulty": "intermediate",
|
|
1284
|
+
"extra_flags": {
|
|
1285
|
+
"a": "Add files to an archive (create or append)",
|
|
1286
|
+
"x": "Extract with full directory paths",
|
|
1287
|
+
"e": "Extract files to current directory (flat, no paths)",
|
|
1288
|
+
"l": "List contents of an archive",
|
|
1289
|
+
"t": "Test archive integrity",
|
|
1290
|
+
"u": "Update files in an archive",
|
|
1291
|
+
"-p": "Set password for encryption/decryption",
|
|
1292
|
+
"-mx": "Set compression level (0=store, 9=ultra)",
|
|
1293
|
+
"-t": "Set archive type (7z, zip, gzip, bzip2, tar)",
|
|
1294
|
+
"-v": "Create multi-volume (split) archives",
|
|
1295
|
+
},
|
|
1296
|
+
},
|
|
1297
|
+
|
|
1298
|
+
"7za": {
|
|
1299
|
+
"man_url": "https://linux.die.net/man/1/7za",
|
|
1300
|
+
"use_cases": [
|
|
1301
|
+
"Create a 7z archive with the standalone version: 7za a archive.7z files/",
|
|
1302
|
+
"Extract an archive: 7za x archive.7z",
|
|
1303
|
+
"Test archive integrity: 7za t archive.7z",
|
|
1304
|
+
],
|
|
1305
|
+
"gotchas": [
|
|
1306
|
+
"7za is a standalone version of 7z with fewer supported formats -- it handles 7z, xz, lzma, and a few others but not all formats 7z supports",
|
|
1307
|
+
"For full format support (zip, rar, cab, etc.), install p7zip-full which provides 7z instead of 7za",
|
|
1308
|
+
],
|
|
1309
|
+
"related": ["7z", "zip", "tar"],
|
|
1310
|
+
"difficulty": "intermediate",
|
|
1311
|
+
"extra_flags": {},
|
|
1312
|
+
},
|
|
1313
|
+
|
|
1314
|
+
"rar": {
|
|
1315
|
+
"man_url": "https://linux.die.net/man/1/rar",
|
|
1316
|
+
"use_cases": [
|
|
1317
|
+
"Create a RAR archive: rar a archive.rar file1.txt file2.txt",
|
|
1318
|
+
"Create a password-protected archive: rar a -p archive.rar secret/",
|
|
1319
|
+
"Create a split archive: rar a -v100m archive.rar largefile.bin",
|
|
1320
|
+
"Update an existing archive: rar u archive.rar newfile.txt",
|
|
1321
|
+
],
|
|
1322
|
+
"gotchas": [
|
|
1323
|
+
"RAR is a proprietary format; the rar command for creating archives is not free software and requires a license",
|
|
1324
|
+
"For extraction only, use unrar which is available as freeware on most Linux distributions",
|
|
1325
|
+
"RAR format is less common on Unix systems; prefer tar+gzip/xz/zstd for Unix-to-Unix transfers",
|
|
1326
|
+
],
|
|
1327
|
+
"related": ["unrar", "7z", "zip", "tar"],
|
|
1328
|
+
"difficulty": "intermediate",
|
|
1329
|
+
"extra_flags": {
|
|
1330
|
+
"a": "Add files to archive",
|
|
1331
|
+
"x": "Extract with full path",
|
|
1332
|
+
"e": "Extract to current directory (flat)",
|
|
1333
|
+
"t": "Test archive files",
|
|
1334
|
+
"-v": "Create split volumes of specified size",
|
|
1335
|
+
"-r": "Recurse into subdirectories",
|
|
1336
|
+
"-m5": "Set maximum compression",
|
|
1337
|
+
},
|
|
1338
|
+
},
|
|
1339
|
+
|
|
1340
|
+
"unrar": {
|
|
1341
|
+
"man_url": "https://linux.die.net/man/1/unrar",
|
|
1342
|
+
"use_cases": [
|
|
1343
|
+
"Extract a RAR archive: unrar x archive.rar",
|
|
1344
|
+
"Extract to a specific directory: unrar x archive.rar /tmp/output/",
|
|
1345
|
+
"List contents of a RAR archive: unrar l archive.rar",
|
|
1346
|
+
"Test archive integrity: unrar t archive.rar",
|
|
1347
|
+
],
|
|
1348
|
+
"gotchas": [
|
|
1349
|
+
"unrar x preserves directory structure; unrar e extracts all files flat to the current directory",
|
|
1350
|
+
"unrar is freeware but not open source (there is also an open-source unrar-free with less format support)",
|
|
1351
|
+
],
|
|
1352
|
+
"related": ["rar", "7z", "unzip"],
|
|
1353
|
+
"difficulty": "beginner",
|
|
1354
|
+
"extra_flags": {
|
|
1355
|
+
"x": "Extract with full path",
|
|
1356
|
+
"e": "Extract to current directory (flat, no paths)",
|
|
1357
|
+
"l": "List archive contents",
|
|
1358
|
+
"t": "Test archive integrity",
|
|
1359
|
+
"-o+": "Overwrite existing files without prompting",
|
|
1360
|
+
"-o-": "Never overwrite existing files",
|
|
1361
|
+
},
|
|
1362
|
+
},
|
|
1363
|
+
|
|
1364
|
+
"zstd": {
|
|
1365
|
+
"man_url": "https://facebook.github.io/zstd/zstd_manual.html",
|
|
1366
|
+
"use_cases": [
|
|
1367
|
+
"Compress a file: zstd file.txt",
|
|
1368
|
+
"Compress with best ratio: zstd -19 file.txt",
|
|
1369
|
+
"Compress ultra-fast: zstd --fast file.txt",
|
|
1370
|
+
"Decompress a .zst file: zstd -d file.txt.zst",
|
|
1371
|
+
"Use multiple CPU cores: zstd -T0 file.txt",
|
|
1372
|
+
"Compress while keeping the original: zstd -k file.txt",
|
|
1373
|
+
],
|
|
1374
|
+
"gotchas": [
|
|
1375
|
+
"zstd supports compression levels from -7 (fast) to 22 (ultra) plus --fast levels -- the default level 3 is usually optimal for most use cases",
|
|
1376
|
+
"zstd replaces the original file by default -- use -k to keep the original",
|
|
1377
|
+
"While zstd is faster than gzip at comparable compression ratios, the .zst format is not as universally supported -- check that your target systems have zstd installed",
|
|
1378
|
+
"The --train option creates a dictionary from sample files for better compression of small, similar files (like JSON logs)",
|
|
1379
|
+
],
|
|
1380
|
+
"related": ["gzip", "bzip2", "xz", "lz4"],
|
|
1381
|
+
"difficulty": "beginner",
|
|
1382
|
+
"extra_flags": {
|
|
1383
|
+
"-T": "Number of compression threads (0 = auto)",
|
|
1384
|
+
"--fast": "Ultra-fast compression (trade ratio for speed)",
|
|
1385
|
+
"--train": "Train a dictionary from sample files",
|
|
1386
|
+
"-D": "Use a dictionary for compression/decompression",
|
|
1387
|
+
"--rm": "Remove source file after compression (explicit default)",
|
|
1388
|
+
"-c": "Write to stdout",
|
|
1389
|
+
"--long": "Enable long-distance matching for large files",
|
|
1390
|
+
"-19": "High compression level (slower, smaller output)",
|
|
1391
|
+
},
|
|
1392
|
+
},
|
|
1393
|
+
|
|
1394
|
+
"compress": {
|
|
1395
|
+
"man_url": "https://linux.die.net/man/1/compress",
|
|
1396
|
+
"use_cases": [
|
|
1397
|
+
"Compress a file (creates .Z file): compress file.txt",
|
|
1398
|
+
"Decompress a .Z file: compress -d file.Z",
|
|
1399
|
+
"Write compressed output to stdout: compress -c file.txt > file.Z",
|
|
1400
|
+
],
|
|
1401
|
+
"gotchas": [
|
|
1402
|
+
"compress uses the LZW algorithm and is largely obsolete -- gzip, bzip2, xz, and zstd all provide better compression",
|
|
1403
|
+
"compress creates .Z files which are rarely seen on modern systems",
|
|
1404
|
+
"compress may not be installed by default on modern Linux distributions",
|
|
1405
|
+
],
|
|
1406
|
+
"related": ["uncompress", "gzip", "bzip2"],
|
|
1407
|
+
"difficulty": "intermediate",
|
|
1408
|
+
"extra_flags": {
|
|
1409
|
+
"-c": "Write to stdout, keep original file",
|
|
1410
|
+
"-f": "Force compression even if .Z file already exists",
|
|
1411
|
+
"-v": "Verbose: print compression ratio",
|
|
1412
|
+
},
|
|
1413
|
+
},
|
|
1414
|
+
|
|
1415
|
+
"uncompress": {
|
|
1416
|
+
"man_url": "https://linux.die.net/man/1/uncompress",
|
|
1417
|
+
"use_cases": [
|
|
1418
|
+
"Decompress a .Z file: uncompress file.Z",
|
|
1419
|
+
"Decompress to stdout for piping: uncompress -c file.Z | grep pattern",
|
|
1420
|
+
],
|
|
1421
|
+
"gotchas": [
|
|
1422
|
+
"uncompress is equivalent to compress -d -- it decompresses .Z files created by the compress command",
|
|
1423
|
+
"If you encounter .Z files, gzip can also decompress them: gunzip file.Z",
|
|
1424
|
+
],
|
|
1425
|
+
"related": ["compress", "gunzip"],
|
|
1426
|
+
"difficulty": "intermediate",
|
|
1427
|
+
"extra_flags": {},
|
|
1428
|
+
},
|
|
1429
|
+
|
|
1430
|
+
"lz4": {
|
|
1431
|
+
"man_url": "https://github.com/lz4/lz4/blob/dev/programs/lz4.1.md",
|
|
1432
|
+
"use_cases": [
|
|
1433
|
+
"Compress a file extremely fast: lz4 file.txt",
|
|
1434
|
+
"Decompress a .lz4 file: lz4 -d file.lz4",
|
|
1435
|
+
"Compress with higher ratio (slower): lz4 -9 file.txt",
|
|
1436
|
+
"Compress and keep the original: lz4 -k file.txt",
|
|
1437
|
+
"Benchmark compression speed: lz4 -b file.txt",
|
|
1438
|
+
],
|
|
1439
|
+
"gotchas": [
|
|
1440
|
+
"lz4 prioritizes speed over compression ratio -- files will be larger than gzip output but compress/decompress much faster",
|
|
1441
|
+
"lz4 is ideal for real-time applications like filesystem compression (btrfs/zfs), database pages, and network compression",
|
|
1442
|
+
"lz4 replaces the original file by default -- use -k to keep it",
|
|
1443
|
+
],
|
|
1444
|
+
"related": ["zstd", "gzip", "lzop"],
|
|
1445
|
+
"difficulty": "beginner",
|
|
1446
|
+
"extra_flags": {
|
|
1447
|
+
"-b": "Benchmark mode: measure compression/decompression speed",
|
|
1448
|
+
"-B": "Set block size for compression",
|
|
1449
|
+
"--content-size": "Store original content size in the frame header",
|
|
1450
|
+
},
|
|
1451
|
+
},
|
|
1452
|
+
|
|
1453
|
+
"lzop": {
|
|
1454
|
+
"man_url": "https://www.lzop.org/lzop_man.php",
|
|
1455
|
+
"use_cases": [
|
|
1456
|
+
"Compress a file fast: lzop file.txt",
|
|
1457
|
+
"Decompress a .lzo file: lzop -d file.lzo",
|
|
1458
|
+
"Compress with best ratio: lzop -9 file.txt",
|
|
1459
|
+
"Test archive integrity: lzop -t file.lzo",
|
|
1460
|
+
],
|
|
1461
|
+
"gotchas": [
|
|
1462
|
+
"lzop is an older speed-focused compressor; lz4 and zstd have largely replaced it for most use cases",
|
|
1463
|
+
"lzop replaces the original file by default -- use -k to keep it",
|
|
1464
|
+
],
|
|
1465
|
+
"related": ["lz4", "gzip", "zstd"],
|
|
1466
|
+
"difficulty": "intermediate",
|
|
1467
|
+
"extra_flags": {},
|
|
1468
|
+
},
|
|
1469
|
+
|
|
1470
|
+
"zcat": {
|
|
1471
|
+
"man_url": "https://www.gnu.org/software/gzip/manual/gzip.html",
|
|
1472
|
+
"use_cases": [
|
|
1473
|
+
"View compressed log file without decompressing: zcat access.log.gz",
|
|
1474
|
+
"Pipe compressed data to grep: zcat file.gz | grep pattern",
|
|
1475
|
+
"Count lines in a compressed file: zcat file.gz | wc -l",
|
|
1476
|
+
],
|
|
1477
|
+
"gotchas": [
|
|
1478
|
+
"zcat is equivalent to gzip -dc (decompress to stdout) -- it does not modify the original .gz file",
|
|
1479
|
+
"On some systems (macOS), zcat expects a .Z suffix; use gzcat or gzip -dc for .gz files instead",
|
|
1480
|
+
],
|
|
1481
|
+
"related": ["gzip", "gunzip", "bzcat", "xzcat"],
|
|
1482
|
+
"difficulty": "beginner",
|
|
1483
|
+
"extra_flags": {},
|
|
1484
|
+
},
|
|
1485
|
+
|
|
1486
|
+
"bzcat": {
|
|
1487
|
+
"man_url": "https://sourceware.org/bzip2/manual/manual.html",
|
|
1488
|
+
"use_cases": [
|
|
1489
|
+
"View a bzip2-compressed file without decompressing: bzcat file.bz2",
|
|
1490
|
+
"Pipe compressed data to another command: bzcat data.bz2 | sort | uniq",
|
|
1491
|
+
],
|
|
1492
|
+
"gotchas": [
|
|
1493
|
+
"bzcat is equivalent to bzip2 -dc -- it decompresses to stdout without modifying the original file",
|
|
1494
|
+
],
|
|
1495
|
+
"related": ["bzip2", "bunzip2", "zcat", "xzcat"],
|
|
1496
|
+
"difficulty": "beginner",
|
|
1497
|
+
"extra_flags": {},
|
|
1498
|
+
},
|
|
1499
|
+
|
|
1500
|
+
"xzcat": {
|
|
1501
|
+
"man_url": "https://man7.org/linux/man-pages/man1/xz.1.html",
|
|
1502
|
+
"use_cases": [
|
|
1503
|
+
"View an xz-compressed file without decompressing: xzcat file.xz",
|
|
1504
|
+
"Pipe compressed data to grep: xzcat data.xz | grep pattern",
|
|
1505
|
+
"Extract a tar archive compressed with xz: xzcat archive.tar.xz | tar xf -",
|
|
1506
|
+
],
|
|
1507
|
+
"gotchas": [
|
|
1508
|
+
"xzcat is equivalent to xz --decompress --stdout -- it does not modify the original file",
|
|
1509
|
+
],
|
|
1510
|
+
"related": ["xz", "unxz", "zcat", "bzcat"],
|
|
1511
|
+
"difficulty": "beginner",
|
|
1512
|
+
"extra_flags": {},
|
|
1513
|
+
},
|
|
1514
|
+
|
|
1515
|
+
# =========================================================================
|
|
1516
|
+
# GIT-RELATED TOOLS
|
|
1517
|
+
# =========================================================================
|
|
1518
|
+
|
|
1519
|
+
"gh": {
|
|
1520
|
+
"man_url": "https://cli.github.com/manual/",
|
|
1521
|
+
"use_cases": [
|
|
1522
|
+
"Clone a repo by shorthand: gh repo clone owner/repo",
|
|
1523
|
+
"Create a pull request from the current branch: gh pr create --fill",
|
|
1524
|
+
"List and filter issues: gh issue list --label bug --state open",
|
|
1525
|
+
"View CI/CD workflow run status: gh run list",
|
|
1526
|
+
"Make an authenticated GitHub API request: gh api repos/owner/repo/releases",
|
|
1527
|
+
"Create a new repo from the current directory: gh repo create my-repo --public --source=.",
|
|
1528
|
+
],
|
|
1529
|
+
"gotchas": [
|
|
1530
|
+
"gh requires authentication first -- run gh auth login before any operations; it supports both browser-based OAuth and personal access tokens",
|
|
1531
|
+
"gh pr create uses the current branch's diff against the default branch -- make sure you have committed and pushed your changes first",
|
|
1532
|
+
"gh api returns raw JSON; pipe to jq for filtering: gh api repos/owner/repo/issues | jq '.[].title'",
|
|
1533
|
+
],
|
|
1534
|
+
"related": ["git", "hub", "tig"],
|
|
1535
|
+
"difficulty": "beginner",
|
|
1536
|
+
"extra_flags": {
|
|
1537
|
+
"pr view": "View details of a pull request",
|
|
1538
|
+
"pr merge": "Merge a pull request",
|
|
1539
|
+
"pr checkout": "Check out a pull request branch locally",
|
|
1540
|
+
"release create": "Create a new GitHub release",
|
|
1541
|
+
"repo fork": "Fork a repository",
|
|
1542
|
+
"codespace": "Manage GitHub Codespaces",
|
|
1543
|
+
"secret": "Manage repository secrets",
|
|
1544
|
+
"variable": "Manage repository variables",
|
|
1545
|
+
"--json": "Output specific fields in JSON format",
|
|
1546
|
+
"--jq": "Filter JSON output with jq expressions",
|
|
1547
|
+
},
|
|
1548
|
+
},
|
|
1549
|
+
|
|
1550
|
+
"hub": {
|
|
1551
|
+
"man_url": "https://hub.github.com/hub.1.html",
|
|
1552
|
+
"use_cases": [
|
|
1553
|
+
"Clone a repo by shorthand: hub clone owner/repo",
|
|
1554
|
+
"Fork the current repo and add a remote: hub fork",
|
|
1555
|
+
"Create a pull request: hub pull-request -m 'My PR title'",
|
|
1556
|
+
"Open the repo page in a browser: hub browse",
|
|
1557
|
+
"Create a new GitHub repository: hub create my-new-repo",
|
|
1558
|
+
],
|
|
1559
|
+
"gotchas": [
|
|
1560
|
+
"hub is deprecated in favor of GitHub CLI (gh) -- GitHub recommends migrating to gh for active support and new features",
|
|
1561
|
+
"hub can be aliased to git (alias git=hub) to seamlessly extend git commands, but this can cause confusion when sharing scripts",
|
|
1562
|
+
"hub uses GITHUB_TOKEN environment variable for authentication, while gh uses its own credential store",
|
|
1563
|
+
],
|
|
1564
|
+
"related": ["gh", "git", "tig"],
|
|
1565
|
+
"difficulty": "intermediate",
|
|
1566
|
+
"extra_flags": {
|
|
1567
|
+
"ci-status": "Show CI status of the current commit",
|
|
1568
|
+
"sync": "Fetch and fast-forward the default branch",
|
|
1569
|
+
"release": "Manage GitHub releases",
|
|
1570
|
+
"issue": "Create and list GitHub issues",
|
|
1571
|
+
},
|
|
1572
|
+
},
|
|
1573
|
+
|
|
1574
|
+
"tig": {
|
|
1575
|
+
"man_url": "https://jonas.github.io/tig/doc/tig.1.html",
|
|
1576
|
+
"use_cases": [
|
|
1577
|
+
"Browse commit history interactively: tig",
|
|
1578
|
+
"View blame annotation for a file: tig blame file.py",
|
|
1579
|
+
"Check working tree status with staging support: tig status",
|
|
1580
|
+
"View stash entries: tig stash",
|
|
1581
|
+
"Browse commits for a specific file: tig -- path/to/file",
|
|
1582
|
+
],
|
|
1583
|
+
"gotchas": [
|
|
1584
|
+
"tig is read-mostly -- you can stage changes from the status view but most operations still require the git CLI",
|
|
1585
|
+
"Navigation uses Vim-like keys (j/k for movement, Enter to open, q to quit) which can be unfamiliar",
|
|
1586
|
+
"tig requires ncurses and may not be available by default on minimal server installs",
|
|
1587
|
+
],
|
|
1588
|
+
"related": ["git", "gitk", "gh"],
|
|
1589
|
+
"difficulty": "intermediate",
|
|
1590
|
+
"extra_flags": {
|
|
1591
|
+
"log": "Start in log view",
|
|
1592
|
+
"show": "Start in diff view for a specific commit",
|
|
1593
|
+
"refs": "Browse all references (branches, tags)",
|
|
1594
|
+
"grep": "Search through repository content",
|
|
1595
|
+
},
|
|
1596
|
+
},
|
|
1597
|
+
|
|
1598
|
+
"gitk": {
|
|
1599
|
+
"man_url": "https://git-scm.com/docs/gitk",
|
|
1600
|
+
"use_cases": [
|
|
1601
|
+
"View the entire commit history graphically: gitk --all",
|
|
1602
|
+
"Inspect history of a specific file: gitk -- path/to/file",
|
|
1603
|
+
"View recent commits: gitk --since='2 weeks ago'",
|
|
1604
|
+
"Explore merge conflicts: gitk --merge",
|
|
1605
|
+
],
|
|
1606
|
+
"gotchas": [
|
|
1607
|
+
"gitk requires a graphical display (X11/Wayland) -- it will not work over SSH without X forwarding or on headless servers",
|
|
1608
|
+
"gitk is part of the git-gui package, which may not be installed by default -- install it separately on some distributions",
|
|
1609
|
+
"gitk can be slow on repositories with very large histories -- use --max-count to limit",
|
|
1610
|
+
],
|
|
1611
|
+
"related": ["git", "tig", "git-gui"],
|
|
1612
|
+
"difficulty": "beginner",
|
|
1613
|
+
"extra_flags": {},
|
|
1614
|
+
},
|
|
1615
|
+
|
|
1616
|
+
"git-lfs": {
|
|
1617
|
+
"man_url": "https://git-lfs.com/",
|
|
1618
|
+
"use_cases": [
|
|
1619
|
+
"Initialize LFS in a repository: git lfs install",
|
|
1620
|
+
"Track large file patterns: git lfs track '*.psd' '*.zip'",
|
|
1621
|
+
"List all files tracked by LFS: git lfs ls-files",
|
|
1622
|
+
"Migrate existing large files to LFS: git lfs migrate import --include='*.bin'",
|
|
1623
|
+
"Pull LFS files after cloning: git lfs pull",
|
|
1624
|
+
],
|
|
1625
|
+
"gotchas": [
|
|
1626
|
+
"git lfs track only updates .gitattributes -- you still need to git add and commit the .gitattributes file",
|
|
1627
|
+
"LFS requires a compatible remote server (GitHub, GitLab, Bitbucket all support it) -- self-hosted Git servers need a separate LFS server",
|
|
1628
|
+
"Cloning an LFS repo downloads all LFS pointers but fetches only the current revision's files -- use git lfs fetch --all to get all versions",
|
|
1629
|
+
"LFS has storage and bandwidth limits on GitHub free plans -- large projects may need paid plans or self-hosted LFS",
|
|
1630
|
+
],
|
|
1631
|
+
"related": ["git", "gh"],
|
|
1632
|
+
"difficulty": "intermediate",
|
|
1633
|
+
"extra_flags": {
|
|
1634
|
+
"env": "Display the LFS environment configuration",
|
|
1635
|
+
"prune": "Delete old LFS files that are no longer referenced",
|
|
1636
|
+
"status": "Show the status of LFS files in the working tree",
|
|
1637
|
+
"logs": "Show LFS error logs for debugging",
|
|
1638
|
+
},
|
|
1639
|
+
},
|
|
1640
|
+
|
|
1641
|
+
# =========================================================================
|
|
1642
|
+
# MISCELLANEOUS / SHELL BUILTINS
|
|
1643
|
+
# =========================================================================
|
|
1644
|
+
|
|
1645
|
+
"date": {
|
|
1646
|
+
"man_url": "https://man7.org/linux/man-pages/man1/date.1.html",
|
|
1647
|
+
"use_cases": [
|
|
1648
|
+
"Display current date and time: date",
|
|
1649
|
+
"Format date for filenames: date +%Y-%m-%d_%H%M%S",
|
|
1650
|
+
"Get ISO 8601 formatted date: date -I or date --iso-8601",
|
|
1651
|
+
"Display a specific date: date -d 'next Friday'",
|
|
1652
|
+
"Calculate time differences: date -d '3 days ago' +%Y-%m-%d",
|
|
1653
|
+
"Get Unix epoch timestamp: date +%s",
|
|
1654
|
+
],
|
|
1655
|
+
"gotchas": [
|
|
1656
|
+
"The -d flag (display a specific date) is a GNU extension and does not work on macOS/BSD -- use gdate from coreutils or the -v flag on macOS instead",
|
|
1657
|
+
"date format specifiers are case-sensitive: %m is month, %M is minute; %d is day-of-month, %D is mm/dd/yy",
|
|
1658
|
+
"Setting the system date (date -s) requires root privileges and does not update the hardware clock -- use hwclock to sync",
|
|
1659
|
+
],
|
|
1660
|
+
"related": ["cal", "timedatectl", "hwclock"],
|
|
1661
|
+
"difficulty": "beginner",
|
|
1662
|
+
"extra_flags": {
|
|
1663
|
+
"+%FORMAT": "Display date using custom format string",
|
|
1664
|
+
"-R": "Output RFC 2822 formatted date",
|
|
1665
|
+
"--rfc-3339": "Output RFC 3339 formatted date",
|
|
1666
|
+
"-r": "Display last modification time of a file",
|
|
1667
|
+
},
|
|
1668
|
+
},
|
|
1669
|
+
|
|
1670
|
+
"sleep": {
|
|
1671
|
+
"man_url": "https://man7.org/linux/man-pages/man1/sleep.1.html",
|
|
1672
|
+
"use_cases": [
|
|
1673
|
+
"Pause execution for 5 seconds: sleep 5",
|
|
1674
|
+
"Wait for half a second: sleep 0.5",
|
|
1675
|
+
"Wait for 2 minutes: sleep 2m",
|
|
1676
|
+
"Add a delay between retries: while ! curl -s http://localhost:8080; do sleep 1; done",
|
|
1677
|
+
"Rate-limit a loop: for i in $(seq 1 100); do command; sleep 0.1; done",
|
|
1678
|
+
],
|
|
1679
|
+
"gotchas": [
|
|
1680
|
+
"sleep accepts suffixes: s (seconds, default), m (minutes), h (hours), d (days) -- these are GNU extensions not available on all systems",
|
|
1681
|
+
"Fractional seconds (sleep 0.5) work on GNU/Linux but not on all BSD/macOS versions -- check your system",
|
|
1682
|
+
"sleep in a script keeps the process alive and counts toward active processes -- do not use sleep for very long delays in production scripts; use cron or at instead",
|
|
1683
|
+
],
|
|
1684
|
+
"related": ["watch", "timeout", "wait"],
|
|
1685
|
+
"difficulty": "beginner",
|
|
1686
|
+
"extra_flags": {},
|
|
1687
|
+
},
|
|
1688
|
+
|
|
1689
|
+
"time": {
|
|
1690
|
+
"man_url": "https://man7.org/linux/man-pages/man1/time.1.html",
|
|
1691
|
+
"use_cases": [
|
|
1692
|
+
"Measure how long a command takes: time make -j4",
|
|
1693
|
+
"Time a complex pipeline: time (find . -name '*.py' | xargs wc -l)",
|
|
1694
|
+
"Benchmark a script: time ./run-tests.sh",
|
|
1695
|
+
],
|
|
1696
|
+
"gotchas": [
|
|
1697
|
+
"There are two 'time' commands: the bash builtin (outputs to stderr) and /usr/bin/time (more detailed output) -- use \\time or command time to invoke the external version",
|
|
1698
|
+
"The three values reported are: real (wall clock), user (CPU in user mode), sys (CPU in kernel mode) -- real >= user + sys due to I/O waits and process scheduling",
|
|
1699
|
+
"/usr/bin/time -v (verbose) gives memory usage, page faults, and more -- useful for profiling resource-intensive commands",
|
|
1700
|
+
],
|
|
1701
|
+
"related": ["timeout", "watch", "perf"],
|
|
1702
|
+
"difficulty": "beginner",
|
|
1703
|
+
"extra_flags": {
|
|
1704
|
+
"-p": "Use POSIX output format",
|
|
1705
|
+
"-v": "Verbose output with resource usage details (external time only)",
|
|
1706
|
+
"-o": "Write output to a file (external time only)",
|
|
1707
|
+
},
|
|
1708
|
+
},
|
|
1709
|
+
|
|
1710
|
+
"watch": {
|
|
1711
|
+
"man_url": "https://man7.org/linux/man-pages/man1/watch.1.html",
|
|
1712
|
+
"use_cases": [
|
|
1713
|
+
"Monitor disk space every 2 seconds: watch df -h",
|
|
1714
|
+
"Watch a directory for new files: watch -n 1 ls -lt /tmp/",
|
|
1715
|
+
"Highlight differences between updates: watch -d free -h",
|
|
1716
|
+
"Monitor a Kubernetes deployment: watch kubectl get pods",
|
|
1717
|
+
"Exit when the output changes: watch -g 'cat /proc/loadavg'",
|
|
1718
|
+
],
|
|
1719
|
+
"gotchas": [
|
|
1720
|
+
"watch runs the command in sh, not bash, so bash-specific syntax like arrays or [[ ]] may fail -- wrap complex commands in quotes",
|
|
1721
|
+
"watch passes the entire command string to sh -c, so pipes and redirects work, but quoting can be tricky",
|
|
1722
|
+
"The default interval is 2 seconds; intervals below 0.1s may cause excessive system load on resource-intensive commands",
|
|
1723
|
+
"watch -g (exit on change) is a GNU extension not available on macOS -- use brew install watch for GNU watch on macOS",
|
|
1724
|
+
],
|
|
1725
|
+
"related": ["sleep", "timeout", "top"],
|
|
1726
|
+
"difficulty": "beginner",
|
|
1727
|
+
"extra_flags": {
|
|
1728
|
+
"-g": "Exit when the output of the command changes",
|
|
1729
|
+
"-t": "Turn off the header showing interval, command, and current time",
|
|
1730
|
+
"-e": "Freeze on command error and exit on keypress",
|
|
1731
|
+
"-c": "Interpret ANSI color and style sequences",
|
|
1732
|
+
"-x": "Pass the command to exec instead of sh -c",
|
|
1733
|
+
},
|
|
1734
|
+
},
|
|
1735
|
+
|
|
1736
|
+
"history": {
|
|
1737
|
+
"man_url": "https://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html",
|
|
1738
|
+
"use_cases": [
|
|
1739
|
+
"Search command history: history | grep docker",
|
|
1740
|
+
"Re-execute the last command: !!",
|
|
1741
|
+
"Re-execute command number 42: !42",
|
|
1742
|
+
"Re-execute the most recent command starting with 'git': !git",
|
|
1743
|
+
"Delete a sensitive entry from history: history -d 42",
|
|
1744
|
+
"Prevent a command from being saved to history: prepend a space (requires HISTCONTROL=ignorespace)",
|
|
1745
|
+
],
|
|
1746
|
+
"gotchas": [
|
|
1747
|
+
"history -c clears the in-memory history but does not erase ~/.bash_history -- to fully clear, run history -c && history -w",
|
|
1748
|
+
"Commands prefixed with a space are not saved to history only if HISTCONTROL contains ignorespace or ignoreboth",
|
|
1749
|
+
"In multi-terminal sessions, history is written when the shell exits, so the last-to-close terminal's history wins unless you set shopt -s histappend",
|
|
1750
|
+
"!! and !n expansions are evaluated before the command runs -- pipe through echo first to see what will execute: echo !!",
|
|
1751
|
+
],
|
|
1752
|
+
"related": ["fc", "alias", "bash"],
|
|
1753
|
+
"difficulty": "beginner",
|
|
1754
|
+
"extra_flags": {
|
|
1755
|
+
"-a": "Append new history lines to the history file",
|
|
1756
|
+
"-r": "Read the history file and append its contents to the history list",
|
|
1757
|
+
"-w": "Write the current history list to the history file",
|
|
1758
|
+
"-d": "Delete a specific history entry by line number",
|
|
1759
|
+
"-p": "Perform history expansion and display the result without executing",
|
|
1760
|
+
},
|
|
1761
|
+
},
|
|
1762
|
+
|
|
1763
|
+
"alias": {
|
|
1764
|
+
"man_url": "https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html",
|
|
1765
|
+
"use_cases": [
|
|
1766
|
+
"Create a shortcut: alias ll='ls -la'",
|
|
1767
|
+
"Shorten a git command: alias gs='git status'",
|
|
1768
|
+
"Override a dangerous command with safety: alias rm='rm -i'",
|
|
1769
|
+
"List all defined aliases: alias",
|
|
1770
|
+
"Make aliases persistent by adding them to ~/.bashrc or ~/.bash_aliases",
|
|
1771
|
+
],
|
|
1772
|
+
"gotchas": [
|
|
1773
|
+
"Aliases defined in a terminal session are lost when the shell exits -- add them to ~/.bashrc or ~/.bash_aliases to persist",
|
|
1774
|
+
"Aliases are not expanded in shell scripts by default (only interactive shells) -- use functions instead for script portability",
|
|
1775
|
+
"Aliasing a command to itself with flags (alias ls='ls --color') works, but complex logic should use a shell function instead",
|
|
1776
|
+
"unalias name removes an alias; unalias -a removes all aliases in the current session",
|
|
1777
|
+
],
|
|
1778
|
+
"related": ["unalias", "history", "function"],
|
|
1779
|
+
"difficulty": "beginner",
|
|
1780
|
+
"extra_flags": {
|
|
1781
|
+
"-p": "Print all defined aliases in a reusable format",
|
|
1782
|
+
},
|
|
1783
|
+
},
|
|
1784
|
+
|
|
1785
|
+
"test": {
|
|
1786
|
+
"man_url": "https://man7.org/linux/man-pages/man1/test.1.html",
|
|
1787
|
+
"use_cases": [
|
|
1788
|
+
"Check if a file exists: test -f /etc/passwd && echo 'exists'",
|
|
1789
|
+
"Check if a directory exists: test -d /tmp && echo 'is a directory'",
|
|
1790
|
+
"Compare two numbers: test $count -gt 10 && echo 'more than 10'",
|
|
1791
|
+
"Check if a string is non-empty: test -n \"$var\" && echo 'has value'",
|
|
1792
|
+
"Use bracket syntax in scripts: [ -f file.txt ] && cat file.txt",
|
|
1793
|
+
],
|
|
1794
|
+
"gotchas": [
|
|
1795
|
+
"[ is an alias for test and requires a closing ] -- forgetting the space before ] causes syntax errors",
|
|
1796
|
+
"Always quote variables in test expressions: [ -f \"$file\" ] -- unquoted variables with spaces or empty values cause errors",
|
|
1797
|
+
"test uses -eq, -ne, -lt, -gt for numeric comparison and =, != for string comparison -- mixing them gives wrong results",
|
|
1798
|
+
"Prefer [[ ]] in bash scripts over [ ] -- it handles quoting better, supports regex with =~, and does not require escaping && and ||",
|
|
1799
|
+
],
|
|
1800
|
+
"related": ["[", "[[", "if"],
|
|
1801
|
+
"difficulty": "beginner",
|
|
1802
|
+
"extra_flags": {
|
|
1803
|
+
"-s": "File exists and has size greater than zero",
|
|
1804
|
+
"-L": "File exists and is a symbolic link",
|
|
1805
|
+
"-eq": "Integer equal comparison",
|
|
1806
|
+
"-ne": "Integer not equal comparison",
|
|
1807
|
+
"-lt": "Integer less than comparison",
|
|
1808
|
+
"-gt": "Integer greater than comparison",
|
|
1809
|
+
"-le": "Integer less than or equal",
|
|
1810
|
+
"-ge": "Integer greater than or equal",
|
|
1811
|
+
"-a": "Logical AND (deprecated; use && with [[ ]] instead)",
|
|
1812
|
+
"-o": "Logical OR (deprecated; use || with [[ ]] instead)",
|
|
1813
|
+
},
|
|
1814
|
+
},
|
|
1815
|
+
|
|
1816
|
+
"read": {
|
|
1817
|
+
"man_url": "https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html",
|
|
1818
|
+
"use_cases": [
|
|
1819
|
+
"Prompt user for input: read -p 'Enter your name: ' name",
|
|
1820
|
+
"Read a password without echoing: read -s -p 'Password: ' password",
|
|
1821
|
+
"Read with a timeout: read -t 5 -p 'Quick! Enter value: ' val",
|
|
1822
|
+
"Read a file line by line: while IFS= read -r line; do echo \"$line\"; done < file.txt",
|
|
1823
|
+
"Split input into multiple variables: read first last <<< 'John Doe'",
|
|
1824
|
+
],
|
|
1825
|
+
"gotchas": [
|
|
1826
|
+
"Always use -r to prevent backslash interpretation -- without it, read treats backslash as an escape character and eats them",
|
|
1827
|
+
"read splits input on IFS (whitespace by default) -- set IFS= before read to preserve leading/trailing whitespace and read the entire line",
|
|
1828
|
+
"read in a pipeline runs in a subshell, so variables set by read are lost after the pipeline ends -- use process substitution or while loop with redirection instead",
|
|
1829
|
+
"read -t (timeout) returns non-zero if the timeout expires -- check the exit code to distinguish timeout from empty input",
|
|
1830
|
+
],
|
|
1831
|
+
"related": ["echo", "printf", "select"],
|
|
1832
|
+
"difficulty": "intermediate",
|
|
1833
|
+
"extra_flags": {
|
|
1834
|
+
"-a": "Read words into an array variable",
|
|
1835
|
+
"-d": "Use specified delimiter instead of newline",
|
|
1836
|
+
"-n": "Read exactly N characters without waiting for Enter",
|
|
1837
|
+
"-N": "Read exactly N characters (ignore delimiter)",
|
|
1838
|
+
"-u": "Read from file descriptor instead of stdin",
|
|
1839
|
+
"-e": "Use readline for input (enables line editing)",
|
|
1840
|
+
"-i": "Use specified text as initial input (with -e only)",
|
|
1841
|
+
},
|
|
1842
|
+
},
|
|
1843
|
+
|
|
1844
|
+
"seq": {
|
|
1845
|
+
"man_url": "https://man7.org/linux/man-pages/man1/seq.1.html",
|
|
1846
|
+
"use_cases": [
|
|
1847
|
+
"Generate numbers from 1 to 10: seq 10",
|
|
1848
|
+
"Generate a range with step: seq 0 2 20",
|
|
1849
|
+
"Generate zero-padded numbers: seq -w 01 10",
|
|
1850
|
+
"Use a custom separator: seq -s ', ' 5",
|
|
1851
|
+
"Use in a for loop: for i in $(seq 1 5); do echo $i; done",
|
|
1852
|
+
],
|
|
1853
|
+
"gotchas": [
|
|
1854
|
+
"seq is not POSIX -- for portability in scripts, use: for i in $(( ... )) or bash brace expansion {1..10}",
|
|
1855
|
+
"seq handles floating point numbers: seq 0.1 0.1 1.0 -- but rounding errors can cause unexpected results",
|
|
1856
|
+
"Brace expansion {1..10} is expanded at parse time and cannot use variables; seq can: seq 1 $n",
|
|
1857
|
+
],
|
|
1858
|
+
"related": ["for", "while", "printf"],
|
|
1859
|
+
"difficulty": "beginner",
|
|
1860
|
+
"extra_flags": {
|
|
1861
|
+
"-f": "Use printf-style format for output numbers",
|
|
1862
|
+
},
|
|
1863
|
+
},
|
|
1864
|
+
|
|
1865
|
+
"stat": {
|
|
1866
|
+
"man_url": "https://man7.org/linux/man-pages/man1/stat.1.html",
|
|
1867
|
+
"use_cases": [
|
|
1868
|
+
"Show all metadata for a file: stat file.txt",
|
|
1869
|
+
"Display file permissions in octal: stat -c '%a %n' file.txt",
|
|
1870
|
+
"Show file size in bytes: stat -c '%s' file.txt",
|
|
1871
|
+
"Get the last modification time: stat -c '%y' file.txt",
|
|
1872
|
+
"Script-friendly output of multiple files: stat -c '%a %U %s %n' *",
|
|
1873
|
+
],
|
|
1874
|
+
"gotchas": [
|
|
1875
|
+
"stat format strings differ between GNU/Linux (-c '%a') and macOS/BSD (-f '%A') -- scripts that use stat are not portable without checking the OS first",
|
|
1876
|
+
"stat shows inode metadata, which reflects the file on disk -- recently written data in buffers may not be reflected until flushed",
|
|
1877
|
+
],
|
|
1878
|
+
"related": ["file", "ls", "find"],
|
|
1879
|
+
"difficulty": "intermediate",
|
|
1880
|
+
"extra_flags": {
|
|
1881
|
+
"-c": "Use specified format string (GNU/Linux)",
|
|
1882
|
+
"-f": "Display filesystem status instead of file status",
|
|
1883
|
+
"--printf": "Like -c but interpret backslash escapes and no trailing newline",
|
|
1884
|
+
"-L": "Follow symbolic links and report the target's status",
|
|
1885
|
+
"-t": "Print information in terse (machine-readable) form",
|
|
1886
|
+
},
|
|
1887
|
+
},
|
|
1888
|
+
|
|
1889
|
+
"file": {
|
|
1890
|
+
"man_url": "https://man7.org/linux/man-pages/man1/file.1.html",
|
|
1891
|
+
"use_cases": [
|
|
1892
|
+
"Determine the type of a file: file mystery_file",
|
|
1893
|
+
"Check all files in a directory: file *",
|
|
1894
|
+
"Get the MIME type for a web server: file -i document.pdf",
|
|
1895
|
+
"Check if a file is a text file or binary: file script.sh",
|
|
1896
|
+
"Identify encoding of a text file: file -i textfile.txt",
|
|
1897
|
+
],
|
|
1898
|
+
"gotchas": [
|
|
1899
|
+
"file examines file content, not the extension -- renaming a .jpg to .txt will still identify it as an image",
|
|
1900
|
+
"file uses magic number databases (/usr/share/misc/magic or /usr/share/file/magic) -- results may vary between systems with different magic databases",
|
|
1901
|
+
"file -i returns MIME types with charset info (e.g., text/plain; charset=utf-8), while -I is used on macOS for the same purpose",
|
|
1902
|
+
],
|
|
1903
|
+
"related": ["stat", "ls", "find", "strings"],
|
|
1904
|
+
"difficulty": "beginner",
|
|
1905
|
+
"extra_flags": {
|
|
1906
|
+
"-z": "Look inside compressed files",
|
|
1907
|
+
"-L": "Follow symbolic links",
|
|
1908
|
+
"-s": "Read block or character special files",
|
|
1909
|
+
"-k": "Keep going after the first match (show all matches)",
|
|
1910
|
+
"--mime-type": "Output only the MIME type without charset",
|
|
1911
|
+
},
|
|
1912
|
+
},
|
|
1913
|
+
|
|
1914
|
+
"less": {
|
|
1915
|
+
"man_url": "https://man7.org/linux/man-pages/man1/less.1.html",
|
|
1916
|
+
"use_cases": [
|
|
1917
|
+
"View a file with scrolling: less file.txt",
|
|
1918
|
+
"View command output with paging: command | less",
|
|
1919
|
+
"Search for a pattern while viewing: /pattern then n for next match",
|
|
1920
|
+
"View a log file and follow new output: less +F logfile.log (press Ctrl+C to stop, F to resume)",
|
|
1921
|
+
"View a file with line numbers: less -N file.txt",
|
|
1922
|
+
],
|
|
1923
|
+
"gotchas": [
|
|
1924
|
+
"less is not cat -- do not use 'cat file | less'; use 'less file' directly for proper seeking and performance",
|
|
1925
|
+
"less +F is similar to tail -f but lets you switch back to scrolling with Ctrl+C -- then press F to resume following",
|
|
1926
|
+
"Use -R or --RAW-CONTROL-CHARS to properly display colored output (e.g., from grep --color) in less",
|
|
1927
|
+
"Type q to quit, / to search forward, ? to search backward, g to go to beginning, G to go to end",
|
|
1928
|
+
],
|
|
1929
|
+
"related": ["more", "cat", "head", "tail"],
|
|
1930
|
+
"difficulty": "beginner",
|
|
1931
|
+
"extra_flags": {
|
|
1932
|
+
"+F": "Follow mode (like tail -f, but interactive)",
|
|
1933
|
+
"-X": "Do not clear the screen when exiting",
|
|
1934
|
+
"-F": "Exit immediately if content fits one screen",
|
|
1935
|
+
"-i": "Case-insensitive search",
|
|
1936
|
+
"-I": "Case-insensitive search even for uppercase patterns",
|
|
1937
|
+
"-g": "Highlight only the current search match",
|
|
1938
|
+
"-J": "Display a status column at the left edge",
|
|
1939
|
+
"--follow-name": "Follow by filename, not file descriptor",
|
|
1940
|
+
},
|
|
1941
|
+
},
|
|
1942
|
+
|
|
1943
|
+
"more": {
|
|
1944
|
+
"man_url": "https://man7.org/linux/man-pages/man1/more.1.html",
|
|
1945
|
+
"use_cases": [
|
|
1946
|
+
"View a file one page at a time: more file.txt",
|
|
1947
|
+
"View command output paged: command | more",
|
|
1948
|
+
],
|
|
1949
|
+
"gotchas": [
|
|
1950
|
+
"more only scrolls forward, not backward -- use less for bidirectional scrolling and better features",
|
|
1951
|
+
"On modern systems, more is often a symlink to less or a minimal implementation -- less is almost always the better choice",
|
|
1952
|
+
],
|
|
1953
|
+
"related": ["less", "cat", "head", "tail"],
|
|
1954
|
+
"difficulty": "beginner",
|
|
1955
|
+
"extra_flags": {
|
|
1956
|
+
"-d": "Display user-friendly prompts instead of ringing the bell",
|
|
1957
|
+
"-s": "Squeeze multiple blank lines into one",
|
|
1958
|
+
"+/pattern": "Start displaying at the first occurrence of pattern",
|
|
1959
|
+
"-num": "Set the screen size to num lines",
|
|
1960
|
+
},
|
|
1961
|
+
},
|
|
1962
|
+
|
|
1963
|
+
"clear": {
|
|
1964
|
+
"man_url": "https://man7.org/linux/man-pages/man1/clear.1.html",
|
|
1965
|
+
"use_cases": [
|
|
1966
|
+
"Clear the terminal screen: clear",
|
|
1967
|
+
"Clear the screen in a script: clear (or use printf '\\033[2J\\033[H')",
|
|
1968
|
+
],
|
|
1969
|
+
"gotchas": [
|
|
1970
|
+
"clear does not erase scrollback history in most terminals -- use clear -x or Ctrl+L for just visual clearing, or reset for a full terminal reset",
|
|
1971
|
+
"Ctrl+L is a keyboard shortcut that does the same thing as clear in most shells and is faster to type",
|
|
1972
|
+
],
|
|
1973
|
+
"related": ["reset", "tput"],
|
|
1974
|
+
"difficulty": "beginner",
|
|
1975
|
+
"extra_flags": {
|
|
1976
|
+
"-x": "Do not attempt to clear the terminal scrollback buffer",
|
|
1977
|
+
},
|
|
1978
|
+
},
|
|
1979
|
+
|
|
1980
|
+
"man": {
|
|
1981
|
+
"man_url": "https://man7.org/linux/man-pages/man1/man.1.html",
|
|
1982
|
+
"use_cases": [
|
|
1983
|
+
"View the manual page for a command: man ls",
|
|
1984
|
+
"Search for commands by keyword: man -k compress",
|
|
1985
|
+
"View a specific section of the manual: man 5 crontab",
|
|
1986
|
+
"View the manual for a C library function: man 3 printf",
|
|
1987
|
+
"Display the location of a man page: man -w ls",
|
|
1988
|
+
],
|
|
1989
|
+
"gotchas": [
|
|
1990
|
+
"Manual sections matter: man printf shows the shell command, while man 3 printf shows the C library function -- specify the section when ambiguous",
|
|
1991
|
+
"man -k (or apropos) searches the whatis database which may need to be rebuilt with mandb or makewhatis",
|
|
1992
|
+
"man uses your PAGER environment variable (usually less) -- set PAGER=less or MANPAGER=less for consistent behavior",
|
|
1993
|
+
"Some commands (bash builtins like cd, export) do not have standalone man pages -- use help cd or man bash and search within",
|
|
1994
|
+
],
|
|
1995
|
+
"related": ["info", "help", "apropos", "whatis"],
|
|
1996
|
+
"difficulty": "beginner",
|
|
1997
|
+
"extra_flags": {
|
|
1998
|
+
"-k": "Search manual page descriptions for a keyword (equivalent to apropos)",
|
|
1999
|
+
"-f": "Display a short description of a command (equivalent to whatis)",
|
|
2000
|
+
"-a": "Display all matching manual pages, not just the first",
|
|
2001
|
+
"-w": "Display the location of the man page file",
|
|
2002
|
+
"-K": "Search all man pages for a string (slow but thorough)",
|
|
2003
|
+
},
|
|
2004
|
+
},
|
|
2005
|
+
|
|
2006
|
+
"cal": {
|
|
2007
|
+
"man_url": "https://man7.org/linux/man-pages/man1/cal.1.html",
|
|
2008
|
+
"use_cases": [
|
|
2009
|
+
"Display the current month: cal",
|
|
2010
|
+
"Display the whole year: cal -y",
|
|
2011
|
+
"Show 3 months (previous, current, next): cal -3",
|
|
2012
|
+
"Display a specific month and year: cal 12 2025",
|
|
2013
|
+
"Show week numbers: cal -w",
|
|
2014
|
+
],
|
|
2015
|
+
"gotchas": [
|
|
2016
|
+
"cal 2024 shows the entire year 2024, not the calendar for the year 2024 BC -- this is rarely an issue but worth noting for scripts",
|
|
2017
|
+
"cal starts weeks on Sunday by default in the US locale; use ncal or set locale to change the start day",
|
|
2018
|
+
"cal output width is fixed and may not align properly in narrow terminal windows",
|
|
2019
|
+
],
|
|
2020
|
+
"related": ["date", "ncal"],
|
|
2021
|
+
"difficulty": "beginner",
|
|
2022
|
+
"extra_flags": {
|
|
2023
|
+
"-j": "Display Julian day numbers (day of year)",
|
|
2024
|
+
"-m": "Start the week on Monday",
|
|
2025
|
+
"-w": "Display ISO week numbers",
|
|
2026
|
+
},
|
|
2027
|
+
},
|
|
2028
|
+
|
|
2029
|
+
"yes": {
|
|
2030
|
+
"man_url": "https://man7.org/linux/man-pages/man1/yes.1.html",
|
|
2031
|
+
"use_cases": [
|
|
2032
|
+
"Auto-confirm prompts: yes | apt-get install package-name",
|
|
2033
|
+
"Auto-decline prompts: yes n | rm -i *",
|
|
2034
|
+
"Generate repeated output for testing: yes 'test line' | head -1000",
|
|
2035
|
+
"Stress test output handling: yes > /dev/null &",
|
|
2036
|
+
],
|
|
2037
|
+
"gotchas": [
|
|
2038
|
+
"yes runs forever until killed or its output pipe closes -- always pipe it to a command or use Ctrl+C to stop",
|
|
2039
|
+
"Most package managers have their own -y flag (apt -y, yum -y) which is safer and more explicit than piping yes",
|
|
2040
|
+
"yes outputs at maximum speed and can spike CPU usage -- do not run it unpiped as a background process",
|
|
2041
|
+
],
|
|
2042
|
+
"related": ["true", "false", "echo"],
|
|
2043
|
+
"difficulty": "beginner",
|
|
2044
|
+
"extra_flags": {},
|
|
2045
|
+
},
|
|
2046
|
+
|
|
2047
|
+
"whoami": {
|
|
2048
|
+
"man_url": "https://man7.org/linux/man-pages/man1/whoami.1.html",
|
|
2049
|
+
"use_cases": [
|
|
2050
|
+
"Check which user you are logged in as: whoami",
|
|
2051
|
+
"Guard a script against running as root: [ $(whoami) = 'root' ] && echo 'Do not run as root' && exit 1",
|
|
2052
|
+
"Include username in log messages: echo \"$(whoami) ran this script at $(date)\"",
|
|
2053
|
+
],
|
|
2054
|
+
"gotchas": [
|
|
2055
|
+
"whoami prints the effective user, which may differ from the login user if you used sudo or su -- use logname for the original login name",
|
|
2056
|
+
"In containers, whoami usually returns root unless a USER directive was set in the Dockerfile",
|
|
2057
|
+
],
|
|
2058
|
+
"related": ["id", "who", "logname"],
|
|
2059
|
+
"difficulty": "beginner",
|
|
2060
|
+
"extra_flags": {},
|
|
2061
|
+
},
|
|
2062
|
+
|
|
2063
|
+
"hostname": {
|
|
2064
|
+
"man_url": "https://man7.org/linux/man-pages/man1/hostname.1.html",
|
|
2065
|
+
"use_cases": [
|
|
2066
|
+
"Display the system hostname: hostname",
|
|
2067
|
+
"Display the fully qualified domain name: hostname -f",
|
|
2068
|
+
"Display all IP addresses of the host: hostname -I",
|
|
2069
|
+
"Use hostname in a script for per-server behavior: case $(hostname) in web*) start_nginx;; db*) start_postgres;; esac",
|
|
2070
|
+
],
|
|
2071
|
+
"gotchas": [
|
|
2072
|
+
"Setting the hostname with 'hostname newname' is temporary and resets on reboot -- use hostnamectl set-hostname on systemd systems for persistence",
|
|
2073
|
+
"hostname -I (capital I) shows all IPs without DNS lookup; hostname -i (lowercase) does a DNS lookup and may fail if DNS is misconfigured",
|
|
2074
|
+
"In containers, hostname returns the container ID by default unless explicitly set",
|
|
2075
|
+
],
|
|
2076
|
+
"related": ["hostnamectl", "uname", "whoami"],
|
|
2077
|
+
"difficulty": "beginner",
|
|
2078
|
+
"extra_flags": {},
|
|
2079
|
+
},
|
|
2080
|
+
|
|
2081
|
+
"uname": {
|
|
2082
|
+
"man_url": "https://man7.org/linux/man-pages/man1/uname.1.html",
|
|
2083
|
+
"use_cases": [
|
|
2084
|
+
"Show all system information: uname -a",
|
|
2085
|
+
"Get the kernel version: uname -r",
|
|
2086
|
+
"Detect the CPU architecture for cross-compilation: uname -m",
|
|
2087
|
+
"Check if running on Linux vs macOS in a script: case $(uname -s) in Linux) echo linux;; Darwin) echo mac;; esac",
|
|
2088
|
+
],
|
|
2089
|
+
"gotchas": [
|
|
2090
|
+
"uname -m returns the kernel architecture, not necessarily the userspace -- a 64-bit kernel can run a 32-bit userspace",
|
|
2091
|
+
"On WSL, uname -r returns a Linux kernel version but the actual host is Windows -- check for 'microsoft' in uname -r to detect WSL",
|
|
2092
|
+
],
|
|
2093
|
+
"related": ["hostname", "lsb_release", "hostnamectl"],
|
|
2094
|
+
"difficulty": "beginner",
|
|
2095
|
+
"extra_flags": {
|
|
2096
|
+
"-o": "Print the operating system name",
|
|
2097
|
+
"-p": "Print the processor type (or 'unknown')",
|
|
2098
|
+
},
|
|
2099
|
+
},
|
|
2100
|
+
|
|
2101
|
+
"uptime": {
|
|
2102
|
+
"man_url": "https://man7.org/linux/man-pages/man1/uptime.1.html",
|
|
2103
|
+
"use_cases": [
|
|
2104
|
+
"Check how long the system has been running: uptime",
|
|
2105
|
+
"Get human-readable uptime duration: uptime -p",
|
|
2106
|
+
"See when the system was last booted: uptime -s",
|
|
2107
|
+
"Check load averages for monitoring: uptime | awk '{print $NF}'",
|
|
2108
|
+
],
|
|
2109
|
+
"gotchas": [
|
|
2110
|
+
"Load averages are 1-min, 5-min, and 15-min averages of processes in runnable or uninterruptible state -- they are NOT CPU percentages and scale with the number of cores",
|
|
2111
|
+
"A load average equal to the number of CPU cores means the system is fully utilized; above that means processes are waiting",
|
|
2112
|
+
],
|
|
2113
|
+
"related": ["free", "top", "w"],
|
|
2114
|
+
"difficulty": "beginner",
|
|
2115
|
+
"extra_flags": {},
|
|
2116
|
+
},
|
|
2117
|
+
|
|
2118
|
+
"free": {
|
|
2119
|
+
"man_url": "https://man7.org/linux/man-pages/man1/free.1.html",
|
|
2120
|
+
"use_cases": [
|
|
2121
|
+
"Display memory usage in human-readable format: free -h",
|
|
2122
|
+
"Show memory usage in megabytes: free -m",
|
|
2123
|
+
"Continuously monitor memory every 5 seconds: free -h -s 5",
|
|
2124
|
+
"Show total line combining RAM and swap: free -h -t",
|
|
2125
|
+
],
|
|
2126
|
+
"gotchas": [
|
|
2127
|
+
"The 'available' column (not 'free') is what matters for new processes -- Linux uses free memory for caches, so 'free' will be low even on healthy systems",
|
|
2128
|
+
"The 'buff/cache' memory is automatically released when applications need it -- a system with low 'free' but high 'available' is healthy",
|
|
2129
|
+
"free shows swap usage which can indicate memory pressure -- if swap is heavily used, the system is likely thrashing",
|
|
2130
|
+
],
|
|
2131
|
+
"related": ["top", "htop", "vmstat", "uptime"],
|
|
2132
|
+
"difficulty": "beginner",
|
|
2133
|
+
"extra_flags": {
|
|
2134
|
+
"-w": "Wide output (separate buffers and cache columns)",
|
|
2135
|
+
"-l": "Show detailed low and high memory statistics",
|
|
2136
|
+
"--si": "Use powers of 1000 instead of 1024",
|
|
2137
|
+
},
|
|
2138
|
+
},
|
|
2139
|
+
|
|
2140
|
+
"env": {
|
|
2141
|
+
"man_url": "https://man7.org/linux/man-pages/man1/env.1.html",
|
|
2142
|
+
"use_cases": [
|
|
2143
|
+
"Display all environment variables: env",
|
|
2144
|
+
"Filter environment variables: env | grep PATH",
|
|
2145
|
+
"Run a command with a modified environment: env VAR=value command",
|
|
2146
|
+
"Run a command with a clean environment: env -i /bin/bash",
|
|
2147
|
+
"Set environment for a single command without affecting current shell: env LANG=C sort file.txt",
|
|
2148
|
+
],
|
|
2149
|
+
"gotchas": [
|
|
2150
|
+
"env -i starts with an empty environment, which can break most commands since PATH, HOME, and other critical variables are unset",
|
|
2151
|
+
"env is commonly used in shebang lines (#!/usr/bin/env python3) to find commands in PATH regardless of installation location",
|
|
2152
|
+
"env shows exported variables only, not shell-local variables -- use set to see all variables",
|
|
2153
|
+
],
|
|
2154
|
+
"related": ["export", "printenv", "set"],
|
|
2155
|
+
"difficulty": "beginner",
|
|
2156
|
+
"extra_flags": {
|
|
2157
|
+
"-0": "Null-terminate output lines (for use with xargs -0)",
|
|
2158
|
+
"-u": "Remove a variable from the environment for the command",
|
|
2159
|
+
"-S": "Split a single string into arguments (useful in shebangs)",
|
|
2160
|
+
},
|
|
2161
|
+
},
|
|
2162
|
+
|
|
2163
|
+
"export": {
|
|
2164
|
+
"man_url": "https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html",
|
|
2165
|
+
"use_cases": [
|
|
2166
|
+
"Make a variable available to child processes: export PATH=$PATH:/usr/local/bin",
|
|
2167
|
+
"Set an environment variable for a session: export NODE_ENV=production",
|
|
2168
|
+
"Export a variable at definition time: export DATABASE_URL='postgres://localhost/mydb'",
|
|
2169
|
+
"List all exported variables: export -p",
|
|
2170
|
+
"Un-export a variable (remove from environment): export -n MYVAR",
|
|
2171
|
+
],
|
|
2172
|
+
"gotchas": [
|
|
2173
|
+
"export only affects child processes started AFTER the export -- already-running processes do not see the change",
|
|
2174
|
+
"Variables set in a script without export are local to that script and invisible to commands it calls",
|
|
2175
|
+
"export in a subshell or child process does not affect the parent shell -- modifications are lost when the subshell exits",
|
|
2176
|
+
"To persist environment variables across sessions, add export statements to ~/.bashrc, ~/.bash_profile, or ~/.profile",
|
|
2177
|
+
],
|
|
2178
|
+
"related": ["env", "set", "unset", "source"],
|
|
2179
|
+
"difficulty": "beginner",
|
|
2180
|
+
"extra_flags": {
|
|
2181
|
+
"-f": "Export a shell function, not a variable",
|
|
2182
|
+
},
|
|
2183
|
+
},
|
|
2184
|
+
|
|
2185
|
+
}
|