6 ms·
While it is generally a good idea to write readable code, it is also true that long flags are not universally supported, and the short flags don't always have t
by npsimons 14y ago
While it is generally a good idea to write readable code, it is also true that long flags are not universally supported, and the short flags don't always have the same meanings (or even exist!) across different systems.
This is an interesting conundrum. As has been pointed out, POSIX specifies standard options (which are all short):
http://news.ycombinator.com/item?id=5165058 http://news.ycombinator.com/item?id=5165058
But these are not universally supported:
http://unixhelp.ed.ac.uk/CGI/man-cgi?ps http://unixhelp.ed.ac.uk/CGI/man-cgi?ps
What to do? My proposal: do what we do in the C/C++ world when presented with portability problems: abstract it away. POSIX sh supports functions, which can be named appropriately for readability, while calling the proper arguments and commands for different platforms. To avoid unnecessary duplication of platform/argument detection, setup could be done in a function called before anything else to create variables with the appropriate command names and arguments.
This may all seem too involved, but realize that we are talking about creating robust software that is to be maintained, so applying proper software engineering principles seems appropriate.
- webreac 14y agoI think you fail on two software engineering principles: * http://en.wikipedia.org/wiki/KISS_principle http://en.wikipedia.org/wiki/KISS_principle * you should adapt the way you think about programming to the language you are using. This is shell, not Ada.
- jcurbo 14y agoSure, but what's wrong with his approach? POSIX sh supports all the things you need to do 'if GNU grep run this, else if BSD grep run that' - functions, case statements, conditionals. He's not talking about building up major libraries in shell, just wrapping the invocations in functions based on the environment you're in.
- npsimons 14y agoUnfortunately, taken as a whole (eg, not just blithely ignoring POSIX, or systems that don't support it, or systems that don't support long options), portable shell is a big mess. Keeping it simple would be nice, but may not be possible, depending on your goals ("make everything as simple as possible, but no simpler"). So you want to write some script that will only ever run on systems with GNU utilities installed, and you never ever plan on porting it? Fine. Just do the world (and yourself) a favor and be aware of and admit that fact upfront. And if you're going to break POSIX compatibility anyway, it would be nice if you use the long options for better readability.
- skrebbel 14y agoIt really depends on what you're making of course, but for a large set of situations, isn't supporting recent bash on recent Linux/BSD good enough? This way, you got all modern Linux installations, OSX, and Windows through msys(git) covered. I'm thinking of shared dotfiles, build scripts, deploy scripts. The article you link to mentions SunOS and OSF/1. How bad are the incompatibilities on modern POSIXes only? (note: I really do not know and wouldn't know how to find out) To compare, how many people would write a web page that supports IE5? Some would, but would you generally advice methods to make IE5-compatible pages in 2013? Maybe we need a http://caniuse.com http://caniuse.com for Unixes.
- npsimons 14y agoI'll admit, I haven't had to touch OSF/1 in a long time, and I really would prefer to avoid it, but it's not always possible. Even modern systems aren't entirely consistent. As a real world example, I like to setup persistent SSH sessions on my laptop at home and personal smartphone. autossh is a nice solution to this, but it isn't available on my smartphone. To create one command across all environments that will create a persistent SSH connection, I do some OS and hostname detection to determine what I've got to work with, then create an appropriate function (either using autossh, or a more crude version using while). Then my dotfiles work across all platforms and I can keep them synchronized with git. Something like: if [ -n `command -v autossh` ]; then function ssh_persist { autossh -C -o "CompressionLevel 9" $@ } else function ssh_persist { while true; do ssh -C -o "CompressionLevel 9" $@ sleep 60 done } fi Edit: well, as long as I'm doing this much editing, I might as well make it better. To be sure, this isn't exactly what I actually run :) But it's a fair approximation and it gets my point across.
- iheartfisting 14y agoStick with twiddling JavaScript, hipster. Leave Unix for the grown-ups.
- jsaxton86 14y agoA much simpler solution is to comment your code: # Invoke curl in silent mode (-s), pipe the output to grep # and use an extended regex (-E) to only show the resulting # digits (-o: only print matching text, not the whole line): curl -s checkip.dyndns.org | grep -Eo '[0-9\.]+'
- deleted 14y ago[deleted]
- ralph 14y agoThe comment is needless noise that the reader must check for correctness and then determine whether it or the code is the intended behaviour when they differ. The same is unfortunately true of many comments. BTW, you've probably a bug in your regexp because you like to needlessly and wrongly escape a dot without knowing the regexp syntax you're using. Assuming you don't intend $ grep -Eo '[\.]' <<<\\ \ $ that is. :-) (curl's -s should be accompanied by -S IMHO, and it's brain-damaged in not having that behaviour under the one option.)
- npsimons 14y agoI don't like commenting the how and what; that's what the code is for. Comments are for "why".
- reledi 14y agoHow and what are good to include when describing the function, but not for specific statements of code.
- bobbydavid 14y agoI agree with ralph that these comments are annoying because I have to waste time reading them (what if they contain something important?) but they offer me nothing (I already know these flags). If you still prefer putting these hints in comments, I would rephrase your comments in a way that they are easily identifiable as useless, so I can stop reading them right away. For example: # -s flag: puts curl in silent mode. # -E flag: puts grep in extended regex mode. # -o flag: prints only matching text. curl -s thingy.thing | grep -Eo '[0-9.]+' An additional win: comments are slightly more future proof. When the comments inevitably become outdated, you'll now see: # -E flag: puts grep in extendex regex mode. curl -s thingy.thing | egrep -o '[0-9.]+' which is better because the comment is now merely irrelevant instead of actively wrong.
- nwatson 14y agoMake sure you have GNU versions installed and in your PATH. Write to those.
- marklit 14y ago# define all the 'magic letters here' (perhaps some if statements for various platforms): CURL_FLAG_SILENT=s # Then call them here: curl -$CURL_FLAG_SILENT ifconfig.me