opus7: submit a new article from Athas - tgtimes - The Gopher Times | |
git clone git://bitreich.org/tgtimes git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
--- | |
commit c8279e8b137436c61ad76e077afe0cec09ed9260 | |
parent 9c6672aaa881709d5e0139128423ad83000b557f | |
Author: Josuah Demangeon <[email protected]> | |
Date: Sun, 16 Oct 2022 02:09:47 +0200 | |
opus7: submit a new article from Athas | |
Diffstat: | |
A opus7/article-athas-shell-redirect… | 73 +++++++++++++++++++++++++++… | |
1 file changed, 73 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/opus7/article-athas-shell-redirections.mw b/opus7/article-athas-sh… | |
@@ -0,0 +1,73 @@ | |
+.SH athas | |
+Shell Redirections | |
+.2C 60 | |
+. | |
+.PP | |
+Newcomers to the Unix shell quickly encounter handy tools such as | |
+sed(1) and sort(1). This command prints the lines of the given file | |
+to stdout, in sorted order: | |
+. | |
+.DS | |
+$ sort numbers | |
+.DE | |
+. | |
+.PP | |
+Soon after, newcomers will also encounter shell redirection, by which | |
+the output of these tools can conveniently be read from or stored in | |
+files: | |
+. | |
+.DS | |
+$ sort < numbers > numbers_sorted | |
+.DE | |
+. | |
+.PP | |
+Our new user, fascinated by the modularity of the Unix shell, may then | |
+try the rather obvious possibility of having the input and output file | |
+be the same: | |
+. | |
+.DS | |
+$ sort < numbers > numbers | |
+.DE | |
+. | |
+.PP | |
+But disaster strikes: the file is empty! The user has lost their | |
+precious collection of numbers - let's hope they had a backup. Losing | |
+data this way is almost a rite of passage for Unix users, but let us | |
+spell out the reason for those who have yet to hurt themselves this | |
+way. | |
+. | |
+.PP | |
+When the Unix shell evaluates a command, it starts by processing the | |
+redirection operators - that's the '>' and '<' above. While '<' just | |
+opens the file, '>' *truncates* the file in-place as it is opened for | |
+reading! This means that the 'sort' process will dutifully read an | |
+empty file, sort its non-existent lines, and correctly produce empty | |
+output. | |
+. | |
+.PP | |
+Some programs can be asked to write their output directly to files | |
+instead of using shell redirection (sed(1) has '-i', and for sort(1) | |
+we can use '-o'), but this is not a general solution, and does not | |
+work for pipelines. Another solution is to use the sponge(1) tool | |
+from the "moreutils" project, which stores its standard input in | |
+memory before finally writing it to a file: | |
+. | |
+.DS | |
+$ sort < numbers | sponge numbers | |
+.DE | |
+. | |
+.PP | |
+The most interesting solution is to take advantage of subshells, the | |
+shell evaluation order, and Unix file systems semantics. When we | |
+delete a file in Unix, it is removed from the file system, but any | |
+file descriptors referencing the file remain valid. We can exploit | |
+this behaviour to delete the input file *after* directing the input, | |
+but *before* redirecting the output: | |
+. | |
+.DS | |
+$ (rm numbers && sort > numbers) < numbers | |
+.DE | |
+. | |
+.PP | |
+This approach requires no dependencies and will work in any Unix | |
+shell. |