@hybridlabor-api/aos 4.7.2 → 4.9.0

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.
Files changed (166) hide show
  1. package/.agents/agents.md +1 -1
  2. package/.agents/nodes.json +1 -1
  3. package/.agents/vendor-manifest.json +23 -1
  4. package/.claude/agents/godmode-media-eventtech.md +1 -1
  5. package/.claude/hooks/conventional-commits.mjs +125 -0
  6. package/.claude/hooks/env-file-protection.mjs +105 -0
  7. package/.claude/hooks/go-gate.mjs +101 -81
  8. package/.claude/settings.json +13 -0
  9. package/.opencode/agents/godmode-media-eventtech.md +1 -1
  10. package/.opencode/plugins/bdb-aos.js +31 -4
  11. package/README.de.md +1 -1
  12. package/README.md +1 -1
  13. package/README.pt.md +1 -1
  14. package/THIRD_PARTY_NOTICES.md +88 -0
  15. package/docs/skills_table.md +1 -1
  16. package/installer.js +309 -101
  17. package/package.json +6 -2
  18. package/packages/aos-cli/README.md +80 -0
  19. package/packages/aos-cli/bin/aos-cli.mjs +134 -0
  20. package/packages/aos-cli/core-skills.json +12 -0
  21. package/packages/aos-cli/extensions/aos.ts +321 -0
  22. package/packages/aos-cli/package-lock.json +1923 -0
  23. package/packages/aos-cli/package.json +29 -0
  24. package/packages/aos-cli/scripts/check-theme.mjs +63 -0
  25. package/packages/aos-cli/themes/aos.json +97 -0
  26. package/scripts/build-plugin-manifest.mjs +131 -0
  27. package/scripts/validate-skills.mjs +81 -6
  28. package/skills/basic/ao-orchestrator/SKILL.md +116 -0
  29. package/skills/global_config/agenttrail/SKILL.md +6 -1
  30. package/skills/global_config/ask-tim/SKILL.md +4 -4
  31. package/skills/global_config/bash-script-generator/SKILL.md +201 -0
  32. package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
  33. package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
  34. package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
  35. package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
  36. package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
  37. package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
  38. package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
  39. package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
  40. package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
  41. package/skills/global_config/bash-script-validator/SKILL.md +249 -0
  42. package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
  43. package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
  44. package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
  45. package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
  46. package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
  47. package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
  48. package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
  49. package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
  50. package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
  51. package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
  52. package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
  53. package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
  54. package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
  55. package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
  56. package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
  57. package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
  58. package/skills/global_config/ci-pipeline/SKILL.md +135 -0
  59. package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
  60. package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
  61. package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
  62. package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
  63. package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
  64. package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
  65. package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
  66. package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
  67. package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
  68. package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
  69. package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
  70. package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
  71. package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
  72. package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
  73. package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
  74. package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
  75. package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
  76. package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
  77. package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
  78. package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
  79. package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
  80. package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
  81. package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
  82. package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
  83. package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
  84. package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
  85. package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
  86. package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
  87. package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
  88. package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
  89. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
  90. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
  91. package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
  92. package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
  93. package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
  94. package/skills/global_config/github-actions-generator/SKILL.md +353 -0
  95. package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
  96. package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
  97. package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
  98. package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
  99. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
  100. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
  101. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
  102. package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
  103. package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
  104. package/skills/global_config/github-actions-generator/examples/README.md +147 -0
  105. package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
  106. package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
  107. package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
  108. package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
  109. package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
  110. package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
  111. package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
  112. package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
  113. package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
  114. package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
  115. package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
  116. package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
  117. package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
  118. package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
  119. package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
  120. package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
  121. package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
  122. package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
  123. package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
  124. package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
  125. package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
  126. package/skills/global_config/github-actions-templates/SKILL.md +7 -0
  127. package/skills/global_config/github-actions-validator/SKILL.md +576 -0
  128. package/skills/global_config/github-actions-validator/examples/README.md +88 -0
  129. package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
  130. package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
  131. package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
  132. package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
  133. package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
  134. package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
  135. package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
  136. package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
  137. package/skills/global_config/github-actions-validator/references/runners.md +317 -0
  138. package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
  139. package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
  140. package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
  141. package/skills/global_config/makefile-generator/SKILL.md +614 -0
  142. package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
  143. package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
  144. package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
  145. package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
  146. package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
  147. package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
  148. package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
  149. package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
  150. package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
  151. package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
  152. package/skills/global_config/makefile-validator/SKILL.md +244 -0
  153. package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
  154. package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
  155. package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
  156. package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
  157. package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
  158. package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
  159. package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
  160. package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
  161. package/skills/global_config/requesting-code-review/SKILL.md +98 -0
  162. package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
  163. package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
  164. package/skills/global_config/verification-before-completion/SKILL.md +123 -0
  165. package/skills/global_config/writing-plans/SKILL.md +126 -46
  166. package/skills/global_config/writing-plans-legacy/SKILL.md +139 -0
@@ -0,0 +1,729 @@
1
+ # Bash Scripting Guide
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Introduction](#introduction)
6
+ 2. [Bash vs POSIX sh](#bash-vs-posix-sh)
7
+ 3. [Strict Mode and Error Handling](#strict-mode-and-error-handling)
8
+ 4. [Variables and Parameter Expansion](#variables-and-parameter-expansion)
9
+ 5. [Functions and Scope](#functions-and-scope)
10
+ 6. [Arrays and Associative Arrays](#arrays-and-associative-arrays)
11
+ 7. [Control Structures](#control-structures)
12
+ 8. [Process and Command Substitution](#process-and-command-substitution)
13
+ 9. [Best Practices](#best-practices)
14
+ 10. [Common Pitfalls](#common-pitfalls)
15
+
16
+ ## Introduction
17
+
18
+ Bash (Bourne Again Shell) is a powerful Unix shell and command language. This guide covers modern bash scripting practices and patterns for creating robust, maintainable scripts.
19
+
20
+ ## Bash vs POSIX sh
21
+
22
+ ### Key Differences
23
+
24
+ **Bash-specific features (not in POSIX sh):**
25
+ - Arrays: `arr=(one two three)`
26
+ - Associative arrays: `declare -A map=([key]=value)`
27
+ - `[[` conditional expressions
28
+ - `$(( ))` arithmetic expansion with more operators
29
+ - `${var//pattern/replacement}` parameter expansion
30
+ - Process substitution: `<(command)`
31
+ - `select` keyword for menus
32
+ - `**` recursive globbing with `shopt -s globstar`
33
+
34
+ **POSIX sh compatible:**
35
+ - Basic variable assignment and substitution
36
+ - `[` test command (single brackets)
37
+ - `case` statements
38
+ - Basic parameter expansion
39
+ - Command substitution with `$()`
40
+ - Functions (with different syntax)
41
+
42
+ ### When to Choose
43
+
44
+ **Use Bash when:**
45
+ - Script runs on modern Linux/macOS systems
46
+ - Need arrays or associative arrays
47
+ - Want advanced string manipulation
48
+ - Targeting bash-specific environments
49
+
50
+ **Use POSIX sh when:**
51
+ - Maximum portability required
52
+ - Running on minimal systems (embedded, containers)
53
+ - Need to run on different Unix variants
54
+ - Following strict POSIX compliance requirements
55
+
56
+ ## Strict Mode and Error Handling
57
+
58
+ ### Essential: set -euo pipefail
59
+
60
+ ```bash
61
+ #!/usr/bin/env bash
62
+ set -euo pipefail
63
+ IFS=$'\n\t'
64
+ ```
65
+
66
+ **Explanation:**
67
+ - `set -e` (errexit): Exit immediately if a command exits with non-zero status
68
+ - `set -u` (nounset): Treat unset variables as an error
69
+ - `set -o pipefail`: Return value of pipeline is status of last command to exit with non-zero status
70
+ - `IFS=$'\n\t'`: Set Internal Field Separator to newline and tab only (prevents word splitting issues)
71
+
72
+ ### When to Disable Strict Mode Temporarily
73
+
74
+ ```bash
75
+ # Disable errexit for commands that are expected to fail
76
+ set +e
77
+ command_that_might_fail
78
+ exit_code=$?
79
+ set -e
80
+
81
+ # Or use || true for single commands
82
+ command_that_might_fail || true
83
+
84
+ # Or handle error explicitly
85
+ if ! command_that_might_fail; then
86
+ echo "Command failed, but continuing..."
87
+ fi
88
+ ```
89
+
90
+ ### Signal Handling with trap
91
+
92
+ ```bash
93
+ # Cleanup function
94
+ cleanup() {
95
+ local exit_code=$?
96
+ echo "Cleaning up..." >&2
97
+ rm -f "${temp_file}"
98
+ exit "${exit_code}"
99
+ }
100
+
101
+ # Set traps
102
+ trap cleanup EXIT # Always run cleanup on exit
103
+ trap cleanup ERR # Run cleanup on error
104
+ trap cleanup INT TERM # Run cleanup on interrupt or termination
105
+
106
+ # Create temp file
107
+ temp_file=$(mktemp)
108
+
109
+ # Rest of script...
110
+ ```
111
+
112
+ ### Error Handling Patterns
113
+
114
+ ```bash
115
+ # Pattern 1: Die function
116
+ die() {
117
+ echo "ERROR: $*" >&2
118
+ exit 1
119
+ }
120
+
121
+ [[ -f "${file}" ]] || die "File not found: ${file}"
122
+
123
+ # Pattern 2: Check function return values
124
+ if ! do_something; then
125
+ echo "do_something failed" >&2
126
+ return 1
127
+ fi
128
+
129
+ # Pattern 3: Command substitution with error handling
130
+ output=$(command 2>&1) || {
131
+ echo "Command failed: ${output}" >&2
132
+ exit 1
133
+ }
134
+
135
+ # Pattern 4: Validate prerequisites
136
+ check_command() {
137
+ command -v "$1" &> /dev/null || die "Required command not found: $1"
138
+ }
139
+
140
+ check_command "jq"
141
+ check_command "curl"
142
+ ```
143
+
144
+ ## Variables and Parameter Expansion
145
+
146
+ ### Variable Naming Conventions
147
+
148
+ ```bash
149
+ # Constants - uppercase with readonly
150
+ readonly MAX_RETRIES=3
151
+ readonly CONFIG_FILE="/etc/myapp/config.conf"
152
+
153
+ # Environment variables - uppercase
154
+ export PATH="${HOME}/bin:${PATH}"
155
+ export LOG_LEVEL="INFO"
156
+
157
+ # Local variables - lowercase
158
+ local counter=0
159
+ local temp_file=""
160
+
161
+ # Function names - lowercase with underscores
162
+ process_data() {
163
+ local input="$1"
164
+ # ...
165
+ }
166
+ ```
167
+
168
+ ### Always Quote Variables
169
+
170
+ ```bash
171
+ # Good - properly quoted
172
+ rm "${file}"
173
+ cp "${source}" "${destination}"
174
+ echo "Value: ${variable}"
175
+
176
+ # Bad - unquoted (prone to word splitting and globbing)
177
+ rm $file
178
+ cp $source $destination
179
+ echo "Value: $variable"
180
+ ```
181
+
182
+ ### Parameter Expansion
183
+
184
+ ```bash
185
+ # Default values
186
+ ${var:-default} # Use default if var is unset or empty
187
+ ${var:=default} # Set var to default if unset or empty
188
+ ${var:?error message} # Exit with error message if var is unset or empty
189
+ ${var:+alternative} # Use alternative if var is set
190
+
191
+ # String manipulation
192
+ ${var#pattern} # Remove shortest match from beginning
193
+ ${var##pattern} # Remove longest match from beginning
194
+ ${var%pattern} # Remove shortest match from end
195
+ ${var%%pattern} # Remove longest match from end
196
+ ${var/pattern/replacement} # Replace first match
197
+ ${var//pattern/replacement} # Replace all matches
198
+ ${var^} # Uppercase first character
199
+ ${var^^} # Uppercase all characters
200
+ ${var,} # Lowercase first character
201
+ ${var,,} # Lowercase all characters
202
+
203
+ # Length and substring
204
+ ${#var} # Length of var
205
+ ${var:offset} # Substring from offset to end
206
+ ${var:offset:length} # Substring from offset with length
207
+
208
+ # Examples
209
+ file="/path/to/file.txt"
210
+ ${file##*/} # file.txt (basename)
211
+ ${file%.*} # /path/to/file (remove extension)
212
+ ${file##*.} # txt (extension only)
213
+ ${file%/*} # /path/to (dirname)
214
+ ```
215
+
216
+ ## Functions and Scope
217
+
218
+ ### Function Definition
219
+
220
+ ```bash
221
+ # POSIX style (portable)
222
+ function_name() {
223
+ # function body
224
+ }
225
+
226
+ # Bash-specific (not portable to sh)
227
+ function function_name {
228
+ # function body
229
+ }
230
+
231
+ # Recommended: POSIX style with local variables
232
+ process_file() {
233
+ local input_file="$1"
234
+ local output_file="$2"
235
+
236
+ # Process file
237
+ grep "pattern" "${input_file}" > "${output_file}"
238
+ }
239
+ ```
240
+
241
+ ### Variable Scope
242
+
243
+ ```bash
244
+ # Global variable
245
+ GLOBAL_VAR="global"
246
+
247
+ my_function() {
248
+ # Local variable - only visible in function
249
+ local local_var="local"
250
+
251
+ # Modifying global variable
252
+ GLOBAL_VAR="modified"
253
+
254
+ # Function parameter access
255
+ local param1="$1"
256
+ local param2="$2"
257
+
258
+ echo "Params: ${param1} ${param2}"
259
+ }
260
+
261
+ my_function "arg1" "arg2"
262
+ ```
263
+
264
+ ### Return Values
265
+
266
+ ```bash
267
+ # Functions return exit status (0-255)
268
+ check_file() {
269
+ local file="$1"
270
+ [[ -f "${file}" ]] && return 0 || return 1
271
+ }
272
+
273
+ # Use function return status
274
+ if check_file "data.txt"; then
275
+ echo "File exists"
276
+ fi
277
+
278
+ # Return data via stdout
279
+ get_value() {
280
+ echo "computed value"
281
+ }
282
+
283
+ # Capture output
284
+ result=$(get_value)
285
+
286
+ # Return data via variable (using nameref in bash 4.3+)
287
+ get_data() {
288
+ local -n result_var=$1
289
+ result_var="computed value"
290
+ }
291
+
292
+ get_data my_result
293
+ echo "${my_result}"
294
+ ```
295
+
296
+ ## Arrays and Associative Arrays
297
+
298
+ ### Indexed Arrays (Bash-specific)
299
+
300
+ ```bash
301
+ # Array creation
302
+ arr=() # Empty array
303
+ arr=(one two three) # Initialize with values
304
+ arr[0]="first" # Assign to specific index
305
+
306
+ # Array operations
307
+ arr+=("four") # Append
308
+ ${arr[0]} # Access element
309
+ ${arr[@]} # All elements (as separate words)
310
+ ${arr[*]} # All elements (as single word)
311
+ ${#arr[@]} # Number of elements
312
+ ${!arr[@]} # Indices
313
+
314
+ # Iterating over array
315
+ for item in "${arr[@]}"; do
316
+ echo "${item}"
317
+ done
318
+
319
+ # Iterating with indices
320
+ for i in "${!arr[@]}"; do
321
+ echo "Index $i: ${arr[i]}"
322
+ done
323
+
324
+ # Array slicing
325
+ ${arr[@]:offset:length} # Slice array
326
+
327
+ # Remove element
328
+ unset 'arr[1]' # Remove specific element
329
+ ```
330
+
331
+ ### Associative Arrays (Bash 4.0+)
332
+
333
+ ```bash
334
+ # Declaration required
335
+ declare -A map
336
+
337
+ # Assignment
338
+ map[key1]="value1"
339
+ map[key2]="value2"
340
+
341
+ # Or initialize
342
+ declare -A map=([key1]="value1" [key2]="value2")
343
+
344
+ # Access
345
+ ${map[key1]} # Get value
346
+ ${map[@]} # All values
347
+ ${!map[@]} # All keys
348
+ ${#map[@]} # Number of elements
349
+
350
+ # Check if key exists
351
+ if [[ -v map[key1] ]]; then
352
+ echo "key1 exists"
353
+ fi
354
+
355
+ # Iterate over keys and values
356
+ for key in "${!map[@]}"; do
357
+ echo "${key}: ${map[${key}]}"
358
+ done
359
+ ```
360
+
361
+ ### POSIX Alternative to Arrays
362
+
363
+ ```bash
364
+ # Use positional parameters
365
+ set -- one two three
366
+
367
+ # Access
368
+ echo "$1" # one
369
+ echo "$2" # two
370
+ echo "$#" # count: 3
371
+
372
+ # Iterate
373
+ for item in "$@"; do
374
+ echo "${item}"
375
+ done
376
+
377
+ # Add item
378
+ set -- "$@" "four"
379
+
380
+ # Remove first item
381
+ shift
382
+ ```
383
+
384
+ ## Control Structures
385
+
386
+ ### Conditional Expressions
387
+
388
+ ```bash
389
+ # Bash [[ ... ]] (recommended for bash)
390
+ if [[ -f "${file}" ]]; then
391
+ echo "File exists"
392
+ fi
393
+
394
+ if [[ "${var}" == "value" ]]; then
395
+ echo "Match"
396
+ fi
397
+
398
+ if [[ "${var}" =~ ^[0-9]+$ ]]; then
399
+ echo "Numeric"
400
+ fi
401
+
402
+ # POSIX [ ... ] (portable)
403
+ if [ -f "${file}" ]; then
404
+ echo "File exists"
405
+ fi
406
+
407
+ # File tests
408
+ [[ -e file ]] # Exists
409
+ [[ -f file ]] # Regular file
410
+ [[ -d file ]] # Directory
411
+ [[ -L file ]] # Symbolic link
412
+ [[ -r file ]] # Readable
413
+ [[ -w file ]] # Writable
414
+ [[ -x file ]] # Executable
415
+ [[ -s file ]] # Not empty
416
+
417
+ # String tests
418
+ [[ -z "${var}" ]] # Empty string
419
+ [[ -n "${var}" ]] # Non-empty string
420
+ [[ "${a}" == "${b}" ]] # Equal
421
+ [[ "${a}" != "${b}" ]] # Not equal
422
+ [[ "${a}" < "${b}" ]] # Lexicographically less (bash only)
423
+
424
+ # Numeric tests
425
+ [[ "${a}" -eq "${b}" ]] # Equal
426
+ [[ "${a}" -ne "${b}" ]] # Not equal
427
+ [[ "${a}" -lt "${b}" ]] # Less than
428
+ [[ "${a}" -le "${b}" ]] # Less than or equal
429
+ [[ "${a}" -gt "${b}" ]] # Greater than
430
+ [[ "${a}" -ge "${b}" ]] # Greater than or equal
431
+
432
+ # Logical operators
433
+ [[ condition1 && condition2 ]] # AND
434
+ [[ condition1 || condition2 ]] # OR
435
+ [[ ! condition ]] # NOT
436
+ ```
437
+
438
+ ### case Statements
439
+
440
+ ```bash
441
+ case "${var}" in
442
+ pattern1)
443
+ # commands
444
+ ;;
445
+ pattern2|pattern3)
446
+ # Multiple patterns
447
+ ;;
448
+ *)
449
+ # Default case
450
+ ;;
451
+ esac
452
+
453
+ # Example with patterns
454
+ case "${file}" in
455
+ *.txt)
456
+ echo "Text file"
457
+ ;;
458
+ *.jpg|*.png)
459
+ echo "Image file"
460
+ ;;
461
+ *)
462
+ echo "Unknown type"
463
+ ;;
464
+ esac
465
+ ```
466
+
467
+ ### Loops
468
+
469
+ ```bash
470
+ # while loop
471
+ while condition; do
472
+ # commands
473
+ done
474
+
475
+ # until loop
476
+ until condition; do
477
+ # commands
478
+ done
479
+
480
+ # for loop (C-style, bash only)
481
+ for ((i=0; i<10; i++)); do
482
+ echo "${i}"
483
+ done
484
+
485
+ # for loop (iterating over values)
486
+ for item in one two three; do
487
+ echo "${item}"
488
+ done
489
+
490
+ # for loop (iterating over files)
491
+ for file in *.txt; do
492
+ echo "${file}"
493
+ done
494
+
495
+ # for loop (iterating over command output)
496
+ while IFS= read -r line; do
497
+ echo "${line}"
498
+ done < file.txt
499
+
500
+ # Or with command substitution (avoid for large output)
501
+ for file in $(find . -name "*.txt"); do
502
+ echo "${file}"
503
+ done
504
+ ```
505
+
506
+ ## Process and Command Substitution
507
+
508
+ ### Command Substitution
509
+
510
+ ```bash
511
+ # Recommended: $( ... )
512
+ result=$(command)
513
+ result=$(command arg1 arg2)
514
+
515
+ # Nested command substitution
516
+ outer=$(echo "Inner: $(echo "value")")
517
+
518
+ # Not recommended: backticks (legacy)
519
+ result=`command`
520
+ ```
521
+
522
+ ### Process Substitution (Bash-specific)
523
+
524
+ ```bash
525
+ # <( ... ) creates a named pipe/file descriptor
526
+ # Treat command output as a file
527
+
528
+ # Compare output of two commands
529
+ diff <(ls dir1) <(ls dir2)
530
+
531
+ # Use multiple inputs
532
+ paste <(cut -f1 file1) <(cut -f2 file2)
533
+
534
+ # Output redirection with process substitution
535
+ command > >(tee stdout.log) 2> >(tee stderr.log >&2)
536
+ ```
537
+
538
+ ## Best Practices
539
+
540
+ ### Script Structure
541
+
542
+ ```bash
543
+ #!/usr/bin/env bash
544
+ set -euo pipefail
545
+ IFS=$'\n\t'
546
+
547
+ # ============================================================================
548
+ # Script Name: example.sh
549
+ # Description: Brief description
550
+ # Author: Your Name
551
+ # Created: 2025-01-23
552
+ # ============================================================================
553
+
554
+ # Constants
555
+ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
556
+ readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
557
+
558
+ # Global variables
559
+ VERBOSE=false
560
+ DRY_RUN=false
561
+
562
+ # Functions
563
+ usage() {
564
+ # ...
565
+ }
566
+
567
+ cleanup() {
568
+ # ...
569
+ }
570
+
571
+ main() {
572
+ # ...
573
+ }
574
+
575
+ # Signal handlers
576
+ trap cleanup EXIT ERR INT TERM
577
+
578
+ # Execute main
579
+ main "$@"
580
+ ```
581
+
582
+ ### Always Use Quotes
583
+
584
+ ```bash
585
+ # Good
586
+ echo "${variable}"
587
+ cp "${source}" "${dest}"
588
+ [[ -f "${file}" ]]
589
+
590
+ # Bad (unsafe)
591
+ echo $variable
592
+ cp $source $dest
593
+ [[ -f $file ]]
594
+ ```
595
+
596
+ ### Use readonly for Constants
597
+
598
+ ```bash
599
+ readonly MAX_RETRIES=3
600
+ readonly CONFIG_FILE="/etc/config"
601
+ ```
602
+
603
+ ### Prefer $() Over Backticks
604
+
605
+ ```bash
606
+ # Good
607
+ output=$(command)
608
+ result=$(first $(second))
609
+
610
+ # Bad
611
+ output=`command`
612
+ result=`first \`second\`` # Hard to read
613
+ ```
614
+
615
+ ### Check Command Existence
616
+
617
+ ```bash
618
+ if ! command -v required_cmd &> /dev/null; then
619
+ echo "Error: required_cmd not found" >&2
620
+ exit 1
621
+ fi
622
+ ```
623
+
624
+ ### Validate Inputs
625
+
626
+ ```bash
627
+ # Check argument count
628
+ if [[ $# -lt 1 ]]; then
629
+ echo "Usage: $0 <file>" >&2
630
+ exit 1
631
+ fi
632
+
633
+ # Validate file exists
634
+ [[ -f "${file}" ]] || { echo "File not found: ${file}" >&2; exit 1; }
635
+
636
+ # Validate numeric input
637
+ [[ "${count}" =~ ^[0-9]+$ ]] || { echo "Count must be numeric" >&2; exit 1; }
638
+ ```
639
+
640
+ ## Common Pitfalls
641
+
642
+ ### Word Splitting
643
+
644
+ ```bash
645
+ # Problem: Filename with spaces
646
+ file="my file.txt"
647
+ rm $file # Tries to remove "my" and "file.txt"
648
+
649
+ # Solution: Quote variables
650
+ rm "${file}" # Correctly removes "my file.txt"
651
+ ```
652
+
653
+ ### Globbing
654
+
655
+ ```bash
656
+ # Problem: Pattern in variable
657
+ pattern="*.txt"
658
+ echo $pattern # Expands to list of .txt files
659
+
660
+ # Solution: Quote to prevent globbing
661
+ echo "${pattern}" # Prints "*.txt"
662
+ ```
663
+
664
+ ### Useless Use of Cat (UUOC)
665
+
666
+ ```bash
667
+ # Bad: Unnecessary cat
668
+ cat file.txt | grep "pattern"
669
+
670
+ # Good: Direct input
671
+ grep "pattern" file.txt
672
+
673
+ # Bad: cat in loop
674
+ cat file.txt | while read line; do
675
+ echo "${line}"
676
+ done
677
+
678
+ # Good: redirect to while
679
+ while read -r line; do
680
+ echo "${line}"
681
+ done < file.txt
682
+ ```
683
+
684
+ ### Not Handling Spaces in Filenames
685
+
686
+ ```bash
687
+ # Bad: Will break on filenames with spaces
688
+ for file in $(find . -name "*.txt"); do
689
+ process "${file}"
690
+ done
691
+
692
+ # Good: Use while read
693
+ find . -name "*.txt" -print0 | while IFS= read -r -d '' file; do
694
+ process "${file}"
695
+ done
696
+
697
+ # Or use globbing
698
+ for file in ./**/*.txt; do
699
+ process "${file}"
700
+ done
701
+ ```
702
+
703
+ ### Ignoring Command Exit Status
704
+
705
+ ```bash
706
+ # Bad: Ignoring failure
707
+ command_that_might_fail
708
+ next_command
709
+
710
+ # Good: Check exit status
711
+ if command_that_might_fail; then
712
+ next_command
713
+ else
714
+ echo "Command failed" >&2
715
+ exit 1
716
+ fi
717
+
718
+ # Or with errexit
719
+ command_that_might_fail || { echo "Failed" >&2; exit 1; }
720
+ ```
721
+
722
+ ---
723
+
724
+ ## References
725
+
726
+ - [GNU Bash Manual](https://www.gnu.org/software/bash/manual/bash.html)
727
+ - [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html)
728
+ - [ShellCheck](https://www.shellcheck.net/) - Script analysis tool
729
+ - [Bash Guide for Beginners](https://tldp.org/LDP/Bash-Beginners-Guide/html/)