fd_demo.sh

Download
bash 288 lines 5.8 KB
  1#!/usr/bin/env bash
  2set -euo pipefail
  3
  4# File Descriptor Demonstrations
  5# Shows advanced usage of file descriptors for I/O redirection
  6
  7echo "=== File Descriptor Demonstrations ==="
  8echo
  9
 10# --- Demo 1: Custom file descriptors ---
 11demo_custom_fd() {
 12    echo "1. Custom File Descriptors"
 13    echo "--------------------------"
 14
 15    local output_file="/tmp/fd_demo_output.txt"
 16    local error_file="/tmp/fd_demo_error.txt"
 17
 18    # Open custom file descriptors
 19    exec 3>"$output_file"  # FD 3 for normal output
 20    exec 4>"$error_file"   # FD 4 for error output
 21
 22    echo "Writing to FD 3 (output file)" >&3
 23    echo "Writing to FD 4 (error file)" >&4
 24
 25    echo "More output data" >&3
 26    echo "More error data" >&4
 27
 28    # Close custom file descriptors
 29    exec 3>&-
 30    exec 4>&-
 31
 32    echo "Files created:"
 33    echo "  Output file: $output_file"
 34    cat "$output_file"
 35
 36    echo
 37    echo "  Error file: $error_file"
 38    cat "$error_file"
 39
 40    # Cleanup
 41    rm -f "$output_file" "$error_file"
 42
 43    echo
 44}
 45
 46# --- Demo 2: Redirecting stderr separately ---
 47demo_separate_stderr() {
 48    echo "2. Redirecting Stderr Separately"
 49    echo "---------------------------------"
 50
 51    local stdout_file="/tmp/stdout.txt"
 52    local stderr_file="/tmp/stderr.txt"
 53
 54    # Function that outputs to both stdout and stderr
 55    mixed_output() {
 56        echo "This goes to stdout"
 57        echo "This goes to stderr" >&2
 58        echo "More stdout"
 59        echo "More stderr" >&2
 60    }
 61
 62    echo "Calling function with mixed output..."
 63    mixed_output 1>"$stdout_file" 2>"$stderr_file"
 64
 65    echo
 66    echo "STDOUT contents:"
 67    cat "$stdout_file"
 68
 69    echo
 70    echo "STDERR contents:"
 71    cat "$stderr_file"
 72
 73    # Cleanup
 74    rm -f "$stdout_file" "$stderr_file"
 75
 76    echo
 77}
 78
 79# --- Demo 3: Swapping stdout and stderr ---
 80demo_swap_stdout_stderr() {
 81    echo "3. Swapping Stdout and Stderr"
 82    echo "-----------------------------"
 83
 84    # Function with mixed output
 85    test_output() {
 86        echo "STDOUT message"
 87        echo "STDERR message" >&2
 88    }
 89
 90    echo "Normal output:"
 91    test_output 2>&1 | sed 's/^/  /'
 92
 93    echo
 94    echo "With stdout and stderr swapped (3>&1 1>&2 2>&3):"
 95    (test_output 3>&1 1>&2 2>&3) 2>&1 | sed 's/^/  /'
 96
 97    echo
 98}
 99
100# --- Demo 4: Logging to both console and file ---
101demo_tee_with_fd() {
102    echo "4. Logging to Console and File Simultaneously"
103    echo "----------------------------------------------"
104
105    local log_file="/tmp/dual_output.log"
106
107    # Open log file on FD 3
108    exec 3>"$log_file"
109
110    # Function to log to both console and file
111    dual_log() {
112        local message="$*"
113        echo "$message" | tee /dev/fd/3
114    }
115
116    dual_log "This message appears on console and in log file"
117    dual_log "Second message"
118    dual_log "Third message"
119
120    # Close log file
121    exec 3>&-
122
123    echo
124    echo "Log file contents:"
125    cat "$log_file"
126
127    # Cleanup
128    rm -f "$log_file"
129
130    echo
131}
132
133# --- Demo 5: Reading from and writing to same file descriptor ---
134demo_readwrite_fd() {
135    echo "5. Read/Write File Descriptor"
136    echo "-----------------------------"
137
138    local data_file="/tmp/rw_data.txt"
139
140    # Create initial data
141    cat > "$data_file" << EOF
142Line 1: Original
143Line 2: Original
144Line 3: Original
145EOF
146
147    echo "Original file:"
148    cat "$data_file"
149
150    echo
151    echo "Opening file for read/write on FD 3..."
152
153    # Open file for reading and writing
154    exec 3<> "$data_file"
155
156    # Read first line
157    read -r line <&3
158    echo "Read: $line"
159
160    # Write to file (appends)
161    echo "Line 4: Added via FD 3" >&3
162
163    # Close FD
164    exec 3>&-
165
166    echo
167    echo "Modified file:"
168    cat "$data_file"
169
170    # Cleanup
171    rm -f "$data_file"
172
173    echo
174}
175
176# --- Demo 6: Saving and restoring stdout ---
177demo_save_restore_stdout() {
178    echo "6. Saving and Restoring Stdout"
179    echo "-------------------------------"
180
181    local temp_file="/tmp/redirected_output.txt"
182
183    echo "This goes to original stdout"
184
185    # Save original stdout to FD 6
186    exec 6>&1
187
188    # Redirect stdout to file
189    exec 1>"$temp_file"
190
191    echo "This goes to the file (not visible on console)"
192    echo "Another line to the file"
193
194    # Restore original stdout
195    exec 1>&6
196
197    # Close FD 6
198    exec 6>&-
199
200    echo "This goes to original stdout again"
201
202    echo
203    echo "File contents:"
204    cat "$temp_file"
205
206    # Cleanup
207    rm -f "$temp_file"
208
209    echo
210}
211
212# --- Demo 7: Here-document with file descriptor ---
213demo_heredoc_fd() {
214    echo "7. Here-document with File Descriptor"
215    echo "--------------------------------------"
216
217    # Assign here-document to FD 3
218    exec 3<<EOF
219First line from here-doc
220Second line from here-doc
221Third line from here-doc
222EOF
223
224    echo "Reading from here-document via FD 3:"
225    while IFS= read -r line <&3; do
226        echo "  > $line"
227    done
228
229    # Close FD 3
230    exec 3>&-
231
232    echo
233}
234
235# --- Demo 8: Noclobber and forcing overwrite ---
236demo_noclobber() {
237    echo "8. Noclobber and Forcing Overwrite"
238    echo "-----------------------------------"
239
240    local test_file="/tmp/noclobber_test.txt"
241
242    echo "Original content" > "$test_file"
243
244    # Enable noclobber
245    set -C
246
247    echo "Noclobber enabled (set -C)"
248    echo "Trying to overwrite existing file..."
249
250    if echo "Overwrite attempt" > "$test_file" 2>/dev/null; then
251        echo "  ✗ Should have failed!"
252    else
253        echo "  ✓ Prevented overwrite (as expected)"
254    fi
255
256    echo "Forcing overwrite with >|..."
257    echo "Forced overwrite" >| "$test_file"
258    echo "  ✓ Success"
259
260    # Disable noclobber
261    set +C
262
263    echo "Noclobber disabled (set +C)"
264    echo "Normal overwrite works again" > "$test_file"
265    echo "  ✓ Overwrite successful"
266
267    # Cleanup
268    rm -f "$test_file"
269
270    echo
271}
272
273# Main execution
274main() {
275    demo_custom_fd
276    demo_separate_stderr
277    demo_swap_stdout_stderr
278    demo_tee_with_fd
279    demo_readwrite_fd
280    demo_save_restore_stdout
281    demo_heredoc_fd
282    demo_noclobber
283
284    echo "=== All Demos Complete ==="
285}
286
287main "$@"