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