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