|
|
article-athas-shell-redirections.mw - tgtimes - The Gopher Times |
|
|
 |
git clone git://bitreich.org/tgtimes git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/tgtimes (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
|
--- |
|
|
|
article-athas-shell-redirections.mw (2204B) |
|
|
|
--- |
|
|
|
1 .SH athas |
|
|
|
2 Shell Redirections |
|
|
|
3 . |
|
|
|
4 .PP |
|
|
|
5 Newcomers to the Unix shell quickly encounter handy tools such as |
|
|
|
6 sed(1) and sort(1). This command prints the lines of the given file |
|
|
|
7 to stdout, in sorted order: |
|
|
|
8 . |
|
|
|
9 .DS |
|
|
|
10 $ sort numbers |
|
|
|
11 .DE |
|
|
|
12 . |
|
|
|
13 .PP |
|
|
|
14 Soon after, newcomers will also encounter shell redirection, by which |
|
|
|
15 the output of these tools can conveniently be read from or stored in |
|
|
|
16 files: |
|
|
|
17 . |
|
|
|
18 .DS |
|
|
|
19 $ sort < numbers > numbers_sorted |
|
|
|
20 .DE |
|
|
|
21 . |
|
|
|
22 .PP |
|
|
|
23 Our new user, fascinated by the modularity of the Unix shell, may then |
|
|
|
24 try the rather obvious possibility of having the input and output file |
|
|
|
25 be the same: |
|
|
|
26 . |
|
|
|
27 .DS |
|
|
|
28 $ sort < numbers > numbers |
|
|
|
29 .DE |
|
|
|
30 . |
|
|
|
31 .PP |
|
|
|
32 But disaster strikes: the file is empty! The user has lost their |
|
|
|
33 precious collection of numbers - let's hope they had a backup. Losing |
|
|
|
34 data this way is almost a rite of passage for Unix users, but let us |
|
|
|
35 spell out the reason for those who have yet to hurt themselves this |
|
|
|
36 way. |
|
|
|
37 . |
|
|
|
38 .PP |
|
|
|
39 When the Unix shell evaluates a command, it starts by processing the |
|
|
|
40 redirection operators - that's the '>' and '<' above. While '<' just |
|
|
|
41 opens the file, '>' *truncates* the file in-place as it is opened for |
|
|
|
42 reading! This means that the 'sort' process will dutifully read an |
|
|
|
43 empty file, sort its non-existent lines, and correctly produce empty |
|
|
|
44 output. |
|
|
|
45 . |
|
|
|
46 .PP |
|
|
|
47 Some programs can be asked to write their output directly to files |
|
|
|
48 instead of using shell redirection (sed(1) has '-i', and for sort(1) |
|
|
|
49 we can use '-o'), but this is not a general solution, and does not |
|
|
|
50 work for pipelines. Another solution is to use the sponge(1) tool |
|
|
|
51 from the "moreutils" project, which stores its standard input in |
|
|
|
52 memory before finally writing it to a file: |
|
|
|
53 . |
|
|
|
54 .DS |
|
|
|
55 $ sort < numbers | sponge numbers |
|
|
|
56 .DE |
|
|
|
57 . |
|
|
|
58 .PP |
|
|
|
59 The most interesting solution is to take advantage of subshells, the |
|
|
|
60 shell evaluation order, and Unix file systems semantics. When we |
|
|
|
61 delete a file in Unix, it is removed from the file system, but any |
|
|
|
62 file descriptors referencing the file remain valid. We can exploit |
|
|
|
63 this behaviour to delete the input file *after* directing the input, |
|
|
|
64 but *before* redirecting the output: |
|
|
|
65 . |
|
|
|
66 .DS |
|
|
|
67 $ (rm numbers && sort > numbers) < numbers |
|
|
|
68 .DE |
|
|
|
69 . |
|
|
|
70 .PP |
|
|
|
71 This approach requires no dependencies and will work in any Unix |
|
|
|
72 shell. |
|