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,2016 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enrichment data for Text Processing, Search/Navigation, and Development commands.
|
|
3
|
+
|
|
4
|
+
This module provides supplemental fields (use_cases, gotchas, man_url, related,
|
|
5
|
+
difficulty, extra_flags) for thin entries in the COMMAND_DB knowledge base.
|
|
6
|
+
|
|
7
|
+
Sources consulted:
|
|
8
|
+
- man7.org Linux man-pages
|
|
9
|
+
- GNU Coreutils documentation (gnu.org)
|
|
10
|
+
- Official project documentation (gcc.gnu.org, docs.docker.com, kubernetes.io, etc.)
|
|
11
|
+
- GitHub project pages for modern CLI tools (fzf, fd, ripgrep, exa, etc.)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
ENRICHMENT_DATA = {
|
|
15
|
+
# =========================================================================
|
|
16
|
+
# TEXT PROCESSING
|
|
17
|
+
# =========================================================================
|
|
18
|
+
"paste": {
|
|
19
|
+
"man_url": "https://man7.org/linux/man-pages/man1/paste.1.html",
|
|
20
|
+
"use_cases": [
|
|
21
|
+
"Merge two column files side by side with paste file1.txt file2.txt to create a combined table",
|
|
22
|
+
"Convert a single-column list into a comma-separated line with paste -sd',' file.txt",
|
|
23
|
+
"Interleave lines from stdin into columns with seq 6 | paste - - - to create 3-column output",
|
|
24
|
+
],
|
|
25
|
+
"gotchas": [
|
|
26
|
+
"The default delimiter is TAB, which may not be visible -- use -d to set an explicit delimiter if you need commas or other separators",
|
|
27
|
+
"The -s flag fundamentally changes behavior from parallel merging (side by side) to serial (one file at a time concatenated horizontally) -- confusing these modes produces unexpected output",
|
|
28
|
+
"When using - for stdin, each - consumes successive lines, so paste - - reads two lines at a time into two columns",
|
|
29
|
+
],
|
|
30
|
+
"related": ["join", "column", "pr", "cut"],
|
|
31
|
+
"difficulty": "intermediate",
|
|
32
|
+
"extra_flags": {
|
|
33
|
+
"-z": "Use NUL as line delimiter instead of newline",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
"join": {
|
|
37
|
+
"man_url": "https://man7.org/linux/man-pages/man1/join.1.html",
|
|
38
|
+
"use_cases": [
|
|
39
|
+
"Perform a relational join of two CSV files on a shared key with join -t',' file1.csv file2.csv",
|
|
40
|
+
"Find unmatched lines between two sorted files with join -v 1 sorted1.txt sorted2.txt",
|
|
41
|
+
"Join files on a non-first field with join -1 2 -2 3 file1.txt file2.txt",
|
|
42
|
+
],
|
|
43
|
+
"gotchas": [
|
|
44
|
+
"Both input files MUST be sorted on the join field before running join -- unsorted input silently produces wrong results rather than an error",
|
|
45
|
+
"By default join matches on the first field with whitespace as separator -- use -t to set the actual delimiter for CSV or TSV data",
|
|
46
|
+
"Lines that do not match are silently dropped unless you use -a or -v to include unpaired lines from one or both files",
|
|
47
|
+
],
|
|
48
|
+
"related": ["paste", "comm", "sort", "awk"],
|
|
49
|
+
"difficulty": "intermediate",
|
|
50
|
+
"extra_flags": {
|
|
51
|
+
"-a": "Also print unpairable lines from the specified file (1 or 2)",
|
|
52
|
+
"-e": "Replace missing input fields with this string",
|
|
53
|
+
"-i": "Ignore case when comparing join fields",
|
|
54
|
+
"-v": "Print only unpairable lines from the specified file",
|
|
55
|
+
"-o": "Specify output format using FILENUM.FIELD notation",
|
|
56
|
+
"-1": "Join on this field of file 1",
|
|
57
|
+
"-2": "Join on this field of file 2",
|
|
58
|
+
"--header": "Treat first line of each file as a header",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
"comm": {
|
|
62
|
+
"man_url": "https://man7.org/linux/man-pages/man1/comm.1.html",
|
|
63
|
+
"use_cases": [
|
|
64
|
+
"Find lines common to two sorted files with comm -12 file1.txt file2.txt",
|
|
65
|
+
"Find lines unique to the first file with comm -23 file1.txt file2.txt for set-difference operations",
|
|
66
|
+
"Compare two sorted package lists to find newly installed packages with comm -13 old_pkgs.txt new_pkgs.txt",
|
|
67
|
+
],
|
|
68
|
+
"gotchas": [
|
|
69
|
+
"Both files MUST be sorted -- comm on unsorted files produces garbage output without any warning",
|
|
70
|
+
"The three columns are: lines only in file1, lines only in file2, lines in both -- the -1 -2 -3 flags SUPPRESS columns, so -12 shows column 3 (common lines)",
|
|
71
|
+
"Column numbering is unintuitive: -12 does not mean columns 1 and 2, it means suppress columns 1 and 2, showing only column 3",
|
|
72
|
+
],
|
|
73
|
+
"related": ["diff", "join", "sort", "uniq"],
|
|
74
|
+
"difficulty": "intermediate",
|
|
75
|
+
"extra_flags": {
|
|
76
|
+
"--check-order": "Check that input is correctly sorted",
|
|
77
|
+
"--nocheck-order": "Do not check input sort order",
|
|
78
|
+
"--output-delimiter": "Separate columns with this string",
|
|
79
|
+
"-z": "Use NUL as line delimiter instead of newline",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
"csplit": {
|
|
83
|
+
"man_url": "https://man7.org/linux/man-pages/man1/csplit.1.html",
|
|
84
|
+
"use_cases": [
|
|
85
|
+
"Split a log file at each date header with csplit access.log '/^2024-/' '{*}'",
|
|
86
|
+
"Split a document at chapter markers with csplit book.txt '/^Chapter/' '{*}'",
|
|
87
|
+
"Extract the section between two patterns by splitting at both boundaries",
|
|
88
|
+
],
|
|
89
|
+
"gotchas": [
|
|
90
|
+
"Without -k, if a pattern is not found csplit removes ALL output files it already created -- use -k to keep partial results on error",
|
|
91
|
+
"The '{*}' repeat specifier means repeat as many times as possible -- without it csplit only splits at the first match",
|
|
92
|
+
"Output files are named xx00, xx01, etc. by default -- use -f to set a meaningful prefix and -n to control digit count",
|
|
93
|
+
],
|
|
94
|
+
"related": ["split", "awk", "grep", "sed"],
|
|
95
|
+
"difficulty": "intermediate",
|
|
96
|
+
"extra_flags": {
|
|
97
|
+
"-b": "Use sprintf-style suffix format instead of default %02d",
|
|
98
|
+
"--suppress-matched": "Suppress the lines matching the pattern in output",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
"split": {
|
|
102
|
+
"man_url": "https://man7.org/linux/man-pages/man1/split.1.html",
|
|
103
|
+
"use_cases": [
|
|
104
|
+
"Break a large CSV file into manageable chunks with split -l 10000 data.csv chunk_ for parallel processing",
|
|
105
|
+
"Split a large backup file into pieces that fit on removable media with split -b 4G backup.tar part_",
|
|
106
|
+
"Create numbered output files with split -d -l 500 log.txt log_ for easier sorting",
|
|
107
|
+
],
|
|
108
|
+
"gotchas": [
|
|
109
|
+
"Output files are named xaa, xab, etc. by default -- use a PREFIX argument and -d for numeric suffixes to get readable names",
|
|
110
|
+
"split does not add headers to subsequent chunks -- when splitting CSV files, the header row only appears in the first piece",
|
|
111
|
+
"The -n flag splits into N equal-sized pieces but can split mid-line unless you use -n l/N for line-boundary splits",
|
|
112
|
+
],
|
|
113
|
+
"related": ["csplit", "cat", "head", "tail"],
|
|
114
|
+
"difficulty": "beginner",
|
|
115
|
+
"extra_flags": {
|
|
116
|
+
"-n": "Split into N chunks (use l/N for line-aligned chunks)",
|
|
117
|
+
"-a": "Set the length of the generated suffix (default 2)",
|
|
118
|
+
"--filter": "Write to a shell command instead of files",
|
|
119
|
+
"--additional-suffix": "Append an extra suffix to output filenames",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
"column": {
|
|
123
|
+
"man_url": "https://man7.org/linux/man-pages/man1/column.1.html",
|
|
124
|
+
"use_cases": [
|
|
125
|
+
"Format command output into a clean table with mount | column -t",
|
|
126
|
+
"Display CSV data as an aligned table with column -t -s',' data.csv",
|
|
127
|
+
"Create readable side-by-side output from tab-delimited data for reports",
|
|
128
|
+
],
|
|
129
|
+
"gotchas": [
|
|
130
|
+
"The -s flag sets the INPUT separator, not the output separator -- the output is always space-padded for alignment",
|
|
131
|
+
"On older Linux systems (util-linux < 2.30), column -t does not support -s with multi-character separators -- only single character delimiters work",
|
|
132
|
+
"The newer util-linux column supports -N for named headers and -J for JSON output, but these are not available on macOS or older systems",
|
|
133
|
+
],
|
|
134
|
+
"related": ["paste", "pr", "printf", "awk"],
|
|
135
|
+
"difficulty": "beginner",
|
|
136
|
+
"extra_flags": {
|
|
137
|
+
"-o": "Set output separator string (util-linux 2.30+)",
|
|
138
|
+
"-N": "Set comma-separated list of column names for headers",
|
|
139
|
+
"-J": "Output as JSON with column names from -N",
|
|
140
|
+
"-c": "Set output width in characters",
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
"rev": {
|
|
144
|
+
"man_url": "https://man7.org/linux/man-pages/man1/rev.1.html",
|
|
145
|
+
"use_cases": [
|
|
146
|
+
"Reverse each line to extract file extensions with rev | cut -d. -f1 | rev",
|
|
147
|
+
"Check for palindromes in a word list by comparing input with reversed output",
|
|
148
|
+
"Get the last field of a variable-length delimited line when you cannot predict field count",
|
|
149
|
+
],
|
|
150
|
+
"gotchas": [
|
|
151
|
+
"rev reverses characters within each line, not the order of lines -- use tac to reverse line order",
|
|
152
|
+
"Multi-byte UTF-8 characters may not reverse correctly on all implementations -- test with your locale",
|
|
153
|
+
],
|
|
154
|
+
"related": ["tac", "cut", "awk"],
|
|
155
|
+
"difficulty": "beginner",
|
|
156
|
+
"extra_flags": {},
|
|
157
|
+
},
|
|
158
|
+
"shuf": {
|
|
159
|
+
"man_url": "https://man7.org/linux/man-pages/man1/shuf.1.html",
|
|
160
|
+
"use_cases": [
|
|
161
|
+
"Select a random line from a file with shuf -n 1 quotes.txt for random quote display",
|
|
162
|
+
"Randomize the order of a playlist or test data with shuf playlist.m3u > shuffled.m3u",
|
|
163
|
+
"Generate random numbers in a range with shuf -i 1-100 -n 10 for sampling",
|
|
164
|
+
],
|
|
165
|
+
"gotchas": [
|
|
166
|
+
"shuf loads the entire input into memory -- for very large files this can exhaust RAM",
|
|
167
|
+
"The randomness comes from /dev/urandom by default -- for reproducible shuffles use --random-source with a fixed seed file",
|
|
168
|
+
],
|
|
169
|
+
"related": ["sort", "head", "seq"],
|
|
170
|
+
"difficulty": "beginner",
|
|
171
|
+
"extra_flags": {
|
|
172
|
+
"-i": "Generate integers from LO to HI range instead of reading input",
|
|
173
|
+
"-o": "Write output to a file instead of stdout",
|
|
174
|
+
"-r": "Allow output lines to repeat (sample with replacement)",
|
|
175
|
+
"-z": "Use NUL as line delimiter instead of newline",
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
"nl": {
|
|
179
|
+
"man_url": "https://man7.org/linux/man-pages/man1/nl.1.html",
|
|
180
|
+
"use_cases": [
|
|
181
|
+
"Number all lines including blanks with nl -ba script.sh for code review",
|
|
182
|
+
"Add right-justified zero-padded line numbers with nl -nrz -w4 file.txt",
|
|
183
|
+
"Number only lines matching a pattern with nl -bp'^function' file.sh",
|
|
184
|
+
],
|
|
185
|
+
"gotchas": [
|
|
186
|
+
"By default nl only numbers non-empty lines (style t) -- use -ba to number ALL lines including blanks",
|
|
187
|
+
"nl treats lines starting with \\:\\:\\: as page section delimiters (header/body/footer) which can cause unexpected behavior if your data contains these patterns",
|
|
188
|
+
"Line numbers reset at each logical page by default -- use -p to prevent renumbering across sections",
|
|
189
|
+
],
|
|
190
|
+
"related": ["cat", "pr", "grep"],
|
|
191
|
+
"difficulty": "beginner",
|
|
192
|
+
"extra_flags": {
|
|
193
|
+
"-n": "Number format: ln (left justified), rn (right justified), rz (right justified with zeros)",
|
|
194
|
+
"-w": "Set number width (default 6)",
|
|
195
|
+
"-s": "Set separator string between number and line (default TAB)",
|
|
196
|
+
"-i": "Line number increment (default 1)",
|
|
197
|
+
"-v": "Starting line number (default 1)",
|
|
198
|
+
"-p": "Do not reset line numbers at logical page boundaries",
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
"fold": {
|
|
202
|
+
"man_url": "https://man7.org/linux/man-pages/man1/fold.1.html",
|
|
203
|
+
"use_cases": [
|
|
204
|
+
"Wrap long lines for terminal display with fold -s -w 80 readme.txt",
|
|
205
|
+
"Prepare text for systems with fixed line-length limits like email with fold -w 76",
|
|
206
|
+
"Break base64-encoded data into fixed-width lines with fold -w 76 encoded.txt",
|
|
207
|
+
],
|
|
208
|
+
"gotchas": [
|
|
209
|
+
"Without -s, fold breaks lines at the exact column count even mid-word -- always use -s for human-readable text to break at spaces",
|
|
210
|
+
"fold counts display columns by default, not bytes -- use -b for byte counting which matters for multi-byte encodings",
|
|
211
|
+
"Unlike fmt, fold does not join short lines or reflow paragraphs -- it only breaks long lines",
|
|
212
|
+
],
|
|
213
|
+
"related": ["fmt", "pr", "column"],
|
|
214
|
+
"difficulty": "beginner",
|
|
215
|
+
"extra_flags": {},
|
|
216
|
+
},
|
|
217
|
+
"fmt": {
|
|
218
|
+
"man_url": "https://man7.org/linux/man-pages/man1/fmt.1.html",
|
|
219
|
+
"use_cases": [
|
|
220
|
+
"Reflow a paragraph to 72 columns for email formatting with fmt -w 72 message.txt",
|
|
221
|
+
"Clean up ragged text from copy-paste with fmt -u file.txt for uniform spacing",
|
|
222
|
+
"Wrap only long lines without joining short ones with fmt -s -w 80 code_comments.txt",
|
|
223
|
+
],
|
|
224
|
+
"gotchas": [
|
|
225
|
+
"fmt joins short lines into paragraphs by default -- use -s if you only want to split long lines without merging short ones",
|
|
226
|
+
"Indented lines are treated as paragraph boundaries, so fmt preserves code indentation but may reflow comments unexpectedly",
|
|
227
|
+
"The default width is 75, not 80 -- explicitly set -w 80 if you want standard terminal width",
|
|
228
|
+
],
|
|
229
|
+
"related": ["fold", "pr", "par"],
|
|
230
|
+
"difficulty": "beginner",
|
|
231
|
+
"extra_flags": {
|
|
232
|
+
"-p": "Only reformat lines starting with this prefix string",
|
|
233
|
+
"-t": "Indent like the first line, subsequent lines like the second",
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
"pr": {
|
|
237
|
+
"man_url": "https://man7.org/linux/man-pages/man1/pr.1.html",
|
|
238
|
+
"use_cases": [
|
|
239
|
+
"Add headers and page numbers to a file for printing with pr -h 'Report' data.txt | lpr",
|
|
240
|
+
"Display two files side by side with pr -m -t file1.txt file2.txt for comparison",
|
|
241
|
+
"Format output into multiple columns with pr -3 -t wordlist.txt",
|
|
242
|
+
],
|
|
243
|
+
"gotchas": [
|
|
244
|
+
"By default pr adds 5-line headers and trailers on each page -- use -t to suppress them for pipeline use",
|
|
245
|
+
"The default page length is 66 lines (standard US letter at 6 lines/inch) -- adjust with -l for other formats",
|
|
246
|
+
"pr paginates output with form feeds -- pipe to head or less if you want continuous output",
|
|
247
|
+
],
|
|
248
|
+
"related": ["column", "nl", "fmt", "fold"],
|
|
249
|
+
"difficulty": "intermediate",
|
|
250
|
+
"extra_flags": {
|
|
251
|
+
"-t": "Suppress headers and trailers",
|
|
252
|
+
"-T": "Suppress headers, trailers, and form feeds",
|
|
253
|
+
"-W": "Set page width including margin (overrides -w)",
|
|
254
|
+
"-J": "Merge full lines, overriding -W truncation",
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
"expand": {
|
|
258
|
+
"man_url": "https://man7.org/linux/man-pages/man1/expand.1.html",
|
|
259
|
+
"use_cases": [
|
|
260
|
+
"Convert tabs to 4 spaces for consistent indentation with expand -t 4 file.c > file_spaces.c",
|
|
261
|
+
"Normalize mixed tab/space files before diffing with expand -t 4 file.txt",
|
|
262
|
+
"Convert only leading tabs (preserve alignment tabs) with expand -i -t 4 source.py",
|
|
263
|
+
],
|
|
264
|
+
"gotchas": [
|
|
265
|
+
"The default tab stop is 8, not 4 -- always specify -t with your project's indentation width",
|
|
266
|
+
"expand processes all tabs by default including those inside strings -- use -i to limit conversion to leading whitespace only",
|
|
267
|
+
"Pipe through expand before diff to avoid false differences caused by mixed tabs and spaces",
|
|
268
|
+
],
|
|
269
|
+
"related": ["unexpand", "sed", "tr"],
|
|
270
|
+
"difficulty": "beginner",
|
|
271
|
+
"extra_flags": {},
|
|
272
|
+
},
|
|
273
|
+
"unexpand": {
|
|
274
|
+
"man_url": "https://man7.org/linux/man-pages/man1/unexpand.1.html",
|
|
275
|
+
"use_cases": [
|
|
276
|
+
"Convert spaces to tabs for Makefiles that require tab indentation with unexpand -t 4 --first-only file",
|
|
277
|
+
"Reduce file size of heavily indented files by converting space runs to tabs",
|
|
278
|
+
"Convert all space sequences (not just leading) with unexpand -a -t 4 file.txt",
|
|
279
|
+
],
|
|
280
|
+
"gotchas": [
|
|
281
|
+
"By default unexpand only converts leading spaces to tabs -- use -a to convert all sequences of spaces",
|
|
282
|
+
"Makefiles REQUIRE literal tab characters for recipe lines -- unexpand can help fix spaces-only Makefiles",
|
|
283
|
+
"The tab stop must match the original indentation width or the conversion will misalign content",
|
|
284
|
+
],
|
|
285
|
+
"related": ["expand", "sed", "tr"],
|
|
286
|
+
"difficulty": "beginner",
|
|
287
|
+
"extra_flags": {},
|
|
288
|
+
},
|
|
289
|
+
"od": {
|
|
290
|
+
"man_url": "https://man7.org/linux/man-pages/man1/od.1.html",
|
|
291
|
+
"use_cases": [
|
|
292
|
+
"Debug encoding issues by viewing raw bytes with od -c file.txt to see newline types (\\r\\n vs \\n)",
|
|
293
|
+
"Inspect binary file headers to identify file format with od -A x -t x1z -N 32 mystery_file",
|
|
294
|
+
"Examine network packet captures at the byte level for protocol debugging",
|
|
295
|
+
],
|
|
296
|
+
"gotchas": [
|
|
297
|
+
"od collapses repeated identical lines with an asterisk (*) by default -- this hides data in repetitive binary files",
|
|
298
|
+
"The default output format is octal, which is rarely what you want -- use -t x1 for hex bytes or -c for character display",
|
|
299
|
+
"od uses the system byte order for multi-byte formats -- -t x2 shows 2-byte hex in host endianness which may confuse cross-platform work",
|
|
300
|
+
],
|
|
301
|
+
"related": ["hexdump", "xxd", "strings"],
|
|
302
|
+
"difficulty": "intermediate",
|
|
303
|
+
"extra_flags": {
|
|
304
|
+
"-j": "Skip this many bytes from the beginning of input",
|
|
305
|
+
"-v": "Display all data without collapsing duplicate lines",
|
|
306
|
+
"-w": "Set output width in bytes per line",
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
"hexdump": {
|
|
310
|
+
"man_url": "https://man7.org/linux/man-pages/man1/hexdump.1.html",
|
|
311
|
+
"use_cases": [
|
|
312
|
+
"View binary files with the canonical hex+ASCII display with hexdump -C file.bin",
|
|
313
|
+
"Inspect the first 512 bytes of a disk for boot sector analysis with hexdump -C -n 512 /dev/sda",
|
|
314
|
+
"Debug character encoding by checking actual byte values with echo -n 'text' | hexdump -C",
|
|
315
|
+
],
|
|
316
|
+
"gotchas": [
|
|
317
|
+
"Without -v, hexdump suppresses duplicate lines with asterisks -- use -v to see all data",
|
|
318
|
+
"hexdump without -C shows little-endian 16-bit words which reverses byte pairs -- always use -C for byte-level inspection",
|
|
319
|
+
"The -e flag for custom format strings uses a confusing printf-like syntax that differs from standard printf",
|
|
320
|
+
],
|
|
321
|
+
"related": ["xxd", "od", "strings"],
|
|
322
|
+
"difficulty": "intermediate",
|
|
323
|
+
"extra_flags": {
|
|
324
|
+
"-e": "Specify custom format string for output",
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
"xxd": {
|
|
328
|
+
"man_url": "https://man7.org/linux/man-pages/man1/xxd.1.html",
|
|
329
|
+
"use_cases": [
|
|
330
|
+
"Create a hex dump for inclusion in C source with xxd -i data.bin > data.h",
|
|
331
|
+
"Patch a binary file by editing hex then converting back with xxd file | edit | xxd -r > patched",
|
|
332
|
+
"Get a plain hex string of a file with xxd -p file.bin for checksums or embedding",
|
|
333
|
+
],
|
|
334
|
+
"gotchas": [
|
|
335
|
+
"xxd -r requires the EXACT same format that xxd produces -- manually edited hex dumps must preserve the offset column format",
|
|
336
|
+
"The -r flag reads hex dump from stdin, not a file argument -- pipe or redirect your edited dump",
|
|
337
|
+
"xxd is bundled with vim, not coreutils -- it may not be available on minimal systems without vim installed",
|
|
338
|
+
],
|
|
339
|
+
"related": ["hexdump", "od", "vim"],
|
|
340
|
+
"difficulty": "intermediate",
|
|
341
|
+
"extra_flags": {},
|
|
342
|
+
},
|
|
343
|
+
"strings": {
|
|
344
|
+
"man_url": "https://man7.org/linux/man-pages/man1/strings.1.html",
|
|
345
|
+
"use_cases": [
|
|
346
|
+
"Find embedded URLs or file paths in a compiled binary with strings binary | grep -i 'http'",
|
|
347
|
+
"Identify the compiler and libraries used to build an executable with strings program | grep -i gcc",
|
|
348
|
+
"Extract readable text from a corrupted document or firmware image for forensic analysis",
|
|
349
|
+
],
|
|
350
|
+
"gotchas": [
|
|
351
|
+
"strings only shows sequences of 4+ printable characters by default -- short strings like 2-character error codes are hidden unless you lower -n",
|
|
352
|
+
"strings may show misleading output from random byte sequences that happen to look like text -- not every match is meaningful",
|
|
353
|
+
"On ELF binaries, strings only scans loadable sections by default -- use -a to scan the entire file including debug sections",
|
|
354
|
+
],
|
|
355
|
+
"related": ["od", "hexdump", "file", "readelf"],
|
|
356
|
+
"difficulty": "beginner",
|
|
357
|
+
"extra_flags": {
|
|
358
|
+
"-e": "Select character encoding (s=7-bit, S=8-bit, b=16-bit big-endian, l=16-bit little-endian)",
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
"tac": {
|
|
362
|
+
"man_url": "https://man7.org/linux/man-pages/man1/tac.1.html",
|
|
363
|
+
"use_cases": [
|
|
364
|
+
"View log files with newest entries first with tac /var/log/syslog | head -20",
|
|
365
|
+
"Reverse the order of lines in a file for bottom-up processing with tac input.txt > reversed.txt",
|
|
366
|
+
"Process records separated by blank lines in reverse with tac -s '' data.txt",
|
|
367
|
+
],
|
|
368
|
+
"gotchas": [
|
|
369
|
+
"tac reverses LINE ORDER, not characters within lines -- use rev to reverse characters",
|
|
370
|
+
"tac reads the entire file into memory for processing -- for very large files consider tail -r on BSD or other approaches",
|
|
371
|
+
"tac is a GNU coreutils command not available on macOS by default -- install via brew install coreutils and use gtac",
|
|
372
|
+
],
|
|
373
|
+
"related": ["rev", "tail", "sort", "head"],
|
|
374
|
+
"difficulty": "beginner",
|
|
375
|
+
"extra_flags": {
|
|
376
|
+
"-b": "Attach separator before instead of after each record",
|
|
377
|
+
"-r": "Interpret separator as a regular expression",
|
|
378
|
+
"-s": "Use STRING as the record separator instead of newline",
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
|
|
382
|
+
# =========================================================================
|
|
383
|
+
# SEARCH & NAVIGATION
|
|
384
|
+
# =========================================================================
|
|
385
|
+
"locate": {
|
|
386
|
+
"man_url": "https://man7.org/linux/man-pages/man1/locate.1.html",
|
|
387
|
+
"use_cases": [
|
|
388
|
+
"Instantly find a configuration file by name with locate nginx.conf instead of slow find /",
|
|
389
|
+
"Count how many Python files exist system-wide with locate -c '*.py'",
|
|
390
|
+
"Find recently installed binaries after updating the database with sudo updatedb && locate new_tool",
|
|
391
|
+
],
|
|
392
|
+
"gotchas": [
|
|
393
|
+
"The database is updated periodically (usually daily via cron) -- recently created files will not appear until you run sudo updatedb",
|
|
394
|
+
"locate shows ALL matches including deleted files still in the database -- verify results exist with locate -e",
|
|
395
|
+
"On modern systems mlocate or plocate may be installed instead of the original locate -- they are CLI-compatible but use different database formats",
|
|
396
|
+
],
|
|
397
|
+
"related": ["find", "updatedb", "mlocate", "plocate", "fd"],
|
|
398
|
+
"difficulty": "beginner",
|
|
399
|
+
"extra_flags": {
|
|
400
|
+
"-e": "Print only entries for files that currently exist on disk",
|
|
401
|
+
"-b": "Match only against the basename, not the full path",
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
"ag": {
|
|
405
|
+
"man_url": "https://github.com/ggreer/the_silver_searcher",
|
|
406
|
+
"use_cases": [
|
|
407
|
+
"Search a codebase for a function definition with ag 'def process_data' --python",
|
|
408
|
+
"Find TODO comments across a project with ag TODO --ignore-dir=node_modules",
|
|
409
|
+
"Search for a pattern only in specific file types with ag -G '\\.jsx?$' 'useState'",
|
|
410
|
+
],
|
|
411
|
+
"gotchas": [
|
|
412
|
+
"ag respects .gitignore by default -- files ignored by git will not appear in search results unless you use -u (unrestricted)",
|
|
413
|
+
"ag uses PCRE regex by default, not basic regex -- metacharacters like ( and | work without escaping unlike grep",
|
|
414
|
+
"ag has been largely superseded by ripgrep (rg) which is faster in most benchmarks -- consider rg for new workflows",
|
|
415
|
+
],
|
|
416
|
+
"related": ["rg", "grep", "ack", "fzf"],
|
|
417
|
+
"difficulty": "beginner",
|
|
418
|
+
"extra_flags": {
|
|
419
|
+
"-u": "Search all files, ignoring .gitignore and .ignore rules",
|
|
420
|
+
"-U": "Search all files including binary files",
|
|
421
|
+
"--stats": "Print stats about matches at the end",
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
"rg": {
|
|
425
|
+
"man_url": "https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md",
|
|
426
|
+
"use_cases": [
|
|
427
|
+
"Search for a pattern in only Python files with rg -t py 'import requests'",
|
|
428
|
+
"Find all TODO and FIXME comments with rg -i 'todo|fixme' --glob '!vendor/'",
|
|
429
|
+
"Search with context lines for code review with rg -C 3 'panic!' src/",
|
|
430
|
+
"List only files containing matches for piping to other tools with rg -l 'deprecated' | xargs sed -i 's/deprecated/new_api/g'",
|
|
431
|
+
],
|
|
432
|
+
"gotchas": [
|
|
433
|
+
"rg skips .gitignore-listed files, hidden files, and binary files by default -- use --no-ignore --hidden -a to search everything",
|
|
434
|
+
"rg uses Rust regex syntax which does not support backreferences or lookahead -- for those patterns use grep -P or ag instead",
|
|
435
|
+
"The -t flag uses built-in type definitions (rg --type-list to see them) -- custom file extensions need --glob or --type-add",
|
|
436
|
+
"rg returns exit code 1 when no matches are found, which can break set -e scripts -- handle it explicitly",
|
|
437
|
+
],
|
|
438
|
+
"related": ["grep", "ag", "ack", "fd", "fzf"],
|
|
439
|
+
"difficulty": "beginner",
|
|
440
|
+
"extra_flags": {
|
|
441
|
+
"-M": "Set max line length to display (suppress very long lines)",
|
|
442
|
+
"--json": "Output results in JSON format for programmatic consumption",
|
|
443
|
+
"-U": "Enable multiline matching across line boundaries",
|
|
444
|
+
"-S": "Smart case: case-insensitive if all lowercase, sensitive if any uppercase",
|
|
445
|
+
"-e": "Specify multiple patterns (each with its own -e flag)",
|
|
446
|
+
"--sort": "Sort results by path, modified time, accessed time, or created time",
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
"ripgrep": {
|
|
450
|
+
"man_url": "https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md",
|
|
451
|
+
"use_cases": [
|
|
452
|
+
"Search for a pattern in only Python files with rg -t py 'import requests'",
|
|
453
|
+
"Find all TODO and FIXME comments with rg -i 'todo|fixme' --glob '!vendor/'",
|
|
454
|
+
"List only files containing matches with rg -l 'deprecated' for batch processing",
|
|
455
|
+
],
|
|
456
|
+
"gotchas": [
|
|
457
|
+
"ripgrep skips .gitignore-listed files, hidden files, and binary files by default -- use --no-ignore --hidden to override",
|
|
458
|
+
"ripgrep uses Rust regex syntax which does not support backreferences or lookahead",
|
|
459
|
+
"Typically invoked as rg, not ripgrep -- the binary name is rg",
|
|
460
|
+
],
|
|
461
|
+
"related": ["grep", "ag", "ack", "fd"],
|
|
462
|
+
"difficulty": "beginner",
|
|
463
|
+
"extra_flags": {},
|
|
464
|
+
},
|
|
465
|
+
"ack": {
|
|
466
|
+
"man_url": "https://beyondgrep.com/documentation/",
|
|
467
|
+
"use_cases": [
|
|
468
|
+
"Search only in Python files with ack --python 'class.*Model'",
|
|
469
|
+
"Find all files of a specific type with ack -f --perl to list Perl source files",
|
|
470
|
+
"Search for a literal string containing regex metacharacters with ack -Q 'array[0]'",
|
|
471
|
+
],
|
|
472
|
+
"gotchas": [
|
|
473
|
+
"ack uses Perl-compatible regex by default -- regex like \\d, \\w, and lookahead work out of the box",
|
|
474
|
+
"ack is slower than ripgrep (rg) for large codebases -- it remains useful for its Perl regex support and --type system",
|
|
475
|
+
"ack ignores backup files, core dumps, and VCS directories by default -- use --noignore-directory to override",
|
|
476
|
+
],
|
|
477
|
+
"related": ["rg", "ag", "grep", "fzf"],
|
|
478
|
+
"difficulty": "beginner",
|
|
479
|
+
"extra_flags": {
|
|
480
|
+
"-f": "List all files that would be searched (no pattern required)",
|
|
481
|
+
"--sort-files": "Sort output by filename",
|
|
482
|
+
"--color-match": "Set the color for matched text",
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
"fzf": {
|
|
486
|
+
"man_url": "https://github.com/junegunn/fzf",
|
|
487
|
+
"use_cases": [
|
|
488
|
+
"Open a file in your editor with interactive search with vim $(fzf --preview 'head -50 {}')",
|
|
489
|
+
"Interactively search and checkout a git branch with git checkout $(git branch | fzf)",
|
|
490
|
+
"Kill a process interactively with kill -9 $(ps aux | fzf | awk '{print $2}')",
|
|
491
|
+
"Search command history with Ctrl+R integration (enabled via fzf --bash or fzf --zsh setup)",
|
|
492
|
+
],
|
|
493
|
+
"gotchas": [
|
|
494
|
+
"fzf reads from stdin by default -- if no input is piped, it uses a file finder (find or fd) which may be slow on large directory trees",
|
|
495
|
+
"Key bindings (Ctrl+R, Ctrl+T, Alt+C) require shell integration setup -- run eval \"$(fzf --bash)\" in your .bashrc",
|
|
496
|
+
"fzf returns exit code 130 when the user presses Escape to cancel -- handle this in scripts with || true",
|
|
497
|
+
"The FZF_DEFAULT_COMMAND environment variable controls what command generates the file list -- set it to fd or rg --files for better performance",
|
|
498
|
+
],
|
|
499
|
+
"related": ["fd", "rg", "find", "grep"],
|
|
500
|
+
"difficulty": "intermediate",
|
|
501
|
+
"extra_flags": {
|
|
502
|
+
"--bind": "Set custom key bindings for actions within fzf",
|
|
503
|
+
"--header": "Display a fixed header line above the match list",
|
|
504
|
+
"--delimiter": "Set field delimiter for --with-nth and --nth",
|
|
505
|
+
"--nth": "Restrict matching to specific fields",
|
|
506
|
+
"--tac": "Reverse input order",
|
|
507
|
+
"--no-sort": "Do not sort the results",
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
"fd": {
|
|
511
|
+
"man_url": "https://github.com/sharkdp/fd",
|
|
512
|
+
"use_cases": [
|
|
513
|
+
"Find all Python files in a project with fd -e py",
|
|
514
|
+
"Find and delete all .DS_Store files with fd -H '.DS_Store' -x rm",
|
|
515
|
+
"Find large files with fd -e log -x ls -lh {} to inspect file sizes",
|
|
516
|
+
"Find recently modified files with fd --changed-within 1d",
|
|
517
|
+
],
|
|
518
|
+
"gotchas": [
|
|
519
|
+
"fd ignores .gitignore patterns and hidden files by default -- use -H for hidden files and -I to skip .gitignore filtering",
|
|
520
|
+
"fd uses regex patterns by default, not glob -- use -g to switch to glob matching for patterns like '*.py'",
|
|
521
|
+
"On some Linux distributions fd is installed as fdfind to avoid conflict with another package -- create an alias if needed",
|
|
522
|
+
],
|
|
523
|
+
"related": ["find", "fzf", "rg", "locate"],
|
|
524
|
+
"difficulty": "beginner",
|
|
525
|
+
"extra_flags": {
|
|
526
|
+
"--changed-within": "Filter to files modified within a time duration",
|
|
527
|
+
"--changed-before": "Filter to files modified before a time duration",
|
|
528
|
+
"--size": "Filter by file size (e.g., +1m for files over 1MB)",
|
|
529
|
+
"-0": "Separate results with NUL for xargs -0",
|
|
530
|
+
"-L": "Follow symbolic links",
|
|
531
|
+
"-p": "Match against the full path, not just the filename",
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
"exa": {
|
|
535
|
+
"man_url": "https://github.com/ogham/exa",
|
|
536
|
+
"use_cases": [
|
|
537
|
+
"List files with git status indicators with exa -la --git",
|
|
538
|
+
"View a directory tree with file sizes with exa -T -L 3 --icons -s size",
|
|
539
|
+
"List files sorted by modification time with exa -la -s modified --reverse",
|
|
540
|
+
],
|
|
541
|
+
"gotchas": [
|
|
542
|
+
"exa is no longer maintained as of 2023 -- the community fork eza is the actively maintained successor",
|
|
543
|
+
"The --icons flag requires a Nerd Font installed and configured in your terminal -- without it you get garbled characters",
|
|
544
|
+
"exa uses different flags than ls -- muscle memory for ls -ltr will not work (exa uses -s modified --reverse instead of -t -r)",
|
|
545
|
+
],
|
|
546
|
+
"related": ["ls", "lsd", "eza", "tree"],
|
|
547
|
+
"difficulty": "beginner",
|
|
548
|
+
"extra_flags": {
|
|
549
|
+
"-d": "List directories themselves, not their contents",
|
|
550
|
+
"--no-permissions": "Suppress the permissions column",
|
|
551
|
+
"--time-style": "Set time display format (default, iso, long-iso, full-iso)",
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
"lsd": {
|
|
555
|
+
"man_url": "https://github.com/lsd-rs/lsd",
|
|
556
|
+
"use_cases": [
|
|
557
|
+
"Get a visually rich directory listing with lsd -la for quick file inspection",
|
|
558
|
+
"View a colorful directory tree with lsd --tree --depth 2",
|
|
559
|
+
"Sort files by size to find large files with lsd -lS",
|
|
560
|
+
],
|
|
561
|
+
"gotchas": [
|
|
562
|
+
"lsd requires a Nerd Font for icons to render correctly -- without it icons appear as broken characters",
|
|
563
|
+
"lsd's flag compatibility with ls is intentional but not 100% -- some obscure ls flags may not work",
|
|
564
|
+
"Color output is on by default which can interfere with pipe processing -- use --color never for scripts",
|
|
565
|
+
],
|
|
566
|
+
"related": ["ls", "exa", "tree"],
|
|
567
|
+
"difficulty": "beginner",
|
|
568
|
+
"extra_flags": {
|
|
569
|
+
"--blocks": "Configure which metadata blocks to show",
|
|
570
|
+
"--date": "Set date format (date, relative, +format-string)",
|
|
571
|
+
"--group-directories-first": "List directories before files",
|
|
572
|
+
"--no-symlink": "Do not follow symbolic links",
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
"broot": {
|
|
576
|
+
"man_url": "https://dystroy.org/broot/",
|
|
577
|
+
"use_cases": [
|
|
578
|
+
"Explore a large codebase interactively by typing to fuzzy-filter the tree view",
|
|
579
|
+
"Find and navigate to deeply nested files without typing full paths",
|
|
580
|
+
"View disk usage in a tree with broot -w to identify large directories",
|
|
581
|
+
],
|
|
582
|
+
"gotchas": [
|
|
583
|
+
"broot requires a shell function (br) for cd-on-quit behavior -- run broot --install to set it up, then use br instead of broot",
|
|
584
|
+
"First launch creates a configuration file at ~/.config/broot/conf.hjson -- customize verbs and key bindings there",
|
|
585
|
+
"broot may appear unfamiliar at first -- type text to filter, use arrow keys to navigate, and press Enter to open or Alt+Enter to cd",
|
|
586
|
+
],
|
|
587
|
+
"related": ["tree", "ranger", "nnn", "fzf"],
|
|
588
|
+
"difficulty": "intermediate",
|
|
589
|
+
"extra_flags": {
|
|
590
|
+
"-g": "Show git status for files",
|
|
591
|
+
"--sort-by-date": "Sort entries by modification date",
|
|
592
|
+
"--sort-by-size": "Sort entries by size",
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
"ranger": {
|
|
596
|
+
"man_url": "https://github.com/ranger/ranger",
|
|
597
|
+
"use_cases": [
|
|
598
|
+
"Navigate and preview files visually in a three-column Miller layout",
|
|
599
|
+
"Perform bulk file operations (rename, move, copy) with vi keybindings",
|
|
600
|
+
"Preview images in terminal with ranger (requires w3m or ueberzug for image support)",
|
|
601
|
+
],
|
|
602
|
+
"gotchas": [
|
|
603
|
+
"ranger uses vi keybindings by default -- j/k to move, h to go up, l to enter directories",
|
|
604
|
+
"To cd to the last ranger directory on quit, you must use the shell function: add source ranger-cd to your shell config",
|
|
605
|
+
"ranger can be slow on very large directories because it stats every file for preview -- use nnn or lf for large directory trees",
|
|
606
|
+
],
|
|
607
|
+
"related": ["nnn", "mc", "lf", "broot"],
|
|
608
|
+
"difficulty": "intermediate",
|
|
609
|
+
"extra_flags": {
|
|
610
|
+
"--copy-config": "Create a copy of the default config files for customization",
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
"mc": {
|
|
614
|
+
"man_url": "https://midnight-commander.org/",
|
|
615
|
+
"use_cases": [
|
|
616
|
+
"Manage files across two directories simultaneously with a dual-pane view",
|
|
617
|
+
"Connect to remote servers via SFTP/FTP with mc's built-in virtual filesystem",
|
|
618
|
+
"Edit files with the built-in editor mcedit which supports syntax highlighting",
|
|
619
|
+
],
|
|
620
|
+
"gotchas": [
|
|
621
|
+
"mc captures the F-keys which may conflict with terminal or tmux key bindings -- use Esc+number as an alternative",
|
|
622
|
+
"mc's FTP/SFTP panel (accessed via cd sh://user@host) can be slow on high-latency connections",
|
|
623
|
+
"The mouse support can interfere with terminal copy-paste -- hold Shift while selecting to use the terminal's native selection",
|
|
624
|
+
],
|
|
625
|
+
"related": ["ranger", "nnn", "lf"],
|
|
626
|
+
"difficulty": "intermediate",
|
|
627
|
+
"extra_flags": {
|
|
628
|
+
"-s": "Run in slow terminal mode for better compatibility",
|
|
629
|
+
"-u": "Disable concurrent shell (use subshell only if needed)",
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
"nnn": {
|
|
633
|
+
"man_url": "https://github.com/jarun/nnn",
|
|
634
|
+
"use_cases": [
|
|
635
|
+
"Navigate large directory trees quickly with minimal resource usage",
|
|
636
|
+
"Use plugins for previewing files, opening in editors, or batch renaming with nnn -P preview",
|
|
637
|
+
"Select multiple files for batch operations with nnn -p /tmp/sel and process the selection file",
|
|
638
|
+
],
|
|
639
|
+
"gotchas": [
|
|
640
|
+
"nnn does not cd on quit by default -- you must configure the shell function (n) using the nnn-quitcd setup",
|
|
641
|
+
"nnn uses single-key shortcuts that are case-sensitive -- capital letters do different things than lowercase",
|
|
642
|
+
"nnn requires the NNN_PLUG environment variable to be set for plugins to work",
|
|
643
|
+
],
|
|
644
|
+
"related": ["ranger", "lf", "mc", "broot"],
|
|
645
|
+
"difficulty": "intermediate",
|
|
646
|
+
"extra_flags": {
|
|
647
|
+
"-c": "Set NNN_FCOLORS environment for 8-color scheme",
|
|
648
|
+
"-e": "Open text files in $VISUAL or $EDITOR on Enter",
|
|
649
|
+
"-o": "Open files with only a single click in navigation",
|
|
650
|
+
"-x": "Enable various system notifications and copy path to clipboard",
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
"lf": {
|
|
654
|
+
"man_url": "https://github.com/gokcehan/lf",
|
|
655
|
+
"use_cases": [
|
|
656
|
+
"Navigate files with a ranger-like interface but faster startup due to Go implementation",
|
|
657
|
+
"Configure custom file openers and previews through the lfrc configuration file",
|
|
658
|
+
"Use with fzf for fuzzy file search within the file manager",
|
|
659
|
+
],
|
|
660
|
+
"gotchas": [
|
|
661
|
+
"lf configuration uses its own command language, not shell script -- refer to lf -doc for syntax",
|
|
662
|
+
"Like nnn and ranger, cd-on-quit requires a shell wrapper function -- use the lfcd function from the documentation",
|
|
663
|
+
"lf defaults to a single-column view unlike ranger's three-column layout -- customize with set ratios",
|
|
664
|
+
],
|
|
665
|
+
"related": ["ranger", "nnn", "mc", "broot"],
|
|
666
|
+
"difficulty": "intermediate",
|
|
667
|
+
"extra_flags": {},
|
|
668
|
+
},
|
|
669
|
+
"apropos": {
|
|
670
|
+
"man_url": "https://man7.org/linux/man-pages/man1/apropos.1.html",
|
|
671
|
+
"use_cases": [
|
|
672
|
+
"Find commands related to a concept with apropos compress to discover compression tools",
|
|
673
|
+
"Search for disk-related commands with apropos partition to find fdisk, parted, etc.",
|
|
674
|
+
"Discover all commands in a specific man section with apropos -s 8 network for admin network tools",
|
|
675
|
+
],
|
|
676
|
+
"gotchas": [
|
|
677
|
+
"apropos searches the whatis database which must be built first -- run sudo mandb if you get no results",
|
|
678
|
+
"Results can be noisy -- use apropos -e for exact matches or combine with grep to narrow results",
|
|
679
|
+
"apropos is equivalent to man -k -- they use the same database and return the same results",
|
|
680
|
+
],
|
|
681
|
+
"related": ["whatis", "man", "info", "help"],
|
|
682
|
+
"difficulty": "beginner",
|
|
683
|
+
"extra_flags": {},
|
|
684
|
+
},
|
|
685
|
+
"whatis": {
|
|
686
|
+
"man_url": "https://man7.org/linux/man-pages/man1/whatis.1.html",
|
|
687
|
+
"use_cases": [
|
|
688
|
+
"Quickly check what a command does with whatis tar before reading the full man page",
|
|
689
|
+
"Get one-line descriptions of multiple commands at once with whatis ls cp mv rm",
|
|
690
|
+
"Verify which man page section a command belongs to with whatis printf to see both the shell builtin and C library versions",
|
|
691
|
+
],
|
|
692
|
+
"gotchas": [
|
|
693
|
+
"whatis requires the man database to be built -- if it returns nothing, run sudo mandb",
|
|
694
|
+
"whatis only shows exact name matches by default -- use apropos (man -k) for keyword searches across descriptions",
|
|
695
|
+
],
|
|
696
|
+
"related": ["apropos", "man", "help", "info"],
|
|
697
|
+
"difficulty": "beginner",
|
|
698
|
+
"extra_flags": {},
|
|
699
|
+
},
|
|
700
|
+
"help": {
|
|
701
|
+
"man_url": "https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html",
|
|
702
|
+
"use_cases": [
|
|
703
|
+
"Look up syntax for a shell builtin with help test or help [[ when man page is unavailable",
|
|
704
|
+
"Get a quick list of all builtins with help -d '*'",
|
|
705
|
+
"View man-page-style formatted help with help -m export",
|
|
706
|
+
],
|
|
707
|
+
"gotchas": [
|
|
708
|
+
"help only works for bash builtins -- external commands like grep or find need man instead",
|
|
709
|
+
"help is itself a builtin and is not available in sh or dash -- it is bash-specific",
|
|
710
|
+
"Some builtins have both a help entry and a man page -- the help version covers the bash-specific behavior",
|
|
711
|
+
],
|
|
712
|
+
"related": ["man", "whatis", "apropos", "info"],
|
|
713
|
+
"difficulty": "beginner",
|
|
714
|
+
"extra_flags": {},
|
|
715
|
+
},
|
|
716
|
+
"info": {
|
|
717
|
+
"man_url": "https://www.gnu.org/software/texinfo/manual/info-stnd/info-stnd.html",
|
|
718
|
+
"use_cases": [
|
|
719
|
+
"Read detailed GNU coreutils documentation with info coreutils for comprehensive examples",
|
|
720
|
+
"Navigate directly to a specific topic with info bash 'Shell Expansions'",
|
|
721
|
+
"Read info pages that contain more detail than their man page counterparts, especially for GNU tools",
|
|
722
|
+
],
|
|
723
|
+
"gotchas": [
|
|
724
|
+
"info uses Emacs-style navigation by default (Ctrl+F forward, Ctrl+B back, Tab for links) -- use --vi-keys for vi-style",
|
|
725
|
+
"Not all commands have info pages -- if no info page exists, info falls back to displaying the man page",
|
|
726
|
+
"The info reader is separate from man -- info coreutils has a full tutorial that man pages lack",
|
|
727
|
+
],
|
|
728
|
+
"related": ["man", "help", "whatis", "apropos"],
|
|
729
|
+
"difficulty": "beginner",
|
|
730
|
+
"extra_flags": {},
|
|
731
|
+
},
|
|
732
|
+
|
|
733
|
+
# =========================================================================
|
|
734
|
+
# DEVELOPMENT - BUILD SYSTEMS
|
|
735
|
+
# =========================================================================
|
|
736
|
+
"make": {
|
|
737
|
+
"man_url": "https://www.gnu.org/software/make/manual/make.html",
|
|
738
|
+
"use_cases": [
|
|
739
|
+
"Build a C project with make all or just make to run the default target",
|
|
740
|
+
"Clean build artifacts with make clean before a fresh rebuild",
|
|
741
|
+
"Run a parallel build on all cores with make -j$(nproc) for faster compilation",
|
|
742
|
+
"Perform a dry run to see what commands would execute with make -n before committing",
|
|
743
|
+
],
|
|
744
|
+
"gotchas": [
|
|
745
|
+
"Makefiles require actual TAB characters for recipe indentation -- spaces cause 'missing separator' errors and this is the single most common Makefile problem",
|
|
746
|
+
"Variables set on the command line (make VAR=val) override values set in the Makefile -- use override directive in the Makefile to prevent this",
|
|
747
|
+
"make -j without a number spawns unlimited parallel jobs which can overwhelm the system -- always specify a count like -j4 or -j$(nproc)",
|
|
748
|
+
"make only rebuilds targets whose dependencies have changed -- if timestamps are wrong (e.g., after a timezone change or git checkout), use make -B to force rebuild",
|
|
749
|
+
],
|
|
750
|
+
"related": ["cmake", "ninja", "gcc", "autoconf"],
|
|
751
|
+
"difficulty": "intermediate",
|
|
752
|
+
"extra_flags": {
|
|
753
|
+
"-B": "Unconditionally make all targets (force rebuild)",
|
|
754
|
+
"-C": "Change to directory before reading Makefile",
|
|
755
|
+
"-k": "Keep going when some targets cannot be made",
|
|
756
|
+
"-s": "Silent mode, do not echo recipes",
|
|
757
|
+
"-w": "Print working directory info (useful for recursive make)",
|
|
758
|
+
"-q": "Question mode: exit 0 if target is up to date, 1 if not",
|
|
759
|
+
"-p": "Print the database of rules and variables (debug)",
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
"cmake": {
|
|
763
|
+
"man_url": "https://cmake.org/cmake/help/latest/manual/cmake.1.html",
|
|
764
|
+
"use_cases": [
|
|
765
|
+
"Configure an out-of-source build with cmake -S . -B build to keep source tree clean",
|
|
766
|
+
"Build a release configuration with cmake -DCMAKE_BUILD_TYPE=Release -S . -B build",
|
|
767
|
+
"Build the project after configuration with cmake --build build -j$(nproc)",
|
|
768
|
+
"Install after building with cmake --install build --prefix /usr/local",
|
|
769
|
+
],
|
|
770
|
+
"gotchas": [
|
|
771
|
+
"CMake generates build files but does not build -- you need to run the generated build system (make, ninja) or use cmake --build",
|
|
772
|
+
"CMake caches variables in CMakeCache.txt -- if you change a -D option and it does not take effect, delete the cache or the build directory",
|
|
773
|
+
"The minimum CMake version in cmake_minimum_required affects available features -- old minimum versions may disable modern CMake features",
|
|
774
|
+
"Prefer cmake --build build over cd build && make because it works regardless of the generator (Make, Ninja, VS)",
|
|
775
|
+
],
|
|
776
|
+
"related": ["make", "ninja", "gcc", "clang"],
|
|
777
|
+
"difficulty": "intermediate",
|
|
778
|
+
"extra_flags": {
|
|
779
|
+
"--preset": "Use a named preset from CMakePresets.json",
|
|
780
|
+
"-Wdev": "Enable developer warnings",
|
|
781
|
+
"--fresh": "Configure a fresh build tree, removing any existing cache",
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
"ninja": {
|
|
785
|
+
"man_url": "https://ninja-build.org/manual.html",
|
|
786
|
+
"use_cases": [
|
|
787
|
+
"Build a CMake project faster by generating Ninja files with cmake -G Ninja -S . -B build && ninja -C build",
|
|
788
|
+
"Build with verbose output to debug compilation issues with ninja -v",
|
|
789
|
+
"Clean build artifacts with ninja -t clean",
|
|
790
|
+
],
|
|
791
|
+
"gotchas": [
|
|
792
|
+
"Ninja is not designed to be written by hand -- use CMake or Meson to generate build.ninja files",
|
|
793
|
+
"Ninja defaults to parallel builds using all available cores -- unlike make, you rarely need -j",
|
|
794
|
+
"Ninja does not support pattern rules or includes like Makefiles -- it is intentionally minimal and relies on a generator",
|
|
795
|
+
],
|
|
796
|
+
"related": ["cmake", "meson", "make"],
|
|
797
|
+
"difficulty": "intermediate",
|
|
798
|
+
"extra_flags": {},
|
|
799
|
+
},
|
|
800
|
+
"meson": {
|
|
801
|
+
"man_url": "https://mesonbuild.com/Reference-manual.html",
|
|
802
|
+
"use_cases": [
|
|
803
|
+
"Set up a new C/C++ project build with meson setup builddir",
|
|
804
|
+
"Create a release build with meson setup --buildtype=release builddir",
|
|
805
|
+
"Run project tests after building with meson test -C builddir",
|
|
806
|
+
],
|
|
807
|
+
"gotchas": [
|
|
808
|
+
"Meson requires a separate build directory -- in-source builds are not supported",
|
|
809
|
+
"Meson uses Python-like syntax in meson.build files but is not actually Python -- it is a custom DSL",
|
|
810
|
+
"Build options can only be changed with meson configure, not by editing the build directory -- regenerate with meson setup --reconfigure if needed",
|
|
811
|
+
],
|
|
812
|
+
"related": ["ninja", "cmake", "make"],
|
|
813
|
+
"difficulty": "intermediate",
|
|
814
|
+
"extra_flags": {
|
|
815
|
+
"--reconfigure": "Regenerate build configuration without clearing the build directory",
|
|
816
|
+
"--wipe": "Clear the build directory and reconfigure from scratch",
|
|
817
|
+
},
|
|
818
|
+
},
|
|
819
|
+
"autoconf": {
|
|
820
|
+
"man_url": "https://www.gnu.org/software/autoconf/manual/autoconf.html",
|
|
821
|
+
"use_cases": [
|
|
822
|
+
"Generate a configure script from configure.ac with autoreconf --install",
|
|
823
|
+
"Regenerate all autotools files after modifying configure.ac with autoreconf -fiv",
|
|
824
|
+
"Create a portable build system for distributable open-source packages",
|
|
825
|
+
],
|
|
826
|
+
"gotchas": [
|
|
827
|
+
"autoconf is typically used through autoreconf which runs autoconf, automake, aclocal, and other tools in the correct order",
|
|
828
|
+
"configure.ac uses M4 macro language which has unusual quoting rules -- use [ ] for quoting, not single or double quotes",
|
|
829
|
+
"The autotools toolchain (autoconf + automake + libtool) has a steep learning curve -- CMake or Meson are simpler alternatives for new projects",
|
|
830
|
+
],
|
|
831
|
+
"related": ["automake", "make", "cmake", "meson"],
|
|
832
|
+
"difficulty": "advanced",
|
|
833
|
+
"extra_flags": {},
|
|
834
|
+
},
|
|
835
|
+
"automake": {
|
|
836
|
+
"man_url": "https://www.gnu.org/software/automake/manual/automake.html",
|
|
837
|
+
"use_cases": [
|
|
838
|
+
"Generate Makefile.in templates from Makefile.am files with automake --add-missing",
|
|
839
|
+
"Set up the standard GNU build system with aclocal && automake --add-missing && autoconf",
|
|
840
|
+
"Create a distribution tarball with make dist after automake setup",
|
|
841
|
+
],
|
|
842
|
+
"gotchas": [
|
|
843
|
+
"Makefile.am files use a special syntax that is not regular Makefile syntax -- variables like bin_PROGRAMS and _SOURCES follow automake naming conventions",
|
|
844
|
+
"automake --foreign relaxes GNU strictness requirements -- without it, automake expects NEWS, README, AUTHORS, ChangeLog files to exist",
|
|
845
|
+
"automake must be run after aclocal and before autoconf -- the order matters and is why autoreconf exists",
|
|
846
|
+
],
|
|
847
|
+
"related": ["autoconf", "make", "cmake"],
|
|
848
|
+
"difficulty": "advanced",
|
|
849
|
+
"extra_flags": {},
|
|
850
|
+
},
|
|
851
|
+
|
|
852
|
+
# =========================================================================
|
|
853
|
+
# DEVELOPMENT - COMPILERS & LINKERS
|
|
854
|
+
# =========================================================================
|
|
855
|
+
"gcc": {
|
|
856
|
+
"man_url": "https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html",
|
|
857
|
+
"use_cases": [
|
|
858
|
+
"Compile a C program with warnings and debug info with gcc -Wall -Wextra -g -o program main.c",
|
|
859
|
+
"Build an optimized release binary with gcc -O2 -o fast_program main.c",
|
|
860
|
+
"Compile multiple source files and link with a library with gcc -o app main.c utils.c -lm -lpthread",
|
|
861
|
+
"Generate only the object file for later linking with gcc -c -o module.o module.c",
|
|
862
|
+
],
|
|
863
|
+
"gotchas": [
|
|
864
|
+
"Order matters for -l flags: libraries must come AFTER the object files that reference them -- gcc main.c -lm works but gcc -lm main.c may fail with undefined references",
|
|
865
|
+
"-O2 is generally safe for production but -O3 can occasionally produce different floating-point results or expose latent bugs in code with undefined behavior",
|
|
866
|
+
"Without -Wall -Wextra many real bugs go unreported -- always enable warnings and consider -Werror in CI",
|
|
867
|
+
"gcc and g++ are different frontends -- use g++ for C++ code, gcc for C, even though gcc can sometimes compile C++",
|
|
868
|
+
],
|
|
869
|
+
"related": ["g++", "clang", "make", "gdb", "ld"],
|
|
870
|
+
"difficulty": "intermediate",
|
|
871
|
+
"extra_flags": {
|
|
872
|
+
"-Wextra": "Enable extra warnings beyond -Wall",
|
|
873
|
+
"-pedantic": "Issue warnings demanded by strict ISO C compliance",
|
|
874
|
+
"-fsanitize": "Enable runtime sanitizers (address, undefined, thread, memory)",
|
|
875
|
+
"-D": "Define a preprocessor macro",
|
|
876
|
+
"-S": "Compile to assembly instead of object code",
|
|
877
|
+
"-E": "Preprocess only, do not compile",
|
|
878
|
+
"-pie": "Create a position-independent executable",
|
|
879
|
+
"-shared": "Create a shared library",
|
|
880
|
+
},
|
|
881
|
+
},
|
|
882
|
+
"g++": {
|
|
883
|
+
"man_url": "https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html",
|
|
884
|
+
"use_cases": [
|
|
885
|
+
"Compile a C++17 program with g++ -std=c++17 -Wall -o app main.cpp",
|
|
886
|
+
"Build with AddressSanitizer for memory bug detection with g++ -fsanitize=address -g -o test test.cpp",
|
|
887
|
+
"Compile and link with pthread support with g++ -o server server.cpp -lpthread",
|
|
888
|
+
],
|
|
889
|
+
"gotchas": [
|
|
890
|
+
"g++ links the C++ standard library automatically unlike gcc -- use g++ (not gcc) for C++ code to avoid linker errors",
|
|
891
|
+
"The default C++ standard varies by GCC version -- always specify -std=c++17 or -std=c++20 explicitly for portability",
|
|
892
|
+
"Template errors produce notoriously long error messages -- read from the bottom up to find the actual source of the error",
|
|
893
|
+
],
|
|
894
|
+
"related": ["gcc", "clang++", "make", "gdb"],
|
|
895
|
+
"difficulty": "intermediate",
|
|
896
|
+
"extra_flags": {},
|
|
897
|
+
},
|
|
898
|
+
"clang": {
|
|
899
|
+
"man_url": "https://clang.llvm.org/docs/ClangCommandLineReference.html",
|
|
900
|
+
"use_cases": [
|
|
901
|
+
"Compile with AddressSanitizer for catching buffer overflows with clang -fsanitize=address -g -o test test.c",
|
|
902
|
+
"Get detailed error messages with clang -Wall -Wextra -std=c17 -o app main.c",
|
|
903
|
+
"Cross-compile for a different target with clang --target=aarch64-linux-gnu -o app main.c",
|
|
904
|
+
],
|
|
905
|
+
"gotchas": [
|
|
906
|
+
"clang error messages are generally more readable than gcc's -- clang is often preferred for development even if gcc is used for release builds",
|
|
907
|
+
"clang's ABI is compatible with gcc on Linux but some edge cases differ -- test with both compilers in CI",
|
|
908
|
+
"On macOS, the cc and gcc commands are actually clang in disguise -- check with cc --version",
|
|
909
|
+
],
|
|
910
|
+
"related": ["clang++", "gcc", "lldb", "make"],
|
|
911
|
+
"difficulty": "intermediate",
|
|
912
|
+
"extra_flags": {},
|
|
913
|
+
},
|
|
914
|
+
"clang++": {
|
|
915
|
+
"man_url": "https://clang.llvm.org/docs/ClangCommandLineReference.html",
|
|
916
|
+
"use_cases": [
|
|
917
|
+
"Compile modern C++20 code with clang++ -std=c++20 -Wall -o app main.cpp",
|
|
918
|
+
"Use clang++ with libc++ instead of libstdc++ with clang++ -stdlib=libc++ -o app main.cpp",
|
|
919
|
+
"Run UndefinedBehaviorSanitizer to catch UB at runtime with clang++ -fsanitize=undefined -g -o test test.cpp",
|
|
920
|
+
],
|
|
921
|
+
"gotchas": [
|
|
922
|
+
"clang++ defaults to libstdc++ on Linux but libc++ on macOS -- this can cause ABI incompatibility when mixing libraries compiled with different standard libraries",
|
|
923
|
+
"clang++ may produce different warnings than g++ -- enable both in CI for maximum bug detection",
|
|
924
|
+
],
|
|
925
|
+
"related": ["clang", "g++", "lldb", "cmake"],
|
|
926
|
+
"difficulty": "intermediate",
|
|
927
|
+
"extra_flags": {},
|
|
928
|
+
},
|
|
929
|
+
"cc": {
|
|
930
|
+
"man_url": "https://man7.org/linux/man-pages/man1/cc.1p.html",
|
|
931
|
+
"use_cases": [
|
|
932
|
+
"Compile a portable C program with cc -o program main.c as a system-agnostic compiler invocation",
|
|
933
|
+
"Use in Makefiles and configure scripts as the default compiler name that works on any Unix system",
|
|
934
|
+
],
|
|
935
|
+
"gotchas": [
|
|
936
|
+
"cc is a symlink to the system default C compiler -- it may be gcc, clang, or another compiler depending on the OS",
|
|
937
|
+
"On macOS cc points to clang, on most Linux systems cc points to gcc -- check with cc --version",
|
|
938
|
+
"Using cc instead of gcc or clang in build scripts improves portability across Unix-like systems",
|
|
939
|
+
],
|
|
940
|
+
"related": ["gcc", "clang", "make"],
|
|
941
|
+
"difficulty": "beginner",
|
|
942
|
+
"extra_flags": {},
|
|
943
|
+
},
|
|
944
|
+
"ld": {
|
|
945
|
+
"man_url": "https://sourceware.org/binutils/docs/ld/",
|
|
946
|
+
"use_cases": [
|
|
947
|
+
"Link object files into an executable with ld -o program main.o utils.o -lc",
|
|
948
|
+
"Create a shared library with ld -shared -o libfoo.so foo.o",
|
|
949
|
+
"Use a custom linker script for embedded firmware with ld -T linker.ld -o firmware.elf startup.o main.o",
|
|
950
|
+
],
|
|
951
|
+
"gotchas": [
|
|
952
|
+
"ld is usually invoked indirectly through gcc or clang which add necessary startup files and library paths -- calling ld directly requires specifying crt0.o and other platform files",
|
|
953
|
+
"Library order matters: ld processes libraries left to right and only includes symbols needed at that point -- put -l flags after the .o files that need them",
|
|
954
|
+
"ld uses the system default linker script unless -T is specified -- this controls memory layout and is critical for embedded/OS development",
|
|
955
|
+
],
|
|
956
|
+
"related": ["gcc", "as", "ar", "nm", "ldd"],
|
|
957
|
+
"difficulty": "advanced",
|
|
958
|
+
"extra_flags": {
|
|
959
|
+
"-static": "Do not link against shared libraries",
|
|
960
|
+
"-pie": "Create a position-independent executable",
|
|
961
|
+
"--as-needed": "Only link libraries that resolve undefined symbols",
|
|
962
|
+
},
|
|
963
|
+
},
|
|
964
|
+
"as": {
|
|
965
|
+
"man_url": "https://sourceware.org/binutils/docs/as/",
|
|
966
|
+
"use_cases": [
|
|
967
|
+
"Assemble an x86 assembly file with as -o output.o source.s",
|
|
968
|
+
"Generate a listing file alongside assembly with as -ahlms=listing.lst source.s",
|
|
969
|
+
"Assemble with debug information for gdb with as --gstabs -o debug.o source.s",
|
|
970
|
+
],
|
|
971
|
+
"gotchas": [
|
|
972
|
+
"as uses AT&T syntax by default on x86 where source comes before destination -- this is opposite to Intel/NASM syntax",
|
|
973
|
+
"The assembler is architecture-specific -- cross-assembling requires a cross-compilation toolchain (e.g., aarch64-linux-gnu-as)",
|
|
974
|
+
"as is usually invoked automatically by gcc when compiling .s or .S files -- direct use is mainly for OS development and embedded work",
|
|
975
|
+
],
|
|
976
|
+
"related": ["gcc", "ld", "objdump", "gdb"],
|
|
977
|
+
"difficulty": "advanced",
|
|
978
|
+
"extra_flags": {},
|
|
979
|
+
},
|
|
980
|
+
"ar": {
|
|
981
|
+
"man_url": "https://sourceware.org/binutils/docs/binutils/ar.html",
|
|
982
|
+
"use_cases": [
|
|
983
|
+
"Create a static library from object files with ar rcs libmylib.a obj1.o obj2.o",
|
|
984
|
+
"List contents of a static library with ar t libmylib.a",
|
|
985
|
+
"Extract a specific object file from a library with ar x libmylib.a module.o",
|
|
986
|
+
],
|
|
987
|
+
"gotchas": [
|
|
988
|
+
"Always use 's' with 'r' (ar rcs) to create/update the symbol index -- without it the linker may not find symbols",
|
|
989
|
+
"ar creates static libraries (.a) not shared libraries (.so) -- use gcc -shared for shared libraries",
|
|
990
|
+
"The r flag replaces files in the archive, c suppresses the creation warning, and s creates the index -- rcs is the standard combination",
|
|
991
|
+
],
|
|
992
|
+
"related": ["gcc", "ld", "nm", "ranlib"],
|
|
993
|
+
"difficulty": "intermediate",
|
|
994
|
+
"extra_flags": {},
|
|
995
|
+
},
|
|
996
|
+
|
|
997
|
+
# =========================================================================
|
|
998
|
+
# DEVELOPMENT - DEBUGGERS & ANALYSIS
|
|
999
|
+
# =========================================================================
|
|
1000
|
+
"gdb": {
|
|
1001
|
+
"man_url": "https://sourceware.org/gdb/current/onlinedocs/gdb/",
|
|
1002
|
+
"use_cases": [
|
|
1003
|
+
"Debug a segfault by running gdb ./program then typing run, and bt (backtrace) after the crash",
|
|
1004
|
+
"Set a breakpoint and inspect variables with gdb -ex 'break main' -ex 'run' ./program",
|
|
1005
|
+
"Examine a core dump with gdb ./program core to see where a crash occurred post-mortem",
|
|
1006
|
+
"Debug with source display using gdb -tui ./program for a visual split-screen interface",
|
|
1007
|
+
],
|
|
1008
|
+
"gotchas": [
|
|
1009
|
+
"Programs must be compiled with -g for meaningful debug output -- without it gdb shows only assembly and hex addresses",
|
|
1010
|
+
"Optimized code (-O2, -O3) confuses gdb because variables are optimized out and code is reordered -- debug with -O0 -g",
|
|
1011
|
+
"gdb prints variables in the current scope only -- if a variable shows as 'optimized out' try compiling with -O0",
|
|
1012
|
+
"Use -ex to pass commands non-interactively: gdb -batch -ex run -ex bt --args ./program for automated crash analysis",
|
|
1013
|
+
],
|
|
1014
|
+
"related": ["lldb", "valgrind", "gcc", "objdump"],
|
|
1015
|
+
"difficulty": "intermediate",
|
|
1016
|
+
"extra_flags": {
|
|
1017
|
+
"-batch": "Run in batch mode (exit after processing -ex commands)",
|
|
1018
|
+
"-p": "Attach to running process by PID",
|
|
1019
|
+
"-core": "Load a core dump file for post-mortem debugging",
|
|
1020
|
+
"-x": "Execute GDB commands from a file",
|
|
1021
|
+
},
|
|
1022
|
+
},
|
|
1023
|
+
"lldb": {
|
|
1024
|
+
"man_url": "https://lldb.llvm.org/use/tutorial.html",
|
|
1025
|
+
"use_cases": [
|
|
1026
|
+
"Debug a program on macOS with lldb ./program (lldb is the default macOS debugger)",
|
|
1027
|
+
"Attach to a running process with lldb -p $(pgrep myapp)",
|
|
1028
|
+
"Analyze a core dump with lldb -c core ./program for post-mortem debugging",
|
|
1029
|
+
],
|
|
1030
|
+
"gotchas": [
|
|
1031
|
+
"lldb commands differ from gdb: use 'thread backtrace' instead of 'bt', 'breakpoint set -n main' instead of 'break main'",
|
|
1032
|
+
"On macOS, codesigning is required to debug other processes -- lldb shipped with Xcode has the proper entitlements",
|
|
1033
|
+
"lldb uses the LLVM expression parser which can evaluate C++ and Swift but has quirks with complex template expressions",
|
|
1034
|
+
],
|
|
1035
|
+
"related": ["gdb", "clang", "valgrind"],
|
|
1036
|
+
"difficulty": "intermediate",
|
|
1037
|
+
"extra_flags": {},
|
|
1038
|
+
},
|
|
1039
|
+
"valgrind": {
|
|
1040
|
+
"man_url": "https://valgrind.org/docs/manual/manual.html",
|
|
1041
|
+
"use_cases": [
|
|
1042
|
+
"Check for memory leaks with valgrind --leak-check=full --track-origins=yes ./program",
|
|
1043
|
+
"Profile cache usage with valgrind --tool=cachegrind ./program",
|
|
1044
|
+
"Generate a call graph for profiling with valgrind --tool=callgrind ./program then view with kcachegrind",
|
|
1045
|
+
],
|
|
1046
|
+
"gotchas": [
|
|
1047
|
+
"Programs run 10-30x slower under valgrind -- reduce input sizes for testing or it may take hours",
|
|
1048
|
+
"Compile with -g -O0 for accurate line numbers -- optimized code (-O2+) causes valgrind to report false positives for uninitialized values",
|
|
1049
|
+
"Valgrind doubles memory usage (1.25x allocation + ~120 bytes overhead per malloc) -- you may need to reduce parallel workers or input sizes",
|
|
1050
|
+
"Valgrind only works on Linux and macOS x86_64 -- it does not support ARM64 on macOS (Apple Silicon) natively",
|
|
1051
|
+
"Use --suppressions to ignore known false positives from system libraries",
|
|
1052
|
+
],
|
|
1053
|
+
"related": ["gdb", "gcc", "clang"],
|
|
1054
|
+
"difficulty": "intermediate",
|
|
1055
|
+
"extra_flags": {
|
|
1056
|
+
"-v": "Verbose mode with more details about each error",
|
|
1057
|
+
"--gen-suppressions": "Generate suppression entries for each error (all or yes)",
|
|
1058
|
+
"--vgdb": "Enable gdb to connect to valgrind for interactive debugging",
|
|
1059
|
+
},
|
|
1060
|
+
},
|
|
1061
|
+
"objdump": {
|
|
1062
|
+
"man_url": "https://sourceware.org/binutils/docs/binutils/objdump.html",
|
|
1063
|
+
"use_cases": [
|
|
1064
|
+
"Disassemble a binary to view assembly with objdump -d program",
|
|
1065
|
+
"View disassembly interleaved with source code with objdump -d -S -l program (requires -g)",
|
|
1066
|
+
"Inspect section headers and sizes with objdump -h program to understand binary layout",
|
|
1067
|
+
],
|
|
1068
|
+
"gotchas": [
|
|
1069
|
+
"objdump -d only disassembles executable sections -- use -D to disassemble ALL sections including data",
|
|
1070
|
+
"Source interleaving with -S requires the binary to be compiled with -g debug info",
|
|
1071
|
+
"objdump uses AT&T syntax by default on x86 -- use -M intel for Intel syntax if you prefer it",
|
|
1072
|
+
],
|
|
1073
|
+
"related": ["nm", "readelf", "gdb", "strings"],
|
|
1074
|
+
"difficulty": "advanced",
|
|
1075
|
+
"extra_flags": {
|
|
1076
|
+
"-M": "Pass disassembler options (e.g., -M intel for Intel syntax)",
|
|
1077
|
+
"-j": "Disassemble only the specified section",
|
|
1078
|
+
},
|
|
1079
|
+
},
|
|
1080
|
+
"nm": {
|
|
1081
|
+
"man_url": "https://sourceware.org/binutils/docs/binutils/nm.html",
|
|
1082
|
+
"use_cases": [
|
|
1083
|
+
"List all exported symbols in a shared library with nm -gD libfoo.so",
|
|
1084
|
+
"Find undefined symbols that need resolving with nm -u program.o",
|
|
1085
|
+
"Demangle C++ symbols for readability with nm -C libcpp.so",
|
|
1086
|
+
],
|
|
1087
|
+
"gotchas": [
|
|
1088
|
+
"nm cannot read stripped binaries -- if nm shows no symbols, the binary was stripped with strip",
|
|
1089
|
+
"For shared libraries, use -D to show dynamic symbols -- regular nm may show nothing for .so files",
|
|
1090
|
+
"Symbol types: T=text/code, D=data, U=undefined, B=BSS -- U symbols are what the linker needs to resolve",
|
|
1091
|
+
],
|
|
1092
|
+
"related": ["objdump", "readelf", "ldd", "ar"],
|
|
1093
|
+
"difficulty": "advanced",
|
|
1094
|
+
"extra_flags": {},
|
|
1095
|
+
},
|
|
1096
|
+
"readelf": {
|
|
1097
|
+
"man_url": "https://sourceware.org/binutils/docs/binutils/readelf.html",
|
|
1098
|
+
"use_cases": [
|
|
1099
|
+
"Inspect ELF headers to determine architecture with readelf -h binary",
|
|
1100
|
+
"List dynamic library dependencies with readelf -d binary | grep NEEDED",
|
|
1101
|
+
"View all symbols including their types and sizes with readelf -s --wide program",
|
|
1102
|
+
],
|
|
1103
|
+
"gotchas": [
|
|
1104
|
+
"readelf only works on ELF binaries (Linux/Unix) -- it cannot read Mach-O (macOS) or PE (Windows) binaries",
|
|
1105
|
+
"Use -W (wide) to prevent long symbol names from being truncated in output",
|
|
1106
|
+
"readelf -d shows dynamic section including NEEDED (shared library dependencies) and RPATH -- useful for diagnosing library loading issues",
|
|
1107
|
+
],
|
|
1108
|
+
"related": ["objdump", "nm", "ldd", "file"],
|
|
1109
|
+
"difficulty": "advanced",
|
|
1110
|
+
"extra_flags": {
|
|
1111
|
+
"-n": "Display the note segments (build ID, etc.)",
|
|
1112
|
+
"-V": "Display the version sections",
|
|
1113
|
+
},
|
|
1114
|
+
},
|
|
1115
|
+
"ldd": {
|
|
1116
|
+
"man_url": "https://man7.org/linux/man-pages/man1/ldd.1.html",
|
|
1117
|
+
"use_cases": [
|
|
1118
|
+
"Find all shared library dependencies of a binary with ldd ./myapp",
|
|
1119
|
+
"Diagnose 'cannot open shared object file' errors by checking which libraries are missing",
|
|
1120
|
+
"Verify that a binary links to the expected version of a library with ldd -v ./myapp",
|
|
1121
|
+
],
|
|
1122
|
+
"gotchas": [
|
|
1123
|
+
"NEVER run ldd on untrusted binaries -- ldd can execute the binary's code to resolve dependencies, which is a security risk. Use objdump -p or readelf -d instead",
|
|
1124
|
+
"ldd shows the resolved paths at the current moment -- results depend on LD_LIBRARY_PATH and ldconfig cache",
|
|
1125
|
+
"If ldd shows 'not found' for a library, the library is either not installed or not in the linker search path -- fix with ldconfig or LD_LIBRARY_PATH",
|
|
1126
|
+
],
|
|
1127
|
+
"related": ["readelf", "nm", "ldconfig", "objdump"],
|
|
1128
|
+
"difficulty": "intermediate",
|
|
1129
|
+
"extra_flags": {},
|
|
1130
|
+
},
|
|
1131
|
+
|
|
1132
|
+
# =========================================================================
|
|
1133
|
+
# DEVELOPMENT - CONTAINERS & INFRASTRUCTURE
|
|
1134
|
+
# =========================================================================
|
|
1135
|
+
"docker-compose": {
|
|
1136
|
+
"man_url": "https://docs.docker.com/compose/reference/",
|
|
1137
|
+
"use_cases": [
|
|
1138
|
+
"Start a full application stack in the background with docker-compose up -d",
|
|
1139
|
+
"View real-time logs from all services with docker-compose logs -f",
|
|
1140
|
+
"Rebuild images after code changes with docker-compose up --build -d",
|
|
1141
|
+
"Scale a specific service with docker-compose up -d --scale worker=3",
|
|
1142
|
+
],
|
|
1143
|
+
"gotchas": [
|
|
1144
|
+
"docker-compose (V1, Python) is deprecated -- use docker compose (V2, Go plugin) which is now built into Docker CLI",
|
|
1145
|
+
"V2 uses hyphens in container names (myproject-svc-1) instead of V1's underscores (myproject_svc_1) -- this can break scripts that parse container names",
|
|
1146
|
+
"The top-level version: field in docker-compose.yml is ignored by V2 -- it uses the Compose Specification directly",
|
|
1147
|
+
"docker-compose down removes containers but not volumes -- add -v to also remove named volumes, or data persists between restarts",
|
|
1148
|
+
],
|
|
1149
|
+
"related": ["docker", "podman", "kubectl"],
|
|
1150
|
+
"difficulty": "intermediate",
|
|
1151
|
+
"extra_flags": {
|
|
1152
|
+
"--env-file": "Specify an alternate .env file for environment variable substitution",
|
|
1153
|
+
"--profile": "Specify a profile to enable optional services",
|
|
1154
|
+
"--scale": "Scale a service to N instances",
|
|
1155
|
+
},
|
|
1156
|
+
},
|
|
1157
|
+
"podman": {
|
|
1158
|
+
"man_url": "https://docs.podman.io/en/latest/",
|
|
1159
|
+
"use_cases": [
|
|
1160
|
+
"Run containers without root privileges with podman run --rm -it ubuntu bash",
|
|
1161
|
+
"Use as a drop-in Docker replacement with alias docker=podman in your shell config",
|
|
1162
|
+
"Build OCI images with podman build -t myapp . using the same Dockerfile syntax",
|
|
1163
|
+
],
|
|
1164
|
+
"gotchas": [
|
|
1165
|
+
"Podman is daemonless -- there is no background service to start, which means podman ps only shows your containers not other users'",
|
|
1166
|
+
"Rootless podman uses user namespaces which can cause UID mapping issues -- files created inside containers may appear as 'nobody' on the host",
|
|
1167
|
+
"podman-compose exists but is less mature than docker compose -- for complex stacks, test compatibility carefully",
|
|
1168
|
+
],
|
|
1169
|
+
"related": ["docker", "docker-compose", "buildah", "kubectl"],
|
|
1170
|
+
"difficulty": "intermediate",
|
|
1171
|
+
"extra_flags": {},
|
|
1172
|
+
},
|
|
1173
|
+
"kubectl": {
|
|
1174
|
+
"man_url": "https://kubernetes.io/docs/reference/kubectl/",
|
|
1175
|
+
"use_cases": [
|
|
1176
|
+
"View running pods in all namespaces with kubectl get pods -A",
|
|
1177
|
+
"Debug a failing pod by viewing its logs with kubectl logs pod-name -f --previous",
|
|
1178
|
+
"Execute a shell inside a running container with kubectl exec -it pod-name -- /bin/sh",
|
|
1179
|
+
"Apply infrastructure changes declaratively with kubectl apply -f deployment.yaml",
|
|
1180
|
+
],
|
|
1181
|
+
"gotchas": [
|
|
1182
|
+
"Always specify -n namespace or set a default with kubectl config set-context --current --namespace=myns -- forgetting the namespace is a very common source of confusion",
|
|
1183
|
+
"kubectl apply tracks changes via annotations -- switching between apply and create/replace can cause conflicts",
|
|
1184
|
+
"kubectl delete pod does not prevent recreation -- Deployments automatically recreate deleted pods. Delete the Deployment instead to stop pods permanently",
|
|
1185
|
+
"kubectl logs only shows logs from the current container instance -- use --previous to see logs from the crashed previous instance",
|
|
1186
|
+
],
|
|
1187
|
+
"related": ["helm", "minikube", "docker", "podman"],
|
|
1188
|
+
"difficulty": "intermediate",
|
|
1189
|
+
"extra_flags": {
|
|
1190
|
+
"--dry-run": "Preview the request without sending it (client or server side)",
|
|
1191
|
+
"-w": "Watch for changes to resources in real time",
|
|
1192
|
+
"--context": "Specify which kubeconfig context (cluster) to use",
|
|
1193
|
+
"--all-namespaces": "List resources across all namespaces (shorthand: -A)",
|
|
1194
|
+
},
|
|
1195
|
+
},
|
|
1196
|
+
"helm": {
|
|
1197
|
+
"man_url": "https://helm.sh/docs/helm/",
|
|
1198
|
+
"use_cases": [
|
|
1199
|
+
"Install a chart from a repository with helm install myrelease bitnami/nginx",
|
|
1200
|
+
"Upgrade a release with new values with helm upgrade myrelease ./mychart --values prod-values.yaml",
|
|
1201
|
+
"Preview rendered manifests before applying with helm template myrelease ./mychart",
|
|
1202
|
+
"Rollback to a previous release version with helm rollback myrelease 2",
|
|
1203
|
+
],
|
|
1204
|
+
"gotchas": [
|
|
1205
|
+
"helm install and helm upgrade are separate operations -- use helm upgrade --install for idempotent deployments that work regardless of whether the release exists",
|
|
1206
|
+
"Helm stores release metadata as Secrets in the namespace -- deleting those secrets breaks Helm's ability to manage the release",
|
|
1207
|
+
"Chart values are merged, not replaced -- nested YAML structures may accumulate unexpected values across upgrades",
|
|
1208
|
+
"Always use --dry-run and helm diff (plugin) to preview changes before upgrading production releases",
|
|
1209
|
+
],
|
|
1210
|
+
"related": ["kubectl", "minikube", "docker"],
|
|
1211
|
+
"difficulty": "intermediate",
|
|
1212
|
+
"extra_flags": {
|
|
1213
|
+
"--atomic": "Roll back automatically if the install/upgrade fails",
|
|
1214
|
+
"--debug": "Show verbose debug output and rendered templates",
|
|
1215
|
+
"template": "Render chart templates locally without deploying",
|
|
1216
|
+
"rollback": "Roll back a release to a previous revision",
|
|
1217
|
+
},
|
|
1218
|
+
},
|
|
1219
|
+
"minikube": {
|
|
1220
|
+
"man_url": "https://minikube.sigs.k8s.io/docs/",
|
|
1221
|
+
"use_cases": [
|
|
1222
|
+
"Start a local Kubernetes cluster for development with minikube start",
|
|
1223
|
+
"Access the Kubernetes dashboard with minikube dashboard",
|
|
1224
|
+
"Use minikube's Docker daemon to build images directly with eval $(minikube docker-env)",
|
|
1225
|
+
"Test with a specific Kubernetes version with minikube start --kubernetes-version=v1.28.0",
|
|
1226
|
+
],
|
|
1227
|
+
"gotchas": [
|
|
1228
|
+
"minikube runs a single-node cluster -- it does not simulate multi-node scenarios or network policies accurately",
|
|
1229
|
+
"minikube tunnel is required for LoadBalancer services to get external IPs -- without it they stay pending",
|
|
1230
|
+
"minikube consumes significant memory and CPU -- allocate at least 2 CPUs and 4GB RAM or workloads will be unstable",
|
|
1231
|
+
],
|
|
1232
|
+
"related": ["kubectl", "helm", "docker", "kind"],
|
|
1233
|
+
"difficulty": "intermediate",
|
|
1234
|
+
"extra_flags": {
|
|
1235
|
+
"--addons": "Enable specific minikube addons (metrics-server, ingress, etc.)",
|
|
1236
|
+
"tunnel": "Create a route to services deployed with type LoadBalancer",
|
|
1237
|
+
"service": "Get the URL of a service for browser access",
|
|
1238
|
+
},
|
|
1239
|
+
},
|
|
1240
|
+
"vagrant": {
|
|
1241
|
+
"man_url": "https://developer.hashicorp.com/vagrant/docs",
|
|
1242
|
+
"use_cases": [
|
|
1243
|
+
"Create a reproducible development VM with vagrant init ubuntu/jammy64 && vagrant up",
|
|
1244
|
+
"SSH into the development VM with vagrant ssh",
|
|
1245
|
+
"Re-run provisioning scripts with vagrant provision after updating your Vagrantfile",
|
|
1246
|
+
],
|
|
1247
|
+
"gotchas": [
|
|
1248
|
+
"Vagrant requires a hypervisor (VirtualBox, VMware, or libvirt) -- install one before using Vagrant",
|
|
1249
|
+
"vagrant destroy permanently deletes the VM and all its data -- use vagrant halt for a temporary stop",
|
|
1250
|
+
"Synced folders use VirtualBox shared folders by default which can be slow -- use NFS or rsync for better performance",
|
|
1251
|
+
],
|
|
1252
|
+
"related": ["docker", "terraform", "ansible"],
|
|
1253
|
+
"difficulty": "intermediate",
|
|
1254
|
+
"extra_flags": {},
|
|
1255
|
+
},
|
|
1256
|
+
"terraform": {
|
|
1257
|
+
"man_url": "https://developer.hashicorp.com/terraform/cli",
|
|
1258
|
+
"use_cases": [
|
|
1259
|
+
"Initialize a project and download providers with terraform init",
|
|
1260
|
+
"Preview infrastructure changes before applying with terraform plan -out=tfplan",
|
|
1261
|
+
"Apply infrastructure changes with terraform apply tfplan",
|
|
1262
|
+
"Tear down all managed infrastructure with terraform destroy (use with extreme caution)",
|
|
1263
|
+
],
|
|
1264
|
+
"gotchas": [
|
|
1265
|
+
"Terraform state is critical -- losing the state file means Terraform no longer knows about your infrastructure. Use remote backends (S3, GCS) not local state",
|
|
1266
|
+
"terraform destroy destroys ALL resources in the state -- there is no undo. Always use -target for selective destruction",
|
|
1267
|
+
"State locking prevents concurrent modifications -- if a lock gets stuck, use terraform force-unlock (dangerous)",
|
|
1268
|
+
"Terraform plan can show no changes but apply can still fail due to API errors, permissions, or rate limits",
|
|
1269
|
+
],
|
|
1270
|
+
"related": ["ansible", "kubectl", "docker"],
|
|
1271
|
+
"difficulty": "intermediate",
|
|
1272
|
+
"extra_flags": {
|
|
1273
|
+
"-compact-warnings": "Show warnings in a compact single-line format",
|
|
1274
|
+
"-refresh-only": "Update state to match real infrastructure without changing resources",
|
|
1275
|
+
"state": "Advanced state management subcommand (mv, rm, list, show)",
|
|
1276
|
+
"import": "Import existing infrastructure into Terraform management",
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
"ansible": {
|
|
1280
|
+
"man_url": "https://docs.ansible.com/ansible/latest/cli/ansible.html",
|
|
1281
|
+
"use_cases": [
|
|
1282
|
+
"Run a quick ad-hoc command on all servers with ansible all -m ping -i inventory.yml",
|
|
1283
|
+
"Deploy an application with ansible-playbook -i hosts deploy.yml",
|
|
1284
|
+
"Test changes without applying with ansible-playbook site.yml --check --diff",
|
|
1285
|
+
],
|
|
1286
|
+
"gotchas": [
|
|
1287
|
+
"Ansible requires SSH access and Python on managed hosts -- hosts without Python need the raw or script modules",
|
|
1288
|
+
"YAML indentation matters -- a misplaced space can cause silent misconfiguration rather than an error",
|
|
1289
|
+
"ansible-playbook and ansible are different commands -- use ansible for ad-hoc tasks and ansible-playbook for playbook execution",
|
|
1290
|
+
"--check mode does not guarantee idempotency detection -- some modules do not support check mode and will skip",
|
|
1291
|
+
],
|
|
1292
|
+
"related": ["terraform", "puppet", "chef", "ssh"],
|
|
1293
|
+
"difficulty": "intermediate",
|
|
1294
|
+
"extra_flags": {
|
|
1295
|
+
"--diff": "Show file change diffs when modifying files on remote hosts",
|
|
1296
|
+
"--list-hosts": "List hosts that would be affected without executing",
|
|
1297
|
+
"--ask-become-pass": "Prompt for the privilege escalation (sudo) password",
|
|
1298
|
+
},
|
|
1299
|
+
},
|
|
1300
|
+
"puppet": {
|
|
1301
|
+
"man_url": "https://www.puppet.com/docs/puppet/latest/man/overview.html",
|
|
1302
|
+
"use_cases": [
|
|
1303
|
+
"Apply a manifest locally with puppet apply manifest.pp for testing",
|
|
1304
|
+
"Run the Puppet agent in test mode with puppet agent --test to see what changes would be made",
|
|
1305
|
+
"Dry-run a manifest without making changes with puppet apply --noop site.pp",
|
|
1306
|
+
],
|
|
1307
|
+
"gotchas": [
|
|
1308
|
+
"Puppet uses a declarative language that is not Ruby despite looking similar -- it has its own syntax rules",
|
|
1309
|
+
"Puppet runs are not instant -- the agent checks in periodically (default 30 minutes) and convergence takes multiple runs for complex catalogs",
|
|
1310
|
+
"Resource ordering is not guaranteed unless you specify explicit dependencies with require, before, notify, or subscribe",
|
|
1311
|
+
],
|
|
1312
|
+
"related": ["ansible", "chef", "terraform"],
|
|
1313
|
+
"difficulty": "advanced",
|
|
1314
|
+
"extra_flags": {},
|
|
1315
|
+
},
|
|
1316
|
+
"chef": {
|
|
1317
|
+
"man_url": "https://docs.chef.io/workstation/knife/",
|
|
1318
|
+
"use_cases": [
|
|
1319
|
+
"Apply a recipe locally for testing with chef-client --local-mode -r 'recipe[mycookbook]'",
|
|
1320
|
+
"Upload a cookbook to the Chef server with knife cookbook upload mycookbook",
|
|
1321
|
+
"List managed nodes with knife node list",
|
|
1322
|
+
],
|
|
1323
|
+
"gotchas": [
|
|
1324
|
+
"Chef uses Ruby for cookbooks which has a steeper learning curve than Ansible's YAML -- Ruby syntax errors in recipes can be hard to debug",
|
|
1325
|
+
"chef-client runs require a Chef Server or chef-zero for local mode -- the architecture is more complex than agentless tools like Ansible",
|
|
1326
|
+
"The knife CLI is part of Chef Workstation, not Chef Client -- install Chef Workstation on your development machine",
|
|
1327
|
+
],
|
|
1328
|
+
"related": ["ansible", "puppet", "terraform"],
|
|
1329
|
+
"difficulty": "advanced",
|
|
1330
|
+
"extra_flags": {},
|
|
1331
|
+
},
|
|
1332
|
+
|
|
1333
|
+
# =========================================================================
|
|
1334
|
+
# DEVELOPMENT - EDITORS
|
|
1335
|
+
# =========================================================================
|
|
1336
|
+
"code": {
|
|
1337
|
+
"man_url": "https://code.visualstudio.com/docs/editor/command-line",
|
|
1338
|
+
"use_cases": [
|
|
1339
|
+
"Open the current directory in VS Code with code .",
|
|
1340
|
+
"Open a file at a specific line with code --goto main.py:42",
|
|
1341
|
+
"Compare two files side by side with code --diff old.js new.js",
|
|
1342
|
+
"Install an extension from the command line with code --install-extension ms-python.python",
|
|
1343
|
+
],
|
|
1344
|
+
"gotchas": [
|
|
1345
|
+
"The code command must be installed into PATH on macOS -- open VS Code and run 'Shell Command: Install code command' from the command palette",
|
|
1346
|
+
"code --wait is needed for use as a git editor or merge tool -- without it git does not wait for you to close the file",
|
|
1347
|
+
"Running code . in WSL opens VS Code with the Remote-WSL extension -- this is by design but can confuse first-time WSL users",
|
|
1348
|
+
],
|
|
1349
|
+
"related": ["vim", "nvim", "nano", "emacs"],
|
|
1350
|
+
"difficulty": "beginner",
|
|
1351
|
+
"extra_flags": {
|
|
1352
|
+
"--wait": "Wait for file to be closed before returning (for git editor use)",
|
|
1353
|
+
"-r": "Reuse the most recently used window",
|
|
1354
|
+
"--locale": "Set the display language (e.g., en, zh-cn)",
|
|
1355
|
+
},
|
|
1356
|
+
},
|
|
1357
|
+
"vim": {
|
|
1358
|
+
"man_url": "https://vimhelp.org/",
|
|
1359
|
+
"use_cases": [
|
|
1360
|
+
"Edit a file starting at a specific line with vim +42 file.txt",
|
|
1361
|
+
"Open multiple files in split view with vim -O file1.py file2.py",
|
|
1362
|
+
"Compare two files visually with vim -d file1.txt file2.txt (vimdiff)",
|
|
1363
|
+
"Search and replace across a file with vim -c '%s/old/new/gc' -c 'wq' file.txt for scripted editing",
|
|
1364
|
+
],
|
|
1365
|
+
"gotchas": [
|
|
1366
|
+
"Vim starts in normal mode, not insert mode -- press i to start typing. This trips up every new user",
|
|
1367
|
+
"Exiting vim: press Escape, then type :wq to save and quit, or :q! to quit without saving -- this is the most searched programming question on the internet",
|
|
1368
|
+
"Vim swap files (.swp) are created automatically and can cause issues if vim crashes -- use vim -r file to recover, then delete the .swp file",
|
|
1369
|
+
"Avoid using arrow keys in normal mode -- learn hjkl and motions (w, b, e, f, /) for dramatically faster navigation",
|
|
1370
|
+
],
|
|
1371
|
+
"related": ["nvim", "vi", "nano", "emacs"],
|
|
1372
|
+
"difficulty": "intermediate",
|
|
1373
|
+
"extra_flags": {
|
|
1374
|
+
"-o": "Open files in horizontal splits",
|
|
1375
|
+
"-c": "Execute a vim command after opening the file",
|
|
1376
|
+
"-u": "Use a specific vimrc configuration file (use NONE for vanilla vim)",
|
|
1377
|
+
"-x": "Open file with encryption (prompted for password)",
|
|
1378
|
+
},
|
|
1379
|
+
},
|
|
1380
|
+
"nvim": {
|
|
1381
|
+
"man_url": "https://neovim.io/doc/",
|
|
1382
|
+
"use_cases": [
|
|
1383
|
+
"Open a file with nvim file.txt and enjoy built-in LSP support for code completion",
|
|
1384
|
+
"Run headless for plugin installation with nvim --headless '+Lazy sync' +qa",
|
|
1385
|
+
"Start with no configuration to debug plugin issues with nvim --clean file.txt",
|
|
1386
|
+
"Use diff mode to compare files with nvim -d file1.txt file2.txt",
|
|
1387
|
+
],
|
|
1388
|
+
"gotchas": [
|
|
1389
|
+
"Neovim uses ~/.config/nvim/init.lua (or init.vim) not ~/.vimrc -- migrating vim config requires renaming and possibly converting to Lua",
|
|
1390
|
+
"Neovim's built-in LSP and Treesitter provide IDE-like features but require plugin setup (mason.nvim, nvim-lspconfig) -- they are not configured out of the box",
|
|
1391
|
+
"nvim --headless is useful for CI/CD plugin management but requires proper exit commands (+qa) or it hangs",
|
|
1392
|
+
],
|
|
1393
|
+
"related": ["vim", "vi", "code", "emacs"],
|
|
1394
|
+
"difficulty": "intermediate",
|
|
1395
|
+
"extra_flags": {
|
|
1396
|
+
"--startuptime": "Write startup timing to a file for performance profiling",
|
|
1397
|
+
"-l": "Execute a Lua script and exit",
|
|
1398
|
+
},
|
|
1399
|
+
},
|
|
1400
|
+
"nano": {
|
|
1401
|
+
"man_url": "https://www.nano-editor.org/dist/latest/nano.1.html",
|
|
1402
|
+
"use_cases": [
|
|
1403
|
+
"Quick-edit a config file on a server with sudo nano /etc/nginx/nginx.conf",
|
|
1404
|
+
"Edit with line numbers for reference with nano -l file.py",
|
|
1405
|
+
"Create a backup before editing with nano -B important.conf",
|
|
1406
|
+
],
|
|
1407
|
+
"gotchas": [
|
|
1408
|
+
"Keyboard shortcuts shown at the bottom use ^ for Ctrl and M- for Alt -- ^X means Ctrl+X, M-U means Alt+U",
|
|
1409
|
+
"nano wraps long lines by default which can corrupt config files -- use nano -w to disable wrapping for config file editing",
|
|
1410
|
+
"nano does not have the modal editing or macro power of vim -- it is excellent for quick edits but limited for large-scale text manipulation",
|
|
1411
|
+
],
|
|
1412
|
+
"related": ["vim", "vi", "emacs", "code"],
|
|
1413
|
+
"difficulty": "beginner",
|
|
1414
|
+
"extra_flags": {
|
|
1415
|
+
"-E": "Convert tabs to spaces when typing",
|
|
1416
|
+
"-S": "Enable smooth scrolling instead of half-screen jumps",
|
|
1417
|
+
"-Y": "Specify syntax highlighting definition to use",
|
|
1418
|
+
},
|
|
1419
|
+
},
|
|
1420
|
+
"emacs": {
|
|
1421
|
+
"man_url": "https://www.gnu.org/software/emacs/manual/html_node/emacs/",
|
|
1422
|
+
"use_cases": [
|
|
1423
|
+
"Edit a file in terminal mode with emacs -nw file.txt",
|
|
1424
|
+
"Run Emacs as a daemon for instant startup with emacs --daemon then emacsclient file.txt",
|
|
1425
|
+
"Evaluate a Lisp expression for batch processing with emacs --batch --eval '(message \"hello\")'",
|
|
1426
|
+
],
|
|
1427
|
+
"gotchas": [
|
|
1428
|
+
"Emacs uses Ctrl and Meta (Alt) key combinations extensively -- Ctrl+C Ctrl+F opens a file, Ctrl+X Ctrl+S saves, Ctrl+X Ctrl+C quits",
|
|
1429
|
+
"Emacs init files (.emacs or ~/.emacs.d/init.el) can slow startup significantly -- use emacs --daemon + emacsclient for fast subsequent access",
|
|
1430
|
+
"The learning curve is steep but different from vim -- Emacs is always in 'insert mode' and uses modifier keys instead of modal switching",
|
|
1431
|
+
],
|
|
1432
|
+
"related": ["vim", "nvim", "code", "nano"],
|
|
1433
|
+
"difficulty": "advanced",
|
|
1434
|
+
"extra_flags": {},
|
|
1435
|
+
},
|
|
1436
|
+
"ed": {
|
|
1437
|
+
"man_url": "https://man7.org/linux/man-pages/man1/ed.1.html",
|
|
1438
|
+
"use_cases": [
|
|
1439
|
+
"Perform scripted file editing without any terminal UI with echo '1,s/old/new/g\\nw\\nq' | ed -s file.txt",
|
|
1440
|
+
"Edit files in environments where no screen-oriented editor is available (recovery mode, minimal containers)",
|
|
1441
|
+
],
|
|
1442
|
+
"gotchas": [
|
|
1443
|
+
"ed is a line editor with no visual display -- you must use commands like p (print) and n (number) to see file contents",
|
|
1444
|
+
"ed silently succeeds on most operations with no feedback -- use -p to set a prompt character so you know ed is waiting for input",
|
|
1445
|
+
"ed is the standard POSIX editor -- it works everywhere but is mainly used for scripted edits, not interactive editing",
|
|
1446
|
+
],
|
|
1447
|
+
"related": ["ex", "sed", "vim", "vi"],
|
|
1448
|
+
"difficulty": "advanced",
|
|
1449
|
+
"extra_flags": {},
|
|
1450
|
+
},
|
|
1451
|
+
"ex": {
|
|
1452
|
+
"man_url": "https://man7.org/linux/man-pages/man1/ex.1p.html",
|
|
1453
|
+
"use_cases": [
|
|
1454
|
+
"Perform batch find-and-replace without opening a visual editor with ex -sc '%s/old/new/g|x' file.txt",
|
|
1455
|
+
"Delete all lines matching a pattern with ex -sc 'g/DEBUG/d|x' logfile.txt",
|
|
1456
|
+
"Script complex multi-step edits with ex commands piped from a file",
|
|
1457
|
+
],
|
|
1458
|
+
"gotchas": [
|
|
1459
|
+
"ex is essentially vim's command mode run standalone -- the commands are identical to vim : commands",
|
|
1460
|
+
"Use -s for silent batch mode to suppress prompts and messages -- without it ex waits for interactive input",
|
|
1461
|
+
"The x command saves and exits (write-quit) -- use q! to discard changes if the script fails midway",
|
|
1462
|
+
],
|
|
1463
|
+
"related": ["ed", "vim", "sed"],
|
|
1464
|
+
"difficulty": "advanced",
|
|
1465
|
+
"extra_flags": {},
|
|
1466
|
+
},
|
|
1467
|
+
"vi": {
|
|
1468
|
+
"man_url": "https://man7.org/linux/man-pages/man1/vi.1p.html",
|
|
1469
|
+
"use_cases": [
|
|
1470
|
+
"Edit a file on any Unix system where vim may not be installed with vi filename.txt",
|
|
1471
|
+
"Use as a fallback editor during system recovery when only base utilities are available",
|
|
1472
|
+
],
|
|
1473
|
+
"gotchas": [
|
|
1474
|
+
"On most modern systems vi is a symlink to vim or vim in compatible mode -- behavior may differ slightly from POSIX vi",
|
|
1475
|
+
"vi has fewer features than vim -- no syntax highlighting, no multiple undo levels, and limited plugin support",
|
|
1476
|
+
"vi is always available because POSIX requires it -- it is the editor of last resort for emergency system repairs",
|
|
1477
|
+
],
|
|
1478
|
+
"related": ["vim", "nvim", "nano", "ed"],
|
|
1479
|
+
"difficulty": "intermediate",
|
|
1480
|
+
"extra_flags": {},
|
|
1481
|
+
},
|
|
1482
|
+
|
|
1483
|
+
# =========================================================================
|
|
1484
|
+
# DEVELOPMENT - DATA PROCESSING
|
|
1485
|
+
# =========================================================================
|
|
1486
|
+
"jq": {
|
|
1487
|
+
"man_url": "https://jqlang.github.io/jq/manual/",
|
|
1488
|
+
"use_cases": [
|
|
1489
|
+
"Pretty-print JSON from an API with curl -s api.example.com/data | jq '.' for readable output",
|
|
1490
|
+
"Extract a specific field with jq '.users[].name' data.json to pull names from an array",
|
|
1491
|
+
"Transform JSON structure with jq '{name: .full_name, id: .user_id}' to reshape data for another tool",
|
|
1492
|
+
"Filter array elements by condition with jq '[.items[] | select(.price > 100)]' products.json",
|
|
1493
|
+
"Merge two JSON files with jq -s '.[0] * .[1]' defaults.json overrides.json",
|
|
1494
|
+
],
|
|
1495
|
+
"gotchas": [
|
|
1496
|
+
"jq is not installed by default on most systems -- install it with your package manager before relying on it in scripts",
|
|
1497
|
+
"String interpolation in jq uses \\() not ${} -- mixing up shell and jq variable syntax is a common source of errors",
|
|
1498
|
+
"Use --arg name value to safely pass shell variables into jq expressions -- embedding them with $() risks injection",
|
|
1499
|
+
"jq outputs JSON strings with quotes by default -- use -r for raw output when piping to other commands",
|
|
1500
|
+
],
|
|
1501
|
+
"related": ["yq", "python", "xmllint", "curl"],
|
|
1502
|
+
"difficulty": "intermediate",
|
|
1503
|
+
"extra_flags": {
|
|
1504
|
+
"-e": "Set exit status based on output (false/null -> exit 1)",
|
|
1505
|
+
"--argjson": "Set variable to a JSON value (not string)",
|
|
1506
|
+
"--slurpfile": "Read entire file as JSON value into a variable",
|
|
1507
|
+
"--rawfile": "Read entire file as a raw string into a variable",
|
|
1508
|
+
"-n": "Do not read input, use null as input",
|
|
1509
|
+
"--indent": "Set indentation level (default 2)",
|
|
1510
|
+
},
|
|
1511
|
+
},
|
|
1512
|
+
"yq": {
|
|
1513
|
+
"man_url": "https://mikefarah.gitbook.io/yq/",
|
|
1514
|
+
"use_cases": [
|
|
1515
|
+
"Extract a value from a YAML file with yq '.metadata.name' deployment.yaml",
|
|
1516
|
+
"Update a value in-place with yq -i '.image.tag = \"v2.0\"' values.yaml",
|
|
1517
|
+
"Convert YAML to JSON with yq -o json config.yaml for tools that only accept JSON",
|
|
1518
|
+
"Merge multiple YAML files with yq eval-all '. as $item ireduce ({}; . * $item)' a.yaml b.yaml",
|
|
1519
|
+
],
|
|
1520
|
+
"gotchas": [
|
|
1521
|
+
"There are two different tools called yq -- the Go version (mikefarah/yq) and the Python version (kislyuk/yq) with different syntax. Check which you have with yq --version",
|
|
1522
|
+
"yq -i modifies files in-place with no backup -- pipe to a new file or use version control before editing",
|
|
1523
|
+
"YAML anchors and aliases may not round-trip perfectly through yq -- test with complex YAML before automating",
|
|
1524
|
+
"yq uses jq-like syntax but is not fully jq-compatible -- some jq filters work differently or are unsupported",
|
|
1525
|
+
],
|
|
1526
|
+
"related": ["jq", "xmllint", "sed"],
|
|
1527
|
+
"difficulty": "intermediate",
|
|
1528
|
+
"extra_flags": {
|
|
1529
|
+
"-e": "Set exit status based on whether results exist",
|
|
1530
|
+
"eval-all": "Evaluate across all YAML documents in the input",
|
|
1531
|
+
"--front-matter": "Process YAML front matter in markdown files",
|
|
1532
|
+
},
|
|
1533
|
+
},
|
|
1534
|
+
"xmllint": {
|
|
1535
|
+
"man_url": "http://xmlsoft.org/xmllint.html",
|
|
1536
|
+
"use_cases": [
|
|
1537
|
+
"Validate an XML file against its schema with xmllint --noout --schema schema.xsd file.xml",
|
|
1538
|
+
"Pretty-print an XML file with xmllint --format messy.xml > formatted.xml",
|
|
1539
|
+
"Extract data with XPath with xmllint --xpath '//item/@name' data.xml",
|
|
1540
|
+
],
|
|
1541
|
+
"gotchas": [
|
|
1542
|
+
"xmllint requires libxml2 to be installed -- it is usually available as part of the libxml2-utils package",
|
|
1543
|
+
"--xpath with namespaces requires explicit namespace declarations which can be very verbose",
|
|
1544
|
+
"xmllint --format adds a newline at the end of the file -- this may matter for exact binary comparison of XML files",
|
|
1545
|
+
],
|
|
1546
|
+
"related": ["xsltproc", "jq", "yq"],
|
|
1547
|
+
"difficulty": "intermediate",
|
|
1548
|
+
"extra_flags": {
|
|
1549
|
+
"--c14n": "Canonicalize XML output for consistent comparison",
|
|
1550
|
+
"--dtdvalid": "Validate against an external DTD file",
|
|
1551
|
+
"--recover": "Try to recover from malformed XML",
|
|
1552
|
+
},
|
|
1553
|
+
},
|
|
1554
|
+
"xsltproc": {
|
|
1555
|
+
"man_url": "http://xmlsoft.org/xsltproc.html",
|
|
1556
|
+
"use_cases": [
|
|
1557
|
+
"Transform XML to HTML with xsltproc style.xsl data.xml > output.html",
|
|
1558
|
+
"Generate documentation from XML sources with xsltproc -o doc.html docbook.xsl manual.xml",
|
|
1559
|
+
"Pass parameters to stylesheets with xsltproc --param version \"'2.0'\" transform.xsl input.xml",
|
|
1560
|
+
],
|
|
1561
|
+
"gotchas": [
|
|
1562
|
+
"String parameters passed with --param must be wrapped in extra quotes: --param name \"'value'\" (outer quotes for shell, inner for XPath)",
|
|
1563
|
+
"xsltproc only supports XSLT 1.0 -- for XSLT 2.0 or 3.0 you need Saxon or another processor",
|
|
1564
|
+
"Network access for DTDs and external entities can be slow or fail -- use --nonet to disable",
|
|
1565
|
+
],
|
|
1566
|
+
"related": ["xmllint", "jq", "sed"],
|
|
1567
|
+
"difficulty": "advanced",
|
|
1568
|
+
"extra_flags": {},
|
|
1569
|
+
},
|
|
1570
|
+
"jsonnet": {
|
|
1571
|
+
"man_url": "https://jsonnet.org/ref/language.html",
|
|
1572
|
+
"use_cases": [
|
|
1573
|
+
"Generate Kubernetes manifests from templates with jsonnet -J lib/ -m output/ k8s.jsonnet",
|
|
1574
|
+
"Evaluate a simple expression with jsonnet -e '{ result: 1 + 2 }'",
|
|
1575
|
+
"Pass external variables for environment-specific config with jsonnet --ext-str env=prod config.jsonnet",
|
|
1576
|
+
],
|
|
1577
|
+
"gotchas": [
|
|
1578
|
+
"Jsonnet is purely functional with no side effects -- you cannot read files or make network calls from Jsonnet code",
|
|
1579
|
+
"Output is JSON by default -- use -S for string output or -y for YAML (if using the Go implementation)",
|
|
1580
|
+
"Jsonnet evaluation is lazy -- errors in unused branches are not reported until those branches are actually referenced",
|
|
1581
|
+
],
|
|
1582
|
+
"related": ["jq", "yq", "kubectl", "terraform"],
|
|
1583
|
+
"difficulty": "advanced",
|
|
1584
|
+
"extra_flags": {},
|
|
1585
|
+
},
|
|
1586
|
+
|
|
1587
|
+
# =========================================================================
|
|
1588
|
+
# DEVELOPMENT - RUNTIMES & LANGUAGES
|
|
1589
|
+
# =========================================================================
|
|
1590
|
+
"node": {
|
|
1591
|
+
"man_url": "https://nodejs.org/docs/latest/api/cli.html",
|
|
1592
|
+
"use_cases": [
|
|
1593
|
+
"Run a JavaScript file with node app.js",
|
|
1594
|
+
"Start a quick REPL for testing with node (interactive mode)",
|
|
1595
|
+
"Evaluate an expression inline with node -e 'console.log(process.version)'",
|
|
1596
|
+
"Debug a script with Chrome DevTools with node --inspect-brk app.js then open chrome://inspect",
|
|
1597
|
+
],
|
|
1598
|
+
"gotchas": [
|
|
1599
|
+
"Node.js uses CommonJS (require) by default -- to use ES modules (import/export) either use .mjs extension or set \"type\": \"module\" in package.json",
|
|
1600
|
+
"The --inspect flag opens a debug port (9229) -- never expose this in production as it allows arbitrary code execution",
|
|
1601
|
+
"Node.js is single-threaded for JavaScript execution -- CPU-intensive work blocks the event loop and should use worker_threads",
|
|
1602
|
+
"Unhandled promise rejections will crash Node.js in newer versions -- always add .catch() or use try/catch with async/await",
|
|
1603
|
+
],
|
|
1604
|
+
"related": ["npm", "npx", "deno", "bun"],
|
|
1605
|
+
"difficulty": "beginner",
|
|
1606
|
+
"extra_flags": {
|
|
1607
|
+
"--watch": "Watch for file changes and restart automatically (Node 18+)",
|
|
1608
|
+
"--experimental-modules": "Enable ES module support (legacy, now default)",
|
|
1609
|
+
"-p": "Evaluate and print an expression (shorthand for -e with console.log)",
|
|
1610
|
+
"--max-old-space-size": "Set the V8 heap memory limit in MB (default ~1.5GB)",
|
|
1611
|
+
"-r": "Preload a module before executing the script",
|
|
1612
|
+
"--env-file": "Load environment variables from a .env file (Node 20+)",
|
|
1613
|
+
},
|
|
1614
|
+
},
|
|
1615
|
+
"python": {
|
|
1616
|
+
"man_url": "https://docs.python.org/3/using/cmdline.html",
|
|
1617
|
+
"use_cases": [
|
|
1618
|
+
"Run a script with python script.py or start an interactive session with just python for quick testing",
|
|
1619
|
+
"Spin up a quick local web server with python -m http.server 8000 to serve files from the current directory",
|
|
1620
|
+
"Create a virtual environment with python -m venv .venv to isolate project dependencies",
|
|
1621
|
+
"Profile a script to find bottlenecks with python -m cProfile -s cumulative script.py",
|
|
1622
|
+
"Run a module as a script with python -m json.tool < data.json for pretty-printing JSON",
|
|
1623
|
+
],
|
|
1624
|
+
"gotchas": [
|
|
1625
|
+
"On many systems, python points to Python 2 while python3 points to Python 3 -- always verify with python --version and use python3 explicitly if needed",
|
|
1626
|
+
"Running python without arguments starts the REPL which can be confusing in scripts -- always provide a script path or -c flag in automated contexts",
|
|
1627
|
+
"python -m pip install is safer than pip install because it ensures you use the correct Python version's pip",
|
|
1628
|
+
"The -u flag (unbuffered output) is important for Docker containers and CI pipelines where stdout buffering hides log output",
|
|
1629
|
+
],
|
|
1630
|
+
"related": ["pip", "pip3", "conda", "uv", "ipython"],
|
|
1631
|
+
"difficulty": "beginner",
|
|
1632
|
+
"extra_flags": {
|
|
1633
|
+
"-W": "Warning control (error, ignore, default, all)",
|
|
1634
|
+
"-X": "Set implementation-specific options (e.g., -X dev for dev mode with extra checks)",
|
|
1635
|
+
"-q": "Quiet mode: suppress copyright and version messages on startup",
|
|
1636
|
+
"-O": "Optimize: remove assert statements and __debug__-guarded code",
|
|
1637
|
+
"-S": "Do not import the site module on startup (faster but no user site-packages)",
|
|
1638
|
+
},
|
|
1639
|
+
},
|
|
1640
|
+
"deno": {
|
|
1641
|
+
"man_url": "https://docs.deno.com/runtime/reference/cli/",
|
|
1642
|
+
"use_cases": [
|
|
1643
|
+
"Run a TypeScript file directly without compilation with deno run script.ts",
|
|
1644
|
+
"Run a web server with explicit permissions with deno run --allow-net --allow-read server.ts",
|
|
1645
|
+
"Format and lint code with built-in tools with deno fmt && deno lint",
|
|
1646
|
+
"Run tests with deno test for built-in test runner support",
|
|
1647
|
+
],
|
|
1648
|
+
"gotchas": [
|
|
1649
|
+
"Deno uses explicit permissions by default -- scripts cannot access files, network, or environment without --allow-* flags, which breaks scripts silently if forgotten",
|
|
1650
|
+
"Deno uses URL imports not package.json by default -- npm compatibility exists via npm: specifiers but the ecosystem differs from Node.js",
|
|
1651
|
+
"Deno does not support __dirname or require() -- use import.meta.url and ES module imports instead",
|
|
1652
|
+
],
|
|
1653
|
+
"related": ["node", "bun", "npm", "tsc"],
|
|
1654
|
+
"difficulty": "intermediate",
|
|
1655
|
+
"extra_flags": {
|
|
1656
|
+
"--allow-run": "Allow running subprocesses",
|
|
1657
|
+
"--allow-ffi": "Allow loading dynamic libraries",
|
|
1658
|
+
"--lock": "Check specified lockfile for integrity",
|
|
1659
|
+
"--no-check": "Skip TypeScript type checking for faster startup",
|
|
1660
|
+
},
|
|
1661
|
+
},
|
|
1662
|
+
"bun": {
|
|
1663
|
+
"man_url": "https://bun.sh/docs/cli",
|
|
1664
|
+
"use_cases": [
|
|
1665
|
+
"Install dependencies faster than npm with bun install",
|
|
1666
|
+
"Run a TypeScript file directly with bun run script.ts (no tsc needed)",
|
|
1667
|
+
"Run tests with the built-in test runner with bun test",
|
|
1668
|
+
"Bundle JavaScript for production with bun build ./src/index.ts --outdir ./dist",
|
|
1669
|
+
],
|
|
1670
|
+
"gotchas": [
|
|
1671
|
+
"Bun aims for Node.js compatibility but not all Node APIs are implemented -- check the compatibility table for edge cases",
|
|
1672
|
+
"Bun uses its own lockfile (bun.lockb) which is binary -- it is not compatible with npm's package-lock.json or yarn.lock",
|
|
1673
|
+
"Some npm packages with native C++ addons may not work with Bun -- Bun uses JavaScriptCore (not V8) which requires different native bindings",
|
|
1674
|
+
],
|
|
1675
|
+
"related": ["node", "deno", "npm", "tsc"],
|
|
1676
|
+
"difficulty": "intermediate",
|
|
1677
|
+
"extra_flags": {
|
|
1678
|
+
"build": "Bundle JavaScript/TypeScript for production",
|
|
1679
|
+
"--hot": "Enable hot module reloading during development",
|
|
1680
|
+
},
|
|
1681
|
+
},
|
|
1682
|
+
"ruby": {
|
|
1683
|
+
"man_url": "https://ruby-doc.org/3.3/",
|
|
1684
|
+
"use_cases": [
|
|
1685
|
+
"Run a Ruby script with ruby script.rb",
|
|
1686
|
+
"Execute a one-liner with ruby -e 'puts RUBY_VERSION'",
|
|
1687
|
+
"Process text line by line with ruby -ne 'puts $_ if /ERROR/' logfile.txt",
|
|
1688
|
+
"Check syntax without executing with ruby -c script.rb",
|
|
1689
|
+
],
|
|
1690
|
+
"gotchas": [
|
|
1691
|
+
"Ruby version management requires rbenv or rvm -- system Ruby is often outdated",
|
|
1692
|
+
"Ruby's -i flag for in-place editing requires a backup extension on macOS (ruby -i.bak -pe ...) but not on Linux",
|
|
1693
|
+
"Ruby's standard library is being extracted into gems in Ruby 3.x -- some imports that worked before may now require gem install",
|
|
1694
|
+
],
|
|
1695
|
+
"related": ["gem", "bundle", "irb", "perl"],
|
|
1696
|
+
"difficulty": "intermediate",
|
|
1697
|
+
"extra_flags": {},
|
|
1698
|
+
},
|
|
1699
|
+
"perl": {
|
|
1700
|
+
"man_url": "https://perldoc.perl.org/perl",
|
|
1701
|
+
"use_cases": [
|
|
1702
|
+
"Perform complex find-and-replace across files with perl -pi -e 's/old_api/new_api/g' *.py",
|
|
1703
|
+
"Process structured text with field splitting with perl -lane 'print $F[2]' data.tsv",
|
|
1704
|
+
"One-liner to sum a column of numbers with perl -lane '$s+=$F[0]; END{print $s}' data.txt",
|
|
1705
|
+
],
|
|
1706
|
+
"gotchas": [
|
|
1707
|
+
"perl -i edits files in-place and DESTROYS the original -- use -i.bak to create backups",
|
|
1708
|
+
"Perl regex is the reference implementation for PCRE -- what works in Perl regex generally works in other PCRE-based tools",
|
|
1709
|
+
"The difference between -n (loop without print) and -p (loop with auto-print) is critical for one-liners",
|
|
1710
|
+
],
|
|
1711
|
+
"related": ["sed", "awk", "ruby", "grep"],
|
|
1712
|
+
"difficulty": "intermediate",
|
|
1713
|
+
"extra_flags": {},
|
|
1714
|
+
},
|
|
1715
|
+
"php": {
|
|
1716
|
+
"man_url": "https://www.php.net/manual/en/features.commandline.php",
|
|
1717
|
+
"use_cases": [
|
|
1718
|
+
"Start a quick development server with php -S localhost:8000",
|
|
1719
|
+
"Check file syntax without executing with php -l script.php",
|
|
1720
|
+
"Run a quick expression with php -r 'echo phpversion() . \"\\n\";'",
|
|
1721
|
+
],
|
|
1722
|
+
"gotchas": [
|
|
1723
|
+
"php -S is for development only -- it is single-threaded and not suitable for production traffic",
|
|
1724
|
+
"PHP's command-line SAPI uses different php.ini than the web server SAPI -- check with php --ini",
|
|
1725
|
+
"PHP's -r flag requires careful shell quoting because PHP uses $ for variables which conflicts with shell variable expansion",
|
|
1726
|
+
],
|
|
1727
|
+
"related": ["composer", "node", "python"],
|
|
1728
|
+
"difficulty": "intermediate",
|
|
1729
|
+
"extra_flags": {},
|
|
1730
|
+
},
|
|
1731
|
+
"java": {
|
|
1732
|
+
"man_url": "https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html",
|
|
1733
|
+
"use_cases": [
|
|
1734
|
+
"Run a JAR application with java -jar app.jar",
|
|
1735
|
+
"Run a class with specific memory limits with java -Xmx4g -Xms1g -cp classes com.example.Main",
|
|
1736
|
+
"Run a single-file source program directly with java Main.java (Java 11+)",
|
|
1737
|
+
],
|
|
1738
|
+
"gotchas": [
|
|
1739
|
+
"JAVA_HOME must be set correctly -- many tools rely on it and misconfiguration causes confusing errors",
|
|
1740
|
+
"-Xmx sets the maximum heap but the JVM uses additional memory for stack, metaspace, and native allocations -- total memory usage is always higher",
|
|
1741
|
+
"Classpath separator is : on Unix but ; on Windows -- cross-platform scripts need to handle this",
|
|
1742
|
+
"Java 9+ introduced the module system (JPMS) which can cause 'module not found' errors with older code -- use --add-modules or --add-opens for compatibility",
|
|
1743
|
+
],
|
|
1744
|
+
"related": ["javac", "mvn", "gradle"],
|
|
1745
|
+
"difficulty": "intermediate",
|
|
1746
|
+
"extra_flags": {
|
|
1747
|
+
"--add-modules": "Add modules to the module graph for compatibility",
|
|
1748
|
+
"--add-opens": "Open a module's packages for deep reflection access",
|
|
1749
|
+
"-Xss": "Set thread stack size",
|
|
1750
|
+
},
|
|
1751
|
+
},
|
|
1752
|
+
"javac": {
|
|
1753
|
+
"man_url": "https://docs.oracle.com/en/java/javase/21/docs/specs/man/javac.html",
|
|
1754
|
+
"use_cases": [
|
|
1755
|
+
"Compile a Java file with javac Main.java",
|
|
1756
|
+
"Compile to a specific output directory with javac -d build/ src/*.java",
|
|
1757
|
+
"Compile for a specific Java release with javac --release 17 Main.java",
|
|
1758
|
+
],
|
|
1759
|
+
"gotchas": [
|
|
1760
|
+
"javac requires all dependent classes on the classpath -- missing dependencies cause compilation errors even if the source is correct",
|
|
1761
|
+
"The --release flag is preferred over -source/-target combination because it also checks API availability",
|
|
1762
|
+
"javac only compiles .java files explicitly listed -- use build tools (Maven, Gradle) for multi-module projects",
|
|
1763
|
+
],
|
|
1764
|
+
"related": ["java", "mvn", "gradle"],
|
|
1765
|
+
"difficulty": "intermediate",
|
|
1766
|
+
"extra_flags": {},
|
|
1767
|
+
},
|
|
1768
|
+
"kotlin": {
|
|
1769
|
+
"man_url": "https://kotlinlang.org/docs/command-line.html",
|
|
1770
|
+
"use_cases": [
|
|
1771
|
+
"Compile and bundle a self-contained JAR with kotlinc hello.kt -include-runtime -d hello.jar",
|
|
1772
|
+
"Run a Kotlin script with kotlinc -script script.kts",
|
|
1773
|
+
"Start the Kotlin REPL for quick prototyping with kotlinc",
|
|
1774
|
+
],
|
|
1775
|
+
"gotchas": [
|
|
1776
|
+
"kotlinc without -include-runtime creates a JAR that requires the Kotlin runtime on the classpath -- use -include-runtime for standalone JARs",
|
|
1777
|
+
"The kotlin command runs JARs while kotlinc compiles -- they are separate tools",
|
|
1778
|
+
"Kotlin scripts (.kts) cannot import local .kt files without additional configuration -- use a build tool for multi-file projects",
|
|
1779
|
+
],
|
|
1780
|
+
"related": ["java", "javac", "gradle", "scala"],
|
|
1781
|
+
"difficulty": "intermediate",
|
|
1782
|
+
"extra_flags": {},
|
|
1783
|
+
},
|
|
1784
|
+
"scala": {
|
|
1785
|
+
"man_url": "https://docs.scala-lang.org/scala3/book/tools-scala.html",
|
|
1786
|
+
"use_cases": [
|
|
1787
|
+
"Compile a Scala file with scalac Hello.scala then run with scala Hello",
|
|
1788
|
+
"Start the Scala REPL for interactive exploration with scala",
|
|
1789
|
+
"Run a Scala script directly with scala script.sc (Scala 3)",
|
|
1790
|
+
],
|
|
1791
|
+
"gotchas": [
|
|
1792
|
+
"Scala 2 and Scala 3 have significant syntax differences -- check which version you are using with scala -version",
|
|
1793
|
+
"Scala compilation is notoriously slow -- incremental compilation with sbt or Bloop dramatically improves edit-compile-run cycles",
|
|
1794
|
+
"The scala command is both a REPL and a script runner -- behavior depends on whether you pass a file argument",
|
|
1795
|
+
],
|
|
1796
|
+
"related": ["java", "javac", "kotlin", "sbt"],
|
|
1797
|
+
"difficulty": "advanced",
|
|
1798
|
+
"extra_flags": {},
|
|
1799
|
+
},
|
|
1800
|
+
"swift": {
|
|
1801
|
+
"man_url": "https://www.swift.org/documentation/",
|
|
1802
|
+
"use_cases": [
|
|
1803
|
+
"Run a Swift script directly with swift script.swift",
|
|
1804
|
+
"Create a new executable package with swift package init --type executable",
|
|
1805
|
+
"Build a package in release mode with swift build -c release",
|
|
1806
|
+
],
|
|
1807
|
+
"gotchas": [
|
|
1808
|
+
"Swift on Linux requires the Swift toolchain to be installed separately -- it is not included in standard Linux distributions",
|
|
1809
|
+
"swift build uses Swift Package Manager (SPM) not Xcode build settings -- project structure must follow SPM conventions",
|
|
1810
|
+
"Swift REPL is started with just swift (no arguments) -- it can be slow to launch on first use due to compilation",
|
|
1811
|
+
],
|
|
1812
|
+
"related": ["swiftc", "xcode", "lldb"],
|
|
1813
|
+
"difficulty": "intermediate",
|
|
1814
|
+
"extra_flags": {},
|
|
1815
|
+
},
|
|
1816
|
+
"swiftc": {
|
|
1817
|
+
"man_url": "https://www.swift.org/documentation/",
|
|
1818
|
+
"use_cases": [
|
|
1819
|
+
"Compile a Swift file to an executable with swiftc main.swift -o app",
|
|
1820
|
+
"Compile with optimizations for release with swiftc -O main.swift -o release_app",
|
|
1821
|
+
"Create a dynamic library with swiftc -emit-library -o libutils.dylib utils.swift",
|
|
1822
|
+
],
|
|
1823
|
+
"gotchas": [
|
|
1824
|
+
"swiftc compiles individual files -- for multi-file projects with dependencies, use Swift Package Manager (swift build) instead",
|
|
1825
|
+
"Swift ABI stability (Swift 5.0+) means the runtime is part of the OS on macOS but must be bundled on Linux",
|
|
1826
|
+
"swiftc error messages can be long for generic type errors -- look for 'note:' lines that explain the root cause",
|
|
1827
|
+
],
|
|
1828
|
+
"related": ["swift", "clang", "lldb"],
|
|
1829
|
+
"difficulty": "intermediate",
|
|
1830
|
+
"extra_flags": {},
|
|
1831
|
+
},
|
|
1832
|
+
"rust": {
|
|
1833
|
+
"man_url": "https://doc.rust-lang.org/cargo/",
|
|
1834
|
+
"use_cases": [
|
|
1835
|
+
"Create a new Rust project with cargo new myproject",
|
|
1836
|
+
"Build and run a project with cargo run",
|
|
1837
|
+
"Build an optimized release binary with cargo build --release",
|
|
1838
|
+
"Run tests with cargo test",
|
|
1839
|
+
],
|
|
1840
|
+
"gotchas": [
|
|
1841
|
+
"The rust entry in most contexts refers to Cargo, the Rust build tool -- the actual compiler is rustc, but cargo is the standard interface",
|
|
1842
|
+
"cargo build --release applies optimizations that make binaries dramatically faster -- always benchmark with --release, not debug builds",
|
|
1843
|
+
"First compilation downloads and compiles all dependencies which can take several minutes -- subsequent builds use cached artifacts",
|
|
1844
|
+
"Rust's borrow checker produces unique errors that require understanding ownership semantics -- read the error messages carefully as they usually suggest fixes",
|
|
1845
|
+
],
|
|
1846
|
+
"related": ["rustc", "rustup", "cargo"],
|
|
1847
|
+
"difficulty": "intermediate",
|
|
1848
|
+
"extra_flags": {
|
|
1849
|
+
"--edition": "Set the Rust edition (2015, 2018, 2021)",
|
|
1850
|
+
"clippy": "Run the Rust linter via cargo clippy",
|
|
1851
|
+
"fmt": "Format code via cargo fmt",
|
|
1852
|
+
"doc": "Generate documentation via cargo doc",
|
|
1853
|
+
},
|
|
1854
|
+
},
|
|
1855
|
+
"rustc": {
|
|
1856
|
+
"man_url": "https://doc.rust-lang.org/rustc/",
|
|
1857
|
+
"use_cases": [
|
|
1858
|
+
"Compile a single Rust file with rustc main.rs",
|
|
1859
|
+
"Compile with optimizations with rustc -O main.rs -o app",
|
|
1860
|
+
"Cross-compile for a different target with rustc --target aarch64-unknown-linux-gnu main.rs",
|
|
1861
|
+
],
|
|
1862
|
+
"gotchas": [
|
|
1863
|
+
"rustc is rarely invoked directly -- use cargo which manages dependencies, build configuration, and invokes rustc internally",
|
|
1864
|
+
"rustc defaults to the 2015 edition unless --edition is specified -- use --edition 2021 for modern Rust features",
|
|
1865
|
+
"Cross-compilation with rustc requires the target to be installed via rustup target add -- the linker for the target must also be available",
|
|
1866
|
+
],
|
|
1867
|
+
"related": ["rust", "cargo", "rustup"],
|
|
1868
|
+
"difficulty": "intermediate",
|
|
1869
|
+
"extra_flags": {},
|
|
1870
|
+
},
|
|
1871
|
+
"go": {
|
|
1872
|
+
"man_url": "https://pkg.go.dev/cmd/go",
|
|
1873
|
+
"use_cases": [
|
|
1874
|
+
"Build and run a Go program with go run main.go",
|
|
1875
|
+
"Build a static binary with go build -o myapp ./cmd/myapp",
|
|
1876
|
+
"Run all tests with go test ./...",
|
|
1877
|
+
"Clean up module dependencies with go mod tidy",
|
|
1878
|
+
],
|
|
1879
|
+
"gotchas": [
|
|
1880
|
+
"Go compiles to a single static binary by default -- no runtime dependencies needed on the target system",
|
|
1881
|
+
"go get was changed in Go 1.17+ -- it no longer builds/installs, use go install for installing tools",
|
|
1882
|
+
"GOPATH is largely irrelevant with Go modules -- ensure go.mod exists in your project root",
|
|
1883
|
+
"Unused imports are a compilation error, not a warning -- use goimports or _ prefix for intentionally unused imports",
|
|
1884
|
+
],
|
|
1885
|
+
"related": ["gofmt", "golint", "delve"],
|
|
1886
|
+
"difficulty": "intermediate",
|
|
1887
|
+
"extra_flags": {
|
|
1888
|
+
"-ldflags": "Pass flags to the linker (e.g., -s -w to strip debug info for smaller binaries)",
|
|
1889
|
+
"-gcflags": "Pass flags to the Go compiler",
|
|
1890
|
+
"-trimpath": "Remove file system paths from the compiled binary for reproducibility",
|
|
1891
|
+
"vet": "Report likely mistakes in packages (go vet ./...)",
|
|
1892
|
+
},
|
|
1893
|
+
},
|
|
1894
|
+
|
|
1895
|
+
# =========================================================================
|
|
1896
|
+
# DEVELOPMENT - TESTING & LINTING
|
|
1897
|
+
# =========================================================================
|
|
1898
|
+
"eslint": {
|
|
1899
|
+
"man_url": "https://eslint.org/docs/latest/use/command-line-interface",
|
|
1900
|
+
"use_cases": [
|
|
1901
|
+
"Lint all JavaScript files in a project with eslint .",
|
|
1902
|
+
"Auto-fix linting issues with eslint --fix .",
|
|
1903
|
+
"Lint specific file types with eslint --ext .ts,.tsx src/",
|
|
1904
|
+
"Check specific rules with eslint --rule '{no-console: error}' file.js",
|
|
1905
|
+
],
|
|
1906
|
+
"gotchas": [
|
|
1907
|
+
"ESLint 9+ uses flat config (eslint.config.js) by default -- the old .eslintrc format is deprecated",
|
|
1908
|
+
"--fix only fixes rules marked as fixable -- some issues must be resolved manually",
|
|
1909
|
+
"ESLint does not lint TypeScript by default -- you need @typescript-eslint/parser and plugin configured",
|
|
1910
|
+
],
|
|
1911
|
+
"related": ["prettier", "tsc", "jest"],
|
|
1912
|
+
"difficulty": "beginner",
|
|
1913
|
+
"extra_flags": {
|
|
1914
|
+
"--cache": "Only check changed files for faster linting on large projects",
|
|
1915
|
+
"--max-warnings": "Set max warnings before exit with error (0 for strict)",
|
|
1916
|
+
"--no-eslintrc": "Disable use of configuration from .eslintrc files",
|
|
1917
|
+
"--format": "Set output format (stylish, json, compact, etc.)",
|
|
1918
|
+
},
|
|
1919
|
+
},
|
|
1920
|
+
"prettier": {
|
|
1921
|
+
"man_url": "https://prettier.io/docs/en/cli.html",
|
|
1922
|
+
"use_cases": [
|
|
1923
|
+
"Format all files in a project with prettier --write .",
|
|
1924
|
+
"Check formatting without changing files with prettier --check .",
|
|
1925
|
+
"Format a specific file with prettier --write src/index.ts",
|
|
1926
|
+
],
|
|
1927
|
+
"gotchas": [
|
|
1928
|
+
"prettier --write modifies files in-place with no backup -- commit your changes before running",
|
|
1929
|
+
"Prettier is opinionated and has very few configuration options by design -- do not expect to customize every formatting decision",
|
|
1930
|
+
"Prettier and ESLint can conflict -- use eslint-config-prettier to disable ESLint rules that conflict with Prettier",
|
|
1931
|
+
],
|
|
1932
|
+
"related": ["eslint", "tsc"],
|
|
1933
|
+
"difficulty": "beginner",
|
|
1934
|
+
"extra_flags": {
|
|
1935
|
+
"--single-quote": "Use single quotes instead of double quotes",
|
|
1936
|
+
"--trailing-comma": "Print trailing commas (all, es5, none)",
|
|
1937
|
+
"--tab-width": "Set the number of spaces per indentation level",
|
|
1938
|
+
"--ignore-path": "Specify a file to read ignore patterns from",
|
|
1939
|
+
"--cache": "Only format changed files for faster execution",
|
|
1940
|
+
},
|
|
1941
|
+
},
|
|
1942
|
+
"jest": {
|
|
1943
|
+
"man_url": "https://jestjs.io/docs/cli",
|
|
1944
|
+
"use_cases": [
|
|
1945
|
+
"Run all tests with jest",
|
|
1946
|
+
"Run tests in watch mode during development with jest --watch",
|
|
1947
|
+
"Run tests matching a pattern with jest --testPathPattern='auth'",
|
|
1948
|
+
"Generate a coverage report with jest --coverage",
|
|
1949
|
+
],
|
|
1950
|
+
"gotchas": [
|
|
1951
|
+
"Jest runs tests in parallel by default -- tests that share state (databases, files) may fail intermittently. Use --runInBand for serial execution",
|
|
1952
|
+
"Jest uses its own module resolution that does not support ES modules natively -- configure transform with ts-jest or @swc/jest for TypeScript",
|
|
1953
|
+
"Jest's --coverage can significantly slow down test runs -- only use it in CI, not during development",
|
|
1954
|
+
],
|
|
1955
|
+
"related": ["eslint", "prettier", "node", "tsc"],
|
|
1956
|
+
"difficulty": "beginner",
|
|
1957
|
+
"extra_flags": {
|
|
1958
|
+
"--runInBand": "Run tests serially in the current process instead of parallel workers",
|
|
1959
|
+
"--verbose": "Display individual test results in a hierarchy",
|
|
1960
|
+
"--bail": "Stop running tests after N failures (default 0 = run all)",
|
|
1961
|
+
"--passWithNoTests": "Exit with 0 even if no tests are found",
|
|
1962
|
+
"--forceExit": "Force Jest to exit after all tests complete (kills dangling handles)",
|
|
1963
|
+
},
|
|
1964
|
+
},
|
|
1965
|
+
"pytest": {
|
|
1966
|
+
"man_url": "https://docs.pytest.org/en/stable/reference/reference.html",
|
|
1967
|
+
"use_cases": [
|
|
1968
|
+
"Run all tests in a project with pytest",
|
|
1969
|
+
"Run a specific test file with pytest tests/test_auth.py",
|
|
1970
|
+
"Run tests matching a keyword with pytest -k 'test_login and not slow'",
|
|
1971
|
+
"Generate an HTML coverage report with pytest --cov=src --cov-report=html",
|
|
1972
|
+
],
|
|
1973
|
+
"gotchas": [
|
|
1974
|
+
"pytest discovers tests automatically in files named test_*.py or *_test.py -- naming your test files differently will skip them silently",
|
|
1975
|
+
"Fixtures are powerful but can create implicit dependencies that are hard to trace -- use explicit fixture parameters",
|
|
1976
|
+
"pytest --cov requires the pytest-cov plugin to be installed -- it is not built into pytest",
|
|
1977
|
+
"Tests modify shared state (databases, files) at your peril -- pytest-xdist for parallel execution amplifies any shared-state bugs",
|
|
1978
|
+
],
|
|
1979
|
+
"related": ["python", "tox", "coverage"],
|
|
1980
|
+
"difficulty": "beginner",
|
|
1981
|
+
"extra_flags": {
|
|
1982
|
+
"-s": "Do not capture stdout/stderr (show print output during tests)",
|
|
1983
|
+
"-m": "Only run tests with specific markers (e.g., -m 'not slow')",
|
|
1984
|
+
"--tb": "Traceback style: short, long, line, native, no",
|
|
1985
|
+
"--lf": "Re-run only tests that failed last time",
|
|
1986
|
+
"--pdb": "Drop into the Python debugger on test failure",
|
|
1987
|
+
"-n": "Run tests in parallel with N workers (requires pytest-xdist)",
|
|
1988
|
+
},
|
|
1989
|
+
},
|
|
1990
|
+
"tsc": {
|
|
1991
|
+
"man_url": "https://www.typescriptlang.org/docs/handbook/compiler-options.html",
|
|
1992
|
+
"use_cases": [
|
|
1993
|
+
"Type-check a project without emitting files with tsc --noEmit",
|
|
1994
|
+
"Initialize a new TypeScript project with tsc --init",
|
|
1995
|
+
"Watch for changes and recompile with tsc -w",
|
|
1996
|
+
"Compile a single file with tsc script.ts",
|
|
1997
|
+
],
|
|
1998
|
+
"gotchas": [
|
|
1999
|
+
"tsc --noEmit is the standard way to use TypeScript for type checking only when a bundler (webpack, esbuild, vite) handles compilation",
|
|
2000
|
+
"tsc reads tsconfig.json by default -- command-line flags override tsconfig settings but file lists do not merge intuitively",
|
|
2001
|
+
"tsc does not bundle or minify -- it only transpiles TypeScript to JavaScript. Use a bundler for production builds",
|
|
2002
|
+
"strict: true in tsconfig.json enables all strict checks -- new projects should always start with this enabled",
|
|
2003
|
+
],
|
|
2004
|
+
"related": ["node", "eslint", "prettier", "jest"],
|
|
2005
|
+
"difficulty": "intermediate",
|
|
2006
|
+
"extra_flags": {
|
|
2007
|
+
"--strict": "Enable all strict type-checking options",
|
|
2008
|
+
"--outDir": "Redirect output structure to the specified directory",
|
|
2009
|
+
"--target": "Set the JavaScript language version for output (es2015, es2020, esnext)",
|
|
2010
|
+
"--module": "Set the module system (commonjs, esnext, nodenext)",
|
|
2011
|
+
"--declaration": "Generate .d.ts declaration files",
|
|
2012
|
+
"--sourceMap": "Generate source map files for debugging",
|
|
2013
|
+
"-b": "Build mode for project references",
|
|
2014
|
+
},
|
|
2015
|
+
},
|
|
2016
|
+
}
|