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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

Practical Shell Patterns I Use

130 点作者 zwischenzug超过 3 年前

17 条评论

t43562超过 3 年前
The one that I find repeatedly useful:<p>find . -name &lt;some pattern&gt; | { while read F; do &lt;do something to file F&gt;; done; }<p>This lets you do things of almost any level of complexity to files or data listed as input and it doesn&#x27;t require temporary files so you can process a lot of things.<p>e.g. you might use sed -i to alter the files in some way or you might find media files of some kind into ffmpeg to convert them.
评论 #29884516 未加载
评论 #29883247 未加载
评论 #29895349 未加载
pizza234超过 3 年前
&gt; ps -ef | grep VBoxHeadless | awk &#x27;{print $2}&#x27; | xargs kill -9<p>There&#x27;s pkill for that :)<p><pre><code> pkill -KILL VBoxHeadless </code></pre> (the above assumes that the binary is called `VBoxHeadless`)
评论 #29884054 未加载
评论 #29883874 未加载
评论 #29880114 未加载
评论 #29882879 未加载
justsomehnguy超过 3 年前
&gt; Here’s a real-world example I used recently<p><pre><code> gci -rec | ? name -match zabb | ? Extension -eq .deb | % Name </code></pre> Of course it could be replaced with<p><pre><code> gci -rec | ? name -match zabb.+\.deb$ | % name </code></pre> And you can filter on any property (a little excerpt):<p><pre><code> Mode : --r-- BaseName : zabbix-release_5.0-1+bionic_all Length : 4240 DirectoryName : &#x2F;home&#x2F;appliance FullName : &#x2F;home&#x2F;appliance&#x2F;zabbix-release_5.0-1+bionic_all.deb Extension : .deb Name : zabbix-release_5.0-1+bionic_all.deb CreationTime : 5&#x2F;11&#x2F;2020 12:07:35 PM </code></pre> &gt; ps -ef | grep VBoxHeadless | awk &#x27;{print $2}&#x27; | xargs kill -9<p><pre><code> Get-Process apach* | Stop-Process -Force </code></pre> But &#x27;pOwErShEll iS sO vErBoSe&#x27;<p>&gt; Find Files Ending With…<p><pre><code> gci &#x2F; -re | ? name -match \.deb$ </code></pre> Would take longer, sure, but still the same Get-ChildItem cmdlet, no need to remember another two utilities<p>&gt; $ env | grep -w PATH | tr &#x27;:&#x27; &#x27;\n&#x27;<p><pre><code> PS &#x2F;home&gt; ( env ) -match &#x27;^PATH&#x27; -replace &#x27;:&#x27;,&quot;`n&quot; PATH=&#x2F;opt&#x2F;microsoft&#x2F;powershell&#x2F;7 &#x2F;home&#x2F;appliance&#x2F;bin &#x2F;home&#x2F;appliance&#x2F;.local&#x2F;bin [stripped] </code></pre> Again, just built-in functions, no external utilities<p>As usual - there is a ton of useful and nice QOL utils in *nix world, but it always feels like scratching left ear with the right hand.
评论 #29889404 未加载
bostonsre超过 3 年前
&gt; Quick Infinite Loop<p>I use this a lot for polling type commands:<p><pre><code> do_every_n_secs &quot;ps -eaf | grep blablabla&quot; 5 function do_every_n_secs (){ cmd=$1 secs=$2 if [[ $secs -eq &quot;&quot; ]]; then secs=10 fi while true; do echo &quot;################################################################&quot;; date; eval $cmd sleep $secs; done }</code></pre> ```
评论 #29885190 未加载
评论 #29889329 未加载
评论 #29885168 未加载
评论 #29885208 未加载
bxparks超过 3 年前
Interesting stuff. One small correction that I noticed:<p><pre><code> $ sudo locate cfg | grep \.cfg$ </code></pre> should contain quotes, like this:<p><pre><code> $ sudo locate cfg | grep &#x27;\.cfg$&#x27; </code></pre> because the shell swallows the backslash.<p>But locate(1) supports globs, so I think this could be simplified to just:<p><pre><code> $ sudo locate &#x27;*.cfg&#x27; </code></pre> But on my Ubuntu, &#x2F;etc&#x2F;updatedb.conf has PRUNE_BIND_MOUNTS=&quot;yes&quot;, so my &#x2F;home, on a separate partition, does not get updated. So I often resort to:<p><pre><code> $ find -name &#x27;*.cfg&#x27; </code></pre> somewhere in my $HOME directory.
评论 #29882291 未加载
评论 #29883791 未加载
评论 #29884307 未加载
oandrew超过 3 年前
bash 4 supports `|&amp;` as an alternative to `2&gt;&amp;1` which looks better in pipelines e.g.<p><pre><code> $ docker logs container |&amp; grep word</code></pre>
评论 #29883058 未加载
AceJohnny2超过 3 年前
Can anyone recommend a modern explanation of sed&#x27;s more advanced features?<p>I&#x27;m ashamed that, despite having learned many other ostensibly more complex systems and languages, sed continues to elude me. Of course I get the usual &#x27;s&#x2F;foo&#x2F;bar&#x2F;g&#x27; stuff with regular expressions and placeholders, but I still don&#x27;t really understand most of the other commands or, more usefully, the addresses.<p>Perhaps I need to spend quality time with the manpage in a cabin in the woods, away from modern distractions, but so far it has proven impermeable.<p>Perhaps I&#x27;m missing a proper understanding of its &#x27;pattern space&#x27; vs &#x27;hold space&#x27;.
评论 #29885232 未加载
评论 #29885180 未加载
gmuslera超过 3 年前
I try to use &quot;smaller&quot; commands instead of more versatile but complex alternatives. I&#x27;m not sure if I get better cpu&#x2F;io&#x2F;etc usage by using cut or tr instead of sed or awk (or perl and so on) but it is a pattern I followed by decades, at least for simple enough commands. And I may have something less to remember if I do i.e. rev | cut | rev instead of awk to get the last field.<p>And having something less to remember, and lowering the complexity for the reader (that not always be me, or if I am, may not be in the same mind state as when I wrote that) is usually good. But it also is having predictable&#x2F;consistent patterns.
seanhunter超过 3 年前
As an aside, &quot;zwischenzug&quot; is a great name. A &quot;zwischenzug&quot; is an &quot;inbetween move&quot; in chess that might happen in the middle of a sequence, and can often lead to unexpected results if one side hasn&#x27;t been precise in their move order.<p><a href="https:&#x2F;&#x2F;www.chessjournal.com&#x2F;zwischenzug&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.chessjournal.com&#x2F;zwischenzug&#x2F;</a> for example has some more info if you&#x27;re curious.
oandrew超过 3 年前
One feature I really wish for in shells is something similar to Perl&#x27;s unquoted strings &#x2F; single line concise HEREDOC syntax &#x2F; raw literal syntax. e.g.<p><pre><code> $ echo q(no &#x27; escaping ` required &quot; here) no &#x27; escaping ` required &quot; here </code></pre> This would make typing sql &#x2F; json much easier. To my knowledge none of the shells implement this. Does anyone know why?
评论 #29883338 未加载
honkycat超过 3 年前
Going to echo: Bash is bad. Bash is a feature-impoverished language and belongs in the dustbin. I don&#x27;t understand why we script with one hand tied behind our back.<p>With Python I can install &quot;click&quot; and get great argument parsing and multi-command support with a simple install. Bash&#x27;s argument parsing is much more verbose and arcane.<p>Sure, it has nice ways to combine tools and parse strings and such. However: You could also implement those nice abstractions in a higher quality language. So a good thing about bash does not cancel out all the bad.<p>I would LOVE a toolkit that is:<p>- A single binary<p>- That parses a single file like make ( but NOT a makefile )<p>- That uses a well known, powerful language.<p>- That lets me declare tasks, validations ( required arguments, etc ), and workflows as a first-class citizen<p>- With out of the box `--help` support<p>- That lets me import other makefile-like files to improve code re-use ( both remote and local )
评论 #29891514 未加载
评论 #29883042 未加载
bsder超过 3 年前
As much as I like these, these are also how you blow both feet off.<p>As long as you&#x27;re just exploring (everything is read only), you&#x27;re okay.<p>The moment &quot;kill&quot; and &quot;rm&quot; (anything mutable) come into the picture on a long shell pipeline, <i>stop</i>. You probably don&#x27;t want to do that.<p>You need to be thinking very hard to make sure that an errant glob or shell substitution isn&#x27;t going to wipe out your system. Make a complicated pipeline that creates a simple file, examine the simple file by hand, and <i>then</i> feed that file to &quot;kill&quot;&#x2F;&quot;rm&quot;&#x2F;&quot;whatever&quot; as close to unmodified as possible.<p>You may still blow your system away. However, at that point, you&#x27;ve given yourself the best chances to not do so.
yakshaving_jgt超过 3 年前
Being able to write a file directly in the shell with heredocs is so cool, but I know I&#x27;ll never use it because it&#x27;s far quicker to just open vim and type with all the commands and verbs and motions that I&#x27;m used to.
评论 #29885233 未加载
gbrown_超过 3 年前
I know there are many ways the same thing can be done in the shell but there are so many problems here. Please take this as feedback and not harsh criticism (I know there&#x27;s comment section on the blog but I&#x27;d rather not give my e-mail to yet another website).<p><pre><code> &gt; cat &#x2F;etc&#x2F;passwd | sed &#x27;s&#x2F;\([^:]*\):.*:\(.*\)&#x2F;user: \1 shell: \2&#x2F;&#x27; </code></pre> Besides the needless cat this is clearer in awk, a tool you mention just prior.<p><pre><code> awk &#x27;{FS=&quot;:&quot;} {print &quot;user: &quot; $1, &quot;shell: &quot; $NF}&#x27; &#x2F;etc&#x2F;passwd &gt; $ ls | xargs -t ls -l </code></pre> Beware files with whitespace in their names.<p><pre><code> &gt; find . | grep azurerm | grep tf$ | xargs -n1 dirname | sed &#x27;s&#x2F;^.\&#x2F;&#x2F;&#x2F;&#x27; &gt; &gt; ... &gt; &gt; for each of those files, removes the leading dot and forward slash, leaving the final bare filename (eg somefile.tf) </code></pre> No it doesn&#x27;t it returns the names of parent directories where files ending in &quot;tf&quot; are found and where the path also includes the string &quot;azurerm&quot;.<p><pre><code> &gt; $ ls | grep Aug | xargs -IXXX mv XXX aug_folder </code></pre> Ew.<p><pre><code> mv *Aug* aug_folder&#x2F; </code></pre> Though now the issue of whitespace in path names is mentioned. Another minior point here is that with GNU xargs at least when using -I -L 1 is implied, so the original example is equivalent to a loop.<p><pre><code> &gt; $ ps -ef | grep VBoxHeadless | awk &#x27;{print $2}&#x27; | xargs kill -9 pkill VBoxHeadless </code></pre> You acknowledge to avoid SIGKILL if possible so I don&#x27;t know why you put it in the example.<p><pre><code> &gt; $ sudo updatedb &gt; $ sudo locate cfg | grep \.cfg$ locate &#x27;*.cfg&#x27; </code></pre> No idea why sudo is used when running locate, also it takes a glob so the grep here can be avoided.<p><pre><code> &gt; $ grep ^.https doc.md | sed &#x27;s&#x2F;^.(h[^])]).*&#x2F;open \1&#x2F;&#x27; | sh </code></pre> Now this is just nutty.<p><pre><code> &gt; This example looks for https links at the start of lines in the doc.md file </code></pre> No it doesn&#x27;t, it matches the start of the line, followed by a character, then &quot;https&quot;.<p>The sed then matches start of the line, followed by a character, starts a capture group of the letter &quot;h&quot; followed by a single character that is not &quot;]&quot; or &quot;)&quot;, closes the capture group and continues to match anything.<p>The example given will always result in &quot;open ht&quot; for any hit.<p>Then there&#x27;s the piping to sh. You mention like to drop this to review the list. I&#x27;d suggest focusing on extracting the list of links then pipe to xargs open. If you get a pipeline wrong you could unintentionally blast something into a shell executing anything which might be very bad.<p><pre><code> &gt; Give Me All The Output With 2&gt;&amp;1 &amp;&gt; stdout-and-stderr </code></pre> But each to their own.<p><pre><code> &gt; env | grep -w PATH | tr &#x27;:&#x27; &#x27;\n&#x27; echo $PATH | tr &#x27;:&#x27; &#x27;\n&#x27; </code></pre> or<p><pre><code> tr &#x27;:&#x27; &#x27;\n&#x27; &lt;&lt;&lt; $PATH </code></pre> Edit: I know the formatting of this comment is terrible, I think quoting the sed example caused the rest of the comment to be marked up as italics so I indented it along with the other quotes as code.
评论 #29882360 未加载
bravetraveler超过 3 年前
No mention of my pet peeve! You don&#x27;t need a subshell&#x2F;seq to count.<p>The shell is smart, it can count for you - and even respect digits. These examples are subtle, but different in result:<p><pre><code> for i in {00..10} ; do echo $i ; done for i in {0..10} ; do echo $i ; done</code></pre>
AzzieElbab超过 3 年前
I have written thousands locs in bash but every time I have to write another one my teeth start to ache. Not sure why
kstenerud超过 3 年前
After almost 30 years and tens of thousands of LOC, possibly even into 6 figures, I&#x27;ve now thrown in the towel and just use Python for all my scripting needs. I&#x27;ve yet to have a single shell script that hasn&#x27;t turned into a maintenance nightmare, regardless of &quot;bash best practices&quot; (such as they are).<p>Bash is a terrible language, and needs to die.
评论 #29881266 未加载
评论 #29884467 未加载
评论 #29881352 未加载
评论 #29882050 未加载