4 ms·
For fun, I took a crack at your example and came up with this craziness (with the caveat it's late and I didn't spend much time on it), which is made a bit more
by tpmoney 2y ago
For fun, I took a crack at your example and came up with this craziness (with the caveat it's late and I didn't spend much time on it), which is made a bit more awkward because grep doesn't do capturing groups:
netstat -aln \
| grep ESTABLISHED \
| awk '{print $4}' \
| grep -Po '\:\d+$' \
| grep -Po '\d+' \
| sort \
| uniq -c \
| sort -r \
| head -n 10
Changing the awk field to 5 instead of 4 should get you remote ports instead of local. But yeah, that will be fragile if netstat's output ever changes. That said, even if you're piping objects around, if the output of the thing putting out objects changes, your tool is always at risk of breaking. Yes objects breaking because field order changed is less likely, but what happens if `Get-NetTCPConnection` stops including a `State` field? I guess `Where-Object` might validate it found such a field, but I could also see it reasonably silently ignoring input that doesn't have the field. Depends on whether it defaults to strict or lenient parsing behaviors.
- gjvc 2y agoput the pipe character at the end of the line and you don't need the backslashes
- jiggawatts 2y agoI know this sounds like nit-picking but bear with me. It's the point I'm trying to make: 1. Your script outputs an error when run, because 'bash' itself doesn't have netstat as a built-in. That's an external command. In my WSL2, I had to install it. You can't declaratively require this up-front, you script has to have an explicit check... or it'll just fail half-way through. Or do nothing. Or who knows!? PowerShell has up-front required prerequisites that you can declare: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires?view=powershell-7.4 https://learn.microsoft.com/en-us/powershell/module/microsof... Not that that's needed, because Get-NetTcpConnection is a built-in command. 3. Your script is very bravely trying to parse output that includes many different protocols, including: tcp, tcp6, udp, udp6, and unix domain sockets. I'm seeing random junk like 'ACC' turn up after the first awk step. 4. Speaking of which, the task was to get tcp connections, not udp, but I'll let this one slide because it's an easy fix. 5. Now imagine putting your script side-by-side with the PowerShell script, and giving it to people to read. What are the chances that some random person could figure out what each one does? Would they be able to modify the functionality successfully? Note that you had to use 'awk', which is a parser, and then three uses of 'grep' -- a regular expression language, which is also a kind of parsing. The PowerShell version has no parsing at all. That's why it's just 4 pipeline expressions instead of 9 in your bash example. Literally in every discussion about PowerShell there's some Linux person who's only ever used bash complaining that PS syntax is "weird" or "hard to read". What are they talking about!? It's half the complexity for the same functionality, reads like English, and doesn't need write-only hieroglyphics for parameters.
- sgarland 2y ago> PowerShell has up-front required prerequisites that you can declare Anyone who's written more than a few scripts for others will have learned to do something like this at the start: declare -a reqs reqs+=(foo bar baz) missing=0 for r in "${reqs[@]}"; do if (! command -v "$r" &>/dev/null); then echo "${r} is required, please install it" missing=1 fi done if [ $missing -gt 0 ]; then exit 1 fi > Your script is very bravely trying to parse output that includes many different protocols, including: tcp, tcp6, udp, udp6, and unix domain sockets They probably didn't know you could specify a type. Mine only displays TCP4. > Now imagine putting your script side-by-side with the PowerShell script, and giving it to people to read. I'm gonna gatekeep here. If you don't know what that script would do, you have no business administering Linux for pay. I'm not saying that in a "GTFO noob" way, but in a "maybe you should know how to use your job's tools before people depend on you to do so." None of that script is using exotic syntax. > Note that you had to use 'awk', which is a parser, and then three uses of 'grep' -- a regular expression language, which is also a kind of parsing. They _chose_ to. You _can_ do it all with awk (see my example in a separate post). > Literally in every discussion about PowerShell there's some Linux person who's only ever used bash complaining that PS syntax is "weird" or "hard to read". What are they talking about!? It's half the complexity for the same functionality, reads like English, and doesn't need write-only hieroglyphics for parameters. And yet somehow, bash and its kin continue to absolutely dominate usage. There is a reason that tools like ripgrep [0] are beloved and readily accepted: they don't require much in the way of learning new syntax; they just do the same job, but faster. You can load your local machine up with all kinds of newer, friendlier tools like fd [1], fzf[2], etc. – I definitely love fzf to death. But you'd better know how to get along without them, because when you're ssh'd onto a server, or god forbid, exec'd into a container built with who-knows-what, you won't have them. Actually, that last point sparked a memory: what do you do when you're trying to debug a container and it doesn't have things like `ps` available? You iterate through the `/proc` filesystem, because _everything is a file._ THAT is why the *nix way exists, is wonderful, and is unlikely to ever change. There is always a way to get the information you need, even if it's more painful. [0]: https://github.com/BurntSushi/ripgrep https://github.com/BurntSushi/ripgrep [1]: https://github.com/sharkdp/fd https://github.com/sharkdp/fd [2]: https://github.com/junegunn/fzf https://github.com/junegunn/fzf