TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Hints for writing Unix tools

294 点作者 mariusae超过 10 年前

15 条评论

hoggle超过 10 年前
<i>“One thing well” misses the point: it should be “One thing well AND COMPOSES WELL”</i><p>If the implementation isn&#x27;t respecting <i>The Rule of Composition</i> it&#x27;s actually not adhering to the Unix philosophy in the first place. The tweet is referring to one of Doug McIlroy&#x27;s (one of the Unix founders, inventor of the Unix pipe) famous quotes:<p><i>&quot;This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.&quot;</i><p>Pure beauty, but it&#x27;s almost too concise a definition if you haven&#x27;t <i>experienced the culture</i> of Unix (many years of usage &#x2F; reading code &#x2F; writing code &#x2F; communication with other followers). ESR&#x27;s exhaustive list of Unix rules in plain English might be a better start for the uninitiated (among which one will find the aforementioned <i>Rule of Composition</i>).<p>For all those seeking enlightenment, go forth and read the <i>The Art of Unix Programming</i>:<p><a href="https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_Art_of_Unix_Programming</a><p>17 Unix Rules:<p><a href="https://en.wikipedia.org/wiki/Unix_philosophy#Eric_Raymond.E2.80.99s_17_Unix_Rules" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unix_philosophy#Eric_Raymond.E...</a>
jzwinck超过 10 年前
Here&#x27;s one more tip: did you ever notice that &quot;ls&quot; displays multiple columns, but &quot;ls | cat&quot; prints only one filename per line? Or how &quot;ps -f&quot; truncates long lines instead of wrapping, while &quot;ps -f | cat&quot; lets the long lines live?<p>You can do it too, and if you&#x27;re serious about writing Unix-style filter programs, you will someday need to. How do you know which format to write? Call &quot;isatty(STDOUT_FILENO)&quot; in C or C++, &quot;sys.stdout.isatty()&quot; in Python, etc. This returns true if stdout is a terminal, in which case you can provide pretty output for humans and machine-readable output for programs, automatically.
评论 #8485895 未加载
评论 #8485821 未加载
评论 #8487005 未加载
voltagex_超过 10 年前
I&#x27;m not sure I agree with the &quot;no JSON, please&quot; remark. If I&#x27;m parsing normal *nix output I&#x27;m going to have to use sed, grep, awk, cut or whatever and the invocation is probably going to be different for each tool.<p>If it&#x27;s JSON and I know what object I want, I just have to pipe to something like jq [1].<p>PowerShell takes this further and uses the concept of passing objects around - so I can do things like ls | $_.Name and extract a list of file names (or paths, or extensions etc)<p>[1]: <a href="http://stedolan.github.io/jq/" rel="nofollow">http:&#x2F;&#x2F;stedolan.github.io&#x2F;jq&#x2F;</a>
评论 #8485555 未加载
评论 #8486340 未加载
评论 #8485734 未加载
评论 #8487007 未加载
评论 #8485789 未加载
osandov超过 10 年前
A nitpicky tip: --help is normal execution, not an error, so the usage information should be printed to stdout, not stderr (and it should exit with a successful status). Nothing is more annoying than trying to use a convoluted program with a million flags (which should have a man page in the first place) and piping --help into less with no success.
评论 #8487022 未加载
评论 #8486652 未加载
评论 #8486002 未加载
Animats超过 10 年前
1978 called. It wants its pipes back.<p>That approach dates from the days when you got multi-column directory listings with<p><pre><code> ls | mc </code></pre> Putting multi-column output code in &quot;ls&quot; wasn&#x27;t consistent with the UNIX philosophy.<p>There&#x27;s a property of UNIX program interconnection that almost nobody thinks about. You can feed named environment variables into a program, but you can&#x27;t get them back out when the program exits. This is a lack. &quot;exit()&quot; should have taken an optional list of name&#x2F;value pairs as an argument, and the calling program (probably a shell) should have been able to use them. With that, calling programs would be more like calling subroutines.<p>PowerShell does something like that.
评论 #8485992 未加载
评论 #8486482 未加载
评论 #8486000 未加载
to3m超过 10 年前
Additional tip: if writing a tool that prints a list of file names, provide a -0 option that prints them separated by &#x27;\x0&#x27; rather than white space. Then the output can be piped through xargs -0 and it won&#x27;t go wrong if there are files with spaces in their paths.<p>I suggest -0 for symmetry with xargs. find calls it -print0, I think.<p>(In my view, this is poor design on xargs&#x27;s part; it should be reading a newline-separated list of unescaped file names, as produced by many versions of ls (when stdout isn&#x27;t a tty) and find -print, and doing the escaping itself (or making up its own argv for the child process, or whatever it does). But it&#x27;s too late to fix now I suppose.)
评论 #8485623 未加载
评论 #8492804 未加载
评论 #8485751 未加载
acabal超过 10 年前
Great article. The other thing I&#x27;ve always wished for command-line tools is some kind of consistency for flags and arguments. Kind of like a HIG for the command line. I know some distros have something like this, and that it&#x27;s not practical to do as many common commands evolved decades ago and changing the interface would break pretty much everything. But things like `grep -E,--extended-regexp` vs `sed -r,--regexp-extended` and `dd if=&#x2F;a&#x2F;b&#x2F;c` (no dashes) drive me nuts.<p>In a magical dream world I&#x27;d start a distro where every command has its interface rewritten to conform to a command line HIG. Single-letter flags would always mean only one thing, common long flags would be consistent, and no new tools would be added to the distro until they conformed. But at this point everyone&#x27;s used to (and more importantly, the entire system relies on) the weird mismatches and historical leftovers from older commands. Too bad!
评论 #8485667 未加载
评论 #8485467 未加载
评论 #8485704 未加载
评论 #8485654 未加载
评论 #8486424 未加载
评论 #8486377 未加载
评论 #8486738 未加载
dap超过 10 年前
Lots of great points here, but as always, these can be taken too far. Header lines are really useful for human-readable output, and can be easily skipped with an optional flag. (-H is common for this).<p>The &quot;portable output&quot; thing is especially subjective. I buy that it probably makes sense for compilers to print full paths. But it&#x27;s nice that tools like ls(1) and find(1) use paths in the same form you gave them on the command-line (i.e., absolute pathnames in output if given absolute paths, but relative pathnames if given relative paths). For one, it means that when you provide instructions to someone (e.g., a command to run on a cloned git repo), and you want to include sample output, the output matches exactly what they&#x27;d see. Similarly, it makes it easier to write test suites that check for expected stdout contents. And if you want absolute paths in the output, you can specify the input that way.
评论 #8486138 未加载
peterwwillis超过 10 年前
Not every program will be able to take input in stdin and output to stdout. If you have a --file (or -f) option, you&#x27;d do well to support a &quot;-&quot; file argument, which means either stdin or stdout, depending if you&#x27;re reading or writing to -f. But you won&#x27;t support &quot;-&quot; if the -f option requires seeking backwards in a file. Neither will you be using stdin or stdout if binary is involved (because tty drivers).<p>&#x27;One thing well&#x27; is often intended to make people&#x27;s lives easier on the console. Sometimes this means assuming sane defaults, and sometimes just a simpler program that does&#x2F;assumes less. Take these two examples and tell me which you&#x27;d prefer to type:<p><pre><code> user@host~$ ls *.wav | xargs processAudio -e mu-law --endian swap -c 2 -r 16000 user@host~$ find . -type f -maxdepth 1 -name &#x27;*.wav&#x27; -exec processAudio -e mu-law --endian swap -c 2 -r 16000 {} \; </code></pre> Write concise technical documentation. Imagine it&#x27;s your first day on a new job and you need to learn how all your new team&#x27;s tools work; do you want to read every line of code they&#x27;ve written just to find out how it works, or do you want to read a couple pages of technical docs to understand in general how it works? (That&#x27;s a rhetorical question)<p>Definitely provide a verbose mode. When your program doesn&#x27;t work as expected, the user should be able to figure it out without spending hours debugging it.
_pmf_超过 10 年前
I have a strong bias against people who quote their own tweets in their own blog posts. I find this to be highly narcissistic.
评论 #8489698 未加载
RexRollman超过 10 年前
Wow, its been a while since I&#x27;ve seen a monkey.org link. I thought the site was dead. Nice to see I was wrong.
评论 #8485486 未加载
mseepgood超过 10 年前
Another tip: don&#x27;t do colored output. I don&#x27;t want to deal with ANSI codes in your output.
arh68超过 10 年前
I think it&#x27;s insane to restrict programs to just STDOUT &amp; STDERR. Why 2? Why not use another file descriptor, maybe STDFMT, to capture all the formatting markup? This would avoid -0 options (newlines are markup sent to stdfmt, all strings on stdout are 0-terminated), it would avoid -H options (headers go straight to STDFMT), it would allow for less -R to still work, etc.<p>It&#x27;s possible other descriptors would be useful, like stdlog for insecure local logs, stddebug for sending gobs of information to a debugger. It&#x27;s certainly not in POSIX, so too bad, but honestly stdout is hard to keep readable and pipe-able. Adding just one more file descriptor separates the model from the view.
评论 #8487515 未加载
chilicuil超过 10 年前
I agree with what is exposed on the article and I&#x27;ve actually added more details in how to apply this &quot;principles&quot; to shell scripting:<p><a href="http://javier.io/blog/en/2014/10/21/hints-in-writing-unix-tools-with-shell-scripting.html" rel="nofollow">http:&#x2F;&#x2F;javier.io&#x2F;blog&#x2F;en&#x2F;2014&#x2F;10&#x2F;21&#x2F;hints-in-writing-unix-to...</a>
jwr超过 10 年前
I would add to this list:<p>If you are intercepting UNIX signals (starting with SIGINT), go back to the drawing board and think again. Don&#x27;t do it. There is almost never a good reason for doing it, and you will likely get it wrong and frustrate users.
评论 #8487345 未加载
评论 #8486602 未加载