TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The roots of an obscure Bourne shell error message

95 pointsby r4umover 1 year ago

6 comments

pinuscover 1 year ago
Excellent explanation! However, I would disagree both that there isn&#x27;t an easy fix and that each of the decisions are sensible.<p>If the syntax to temporarily set variables was different, say using : instead of =, or requiring some delimiter between assignments and operations, or maybe enclosing the statement in braces (something like: {foo=bar; echo $foo}...) to delimit temporary assignments would have been reasonable alternatives, perhaps even more readable than this. Or having the sntax disallow `foo=`, requiring, say, `foo=null` or `foo=&#x27;&#x27;`, which are both more explicit, or even `unset foo`. These are more sensible individual choices, and that&#x27;s partly because they&#x27;re more explicit and partly because they avoid a (now) common error. I&#x27;d argue good language design needs to think slightly bigger picture than &quot;individually not catastrophic&quot; choices. Sh is littered with a myriad of small bad choices, which add up to a language that&#x27;s hard to code or script without bugs. Nowadays with shellcheck it&#x27;s easier, but it shouldn&#x27;t be necessary. The consensus is: it&#x27;s a scripting language, it shouldn&#x27;t be used for complex stuff. But if it was a slightly better scripting language, it _could_ be used more safely for larger or more complex scripts.<p>The truth is that it&#x27;s an ancient language, its (bad) syntax is set in stone, and there&#x27;s nothing we can do about it except slowly move to alternatives. Sad that there&#x27;s nothing established to take its place (Perl is read-only, python is not good enough as unix glue, everything else is too obscure).<p>I know how and love to write in bash. But oh god was it painful to learn
评论 #37476587 未加载
评论 #37476131 未加载
评论 #37475898 未加载
bdammover 1 year ago
And today I learned about shellcheck.<p>Thank you for that fun and concise trip into shell evaluation :)
da39a3eeover 1 year ago
For what it’s worth, the explanation of the error was obvious to me after seeing the code for a few seconds. So maybe my point is… don’t worry if stuff like that in shell programming seems obscure to you; it becomes much less obscure with practice (and along the way you do learn genuine lessons about unix-like operating systems, not just shell programming details).
评论 #37477316 未加载
jlv2over 1 year ago
Sorry, that&#x27;s not obscure!
评论 #37477369 未加载
1vuio0pswjnm7over 1 year ago
This does not seem obscure to me at all. Having learned about C from reading djb&#x27;s programs, I write programs that read their arguments from environmental variables. (See djbdns for example.) When I run one of these programs it&#x27;s common to set variables on the command line, e.g.,<p><pre><code> echo https:&#x2F;&#x2F;example.com|Connection=keep-alive yy025|nc -vvn 127.127 80 </code></pre> yy025 sets the HTTP Connection header according to the value of the corresponding environmental variable. If I want to send a POST request I set the variable httpMethod to POST. The address 127.0.0.127 is a TLS forward proxy. Original netcat allows one to type 127.127 without the zeros.<p>Using djb&#x27;s envdir utility, one can put a selection of different HTTP headers into a directory so that there&#x27;s no need to type them on the command line.<p><pre><code> cd &#x2F;path&#x2F;to&#x2F;dir echo close &gt; connection echo aplication&#x2F;x-www-form-urlencoded &gt; content-type echo id=123\;key=xyz &gt; cookie echo 19 &gt; content-length echo POST &gt; httpMethod echo &#x2F;api&#x2F;whatever &gt; path echo &quot;{ \&quot;key\&quot;: \&quot;value\&quot; }&quot; &gt; post-data cd echo https:&#x2F;&#x2F;example.com \ |if cd &#x2F;path&#x2F;to&#x2F;dir;envdir . yy025;then cat post-data;fi \ |nc -vvn 127.127 80 </code></pre> It&#x27;s strange to me to see this author use printenv instead of set (a built-in) to display Bourne shell environmental variables. As someone who uses Bourne shell every day and on a variety of computers, I never use printenv. On the smaller systems I make, I do not include printenv in the userland.<p>The use of fgrep to match a single word in all caps is also strange.<p>Maybe I am just missing some UNIX wisdom here. If so, please disregard this comment.<p>From the article<p><pre><code> $ export FRED=value $ printenv | fgrep FRED FRED=value $ FRED= $ printenv | fgrep FRED FRED= $ unset FRED $ printenv | fgrep FRED $ # ie, no output from printenv </code></pre> Without using printenv or grep -F (in shell script &#x2F;bin&#x2F;fgrep)<p><pre><code> $ export FRED=value $ set|grep FRED FRED=&#x27;value&#x27; FRED= $ set|grep FRED FRED=&#x27;&#x27; $ unset FRED $ set|grep FRED $ # ie, no output from set</code></pre>
评论 #37476429 未加载
评论 #37488382 未加载
评论 #37475899 未加载
评论 #37476509 未加载
评论 #37476088 未加载
评论 #37476089 未加载
cmeacham98over 1 year ago
Can I suggest a simple fix that doesn&#x27;t involve changing behavior at all but probably improves the lives of the many users who hit this?<p>Just add an additional line to the error message for lines that look like this pattern:<p><pre><code> sh: 107: command not found Did you mean &quot;AVAR=$(... | wc -l)&quot;?</code></pre>
评论 #37477787 未加载