14 comments

  • wahern1 hour ago
    I find it easier to understand in terms of the Unix syscall API. `2&gt;&amp;1` literally translates as `dup2(1, 2)`, and indeed that&#x27;s exactly how it works. In the classic unix shells that&#x27;s all that happens; in more modern shells there may be some additional internal bookkeeping to remember state. Understanding it as dup2 means it&#x27;s easier to understand how successive redirections work, though you also have to know that redirection operators are executed left-to-right, and traditionally each operator was executed immediately as it was parsed, left-to-right. The pipe operator works similarly, though it&#x27;s a combination of fork and dup&#x27;ing, with the command being forked off from the shell as a child before processing the remainder of the line.<p>Though, understanding it this way makes the direction of the angled bracket a little odd; at least for me it&#x27;s more natural to understand dup2(2, 1) as 2&lt;1, as in make fd 2 a duplicate of fd 1, but in terms of abstract I&#x2F;O semantics that would be misleading.
    • emmelaich1 hour ago
      Yep, there&#x27;s a strong unifying feel between the Unix api, C, the shell, and also say Perl.<p>Which is lost when using more modern or languages foreign to Unix.
      • tkcranny57 minutes ago
        Python too under the hood, a lot of its core is still from how it started as a quick way to do unixy&#x2F;C things.
    • ifh-hn5 minutes ago
      Haha, I&#x27;m even more confused now. I have no idea what dup is...
      • jpollock3 minutes ago
        There are a couple of ways to figure out.<p>open a terminal (OSX&#x2F;Linux) and type:<p><pre><code> man dup </code></pre> open a browser window and search for:<p><pre><code> man dup </code></pre> Both will bring up the man page for the function call.<p>To get recursive, you can try:<p><pre><code> man man unix </code></pre> (the unix is important, otherwise it gives you manly men)
  • amelius1 hour ago
    It&#x27;s a reminder of how archaic the systems we use are.<p>File descriptors are like handing pointers to the users of your software. At least allow us to use names instead of numbers.<p>And sh&#x2F;bash&#x27;s syntax is so weird because the programmer at the time thought it was convenient to do it like that. Nobody ever asked a user.
    • zahlman55 minutes ago
      At the time, the users <i>were</i> the programmers.
      • amelius45 minutes ago
        This is misleading because you use plural for both and I&#x27;m sure most of these UX missteps were _each_ made by a _single_ person, and there were &gt;1 users even at the time.
        • ifh-hn2 minutes ago
          &gt; and there were &gt;1 users even at the time.<p>Are you sure there wasn&#x27;t &gt;&amp;1 users... Sorry I&#x27;ll get my coat.
        • Msurrow42 minutes ago
          I think he meant that at that time all users were programmers. Yes, _all_ .
        • andoando28 minutes ago
          programmers are people too! bash syntax just sucks
      • booi52 minutes ago
        arguably if you&#x27;re using the CLI they still are
    • csours43 minutes ago
      The conveniences also mean that there is more than ~one~ ~two~ several ways to do something.<p>Which means that reading someone else&#x27;s shell script (or awk, or perl, or regex) is INCREDIBLY inconvenient.
      • amelius36 minutes ago
        Yes. There are many reasons why one shouldn&#x27;t use sh&#x2F;bash for scripting.<p>But my main reason is that most scripts break when you call them with filenames that contain spaces. And they break spectacularly.
    • HackerThemAll48 minutes ago
      &gt; bash&#x27;s syntax is so weird<p>What should be the syntax according to contemporary IT people? JSON? YAML? Or just LLM prompt?
      • ifh-hn0 minutes ago
        Nushell! Or powershell, but I much prefer nushell!
      • amelius42 minutes ago
        Honestly, Python with the &quot;sh&quot; module is a lot more sane.
  • kazinator19 minutes ago
    It means redirect file descriptor 2 to the same destination as file descriptor 1.<p>Which actually means that an undelrying <i>dup2</i> operation happens in this direction:<p><pre><code> 2 &lt;- 1 &#x2F;&#x2F; dup2(2, 1) </code></pre> The file description at [1] is duplicated into [2], thereby [2] points to the same object. Anything written to stderr goes to the same device that stdout is sending to.<p>The notation follows I&#x2F;O redirections: cmd &gt; file actually means that a descriptor [n] is first created for the open file, and then that descriptor&#x27;s decription is duplicated into [1]:<p><pre><code> n &lt;- open(&quot;file&quot;, O_RDONLY) 1 &lt;- n</code></pre>
  • vessenes1 hour ago
    Not sure why this link and&#x2F;or question is here, except to say LLMs like this incantation.<p>It redirects STDERR (2) to where STDOUT is piped already (&amp;1). Good for dealing with random CLI tools if you&#x27;re not a human.
    • WhyNotHugo47 minutes ago
      Humans used this combination extensively for decades too. I&#x27;m no aware of any other simple way to grep both stdout and stderr from a process. (grep, or save to file, or pipe in any other way).
      • TacticalCoder13 minutes ago
        &quot;not humans&quot; are using this extensively precisely because humans used this combination extensively for decades. It&#x27;s muscle-memory for me. And so is it for LLMs.
    • anitil34 minutes ago
      I&#x27;ve also found llms seem to love it when calling out to tools, I suppose for them having stderr interspersed messaged in their input doesn&#x27;t make much difference
    • ElijahLynn1 hour ago
      I found the explanation useful, about &quot;why&quot; it is that way. I didn&#x27;t realize the &amp; before the 1 means to tell it is the filedescriptor 1 and not a file named 1.
      • weavie1 hour ago
        I get the ocassional file named `1` lying around.
      • LtWorf25 minutes ago
        It&#x27;s an operator called &quot;&gt;&amp;&quot;, the 1 is the parameter.
        • WJW10 minutes ago
          Well sure, but surely this takes some inspiration from both `&amp;` as the &quot;address of&quot; operator in C as well as the `&gt;` operator which (apart from being the greater-than operator) very much implies &quot;into&quot; in many circumstances.<p>So `&gt;&amp;1` is &quot;into the file descriptor pointed to by 1&quot;, and at the time any reasonable programmer would have known that fd 1 == STDOUT.
  • maxeda34 minutes ago
    &gt; I am thinking that they are using &amp; like it is used in c style programming languages. As a pointer address-of operator. [...] 2&gt;&amp;1 would represent &#x27;direct file 2 to the address of file 1&#x27;.<p>I had never made the connection of the &amp; symbol in this context. I think I never really understood the operation before, treating it just as a magic incantation but reading this just made it click for me.
    • jibal22 minutes ago
      No, the shell author needed <i>some</i> way to distinguish file descriptor 1 from a file named &quot;1&quot; (note that 2&gt;1 means to write stderr to the file named &quot;1&quot;), and &#x27;&amp;&#x27; was one of the few available characters. It&#x27;s not the address of anything.<p>To be consistent, it would be &amp;2&gt;&amp;1, but that makes it more verbose than necessary and actually means something else -- the first &amp; means that the command before it runs asynchronously.
  • gnabgib1 hour ago
    Better: <i>Understanding Linux&#x27;s File Descriptors: A Deep Dive Into &#x27;2&gt;&amp;1&#x27; and Redirection</i> <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41384919">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41384919</a> <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=39095755">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=39095755</a>
  • arjie46 minutes ago
    Redirects are fun but there are way more than I actually routinely use. One thing I do is the file redirects.<p><pre><code> diff &lt;(seq 1 20) &lt;(seq 1 10) </code></pre> I do that with diff &lt;(xxd -r file.bin) &lt;(xxd -r otherfile.bin) sometimes when I should expect things to line up and want to see where things break.
  • ucarion1 hour ago
    I&#x27;ve almost never needed any of these, but there&#x27;s all sorts of weird redirections you can do in GNU Bash: <a href="https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;manual&#x2F;bash.html#Redirecting-Output" rel="nofollow">https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;bash&#x2F;manual&#x2F;bash.html#Redirecti...</a>
    • keithnz48 minutes ago
      agentic ai tends to use it ALL the time.
  • csours46 minutes ago
    If you need to know what 2&gt;&amp;1 means, then I would recommend shellcheck<p>It&#x27;s very, very easy to get shell scripts wrong; for instance the location of the file redirect operator in a pipeline is easy to get wrong.
    • TacticalCoder11 minutes ago
      As someone who use LLMs to generate, among others, Bash script I recommend shellcheck too. Shellcheck catches <i>lots</i> of things and shall really make your Bash scripts better. And if for whatever reason there&#x27;s an idiom you use all the time that shellcheck doesn&#x27;t like, you can simply configure shellcheck to ignore that one.
  • wodenokoto52 minutes ago
    I enjoyed the commenter asking “Why did they pick such arcane stuff as this?” - I don’t think I touch more arcane stuff than shell, so asking why shell used something that is arcane relative to itself is to me arcane squared.
  • nurettin52 minutes ago
    I saw this newer bash syntax for redirecting all output some years ago on irc<p><pre><code> foo &amp;&gt; file foo |&amp; program</code></pre>
    • rezonant41 minutes ago
      I didn&#x27;t know about |&amp;, not sure if it was introduced at the same time. So I&#x27;d always use &amp;&gt; for redirection to file and 2&gt;&amp;1 for piping
  • adzm1 hour ago
    I always wondered if there ever was a standard stream for stdlog which seems useful, and comes up in various places but usually just as an alias to stderr
    • jibal16 minutes ago
      &#x2F;dev&#x2F;stderr on Linux
    • knfkgklglwjg32 minutes ago
      Powershell has ”stdprogress”
  • zem1 hour ago
    back when stackoverflow was still good and useful, I asked about some stderr manipulation[0] and learnt a lot from the replies<p>[0] <a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3618078&#x2F;pipe-only-stderr-through-a-filter" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;3618078&#x2F;pipe-only-stderr...</a>
  • emmelaich58 minutes ago
    A gotcha for me originally and perhaps others is that while using ordering like<p><pre><code> $ .&#x2F;outerr &gt;blah 2&gt;&amp;1 </code></pre> sends stdout and stderr to blah, imitating the order with pipe instead does not.<p><pre><code> $ .&#x2F;outerr | 2&gt;&amp;1 cat &gt;blah err </code></pre> This is because | is not a mere redirector but a statement terminator.<p><pre><code> (where outerr is the following...) echo out echo err &gt;&amp;2</code></pre>
    • time4tea11 minutes ago
      Useless use of cat error&#x2F;award<p>But also | isnt a redirection, it takes stdout and pipes it to another program.<p>So, if you want stderr to go to stdout, so you can pipe it, you need to do it in order.<p>bob 2&gt;&amp;1 | prog<p>You usually dont want to do this though.
    • inigyou43 minutes ago
      Why would that second one be expected to work?