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