Hyphen usage on Linux command options - linux

Until recently, I was under the impression that by convention, all Linux command options were required to be prefixed by a hyphen (-). So for example, the instruction ls –l executes the ls command with the l option (here we can see that the l option is prefixed by a hyphen).
Life was good until I got to the chapter of my Linux for beginners book that explained the ps command. There I learned that I could write something like ps u U xyz where as far as I can tell, theu and U are options that are not required to be prefixed by a hyphen. Normally, I would have expected to have to write that same command as something like ps –uU xyz to force the usage of a hyphen.
I realize that this is probably a stupid question but I was wondering if there is a particular reason as to why the ps command does not follow what I thought was the standard way of specifying command options (prefixing them with hyphens). Why the variation? Is there a particular meaning to specifying hyphen-less options like that?

There are a handful of old programs on Unix that were written when the conventions were not as widely adopted, and ps is one of them. Another example is tar, although it has since been updated to allow options both with and without the - prefix.

IMO the best practice concerning hyphenation is to use them as the default go-to. More times than not, they have accepted hyphen prefixes to most or all flags/options available for commands. Happy to be corrected if I am wrong in this instance. I am still new to this myself! :)

Related

In this bash script, what does "-" mean? And how could one find out what it means?

Here's the script:
node /app/ganache-core.docker.cli.js — quiet \ — account=”0x873c254263b17925b686f971d7724267710895f1585bb0533db8e693a2af32ff,100000000000000000000" \ — account=”0x8c0ba8fece2e596a9acfc56c6c1bf57b6892df2cf136256dfcb49f6188d67940,100000000000000000000"
I've read What's the magic of "-" (a dash) in command-line parameters?. And I took away that it CAN mean standard input... if the authors of the bash program define it as such.
However, here (link to ganache-core.docker.cli.js github file), I cannot find how or where the author of ganache-core.docker.cli.js would have defined the dash ("-") as standard input. Can someone point that out as well?
Edit: I am looking for confirmation that the dashes do mean standard input for cli args, but more-so looking to understand, WHY they should be definitively be interpreted as stnin when according the linked question above it's only a convention.
Edit2: I suspect the CLI arg parsing library is yArgs
This command line is just badly formatted. You're reading into something that isn't there. Some Blog software author thought it was a smart idea to auto-reformat the article so that hyphens and such were long dashes and quotes were "smart", etc. In the end, somehow a space ended up after the dash, before the next parameter.
For example, let's look at this:
node /app/ganache-core.docker.cli.js — quiet
Even if we assume that's a regular hyphen -, we know it's not supposed to have a space after it. It's supposed to be -quiet. And, if you have any doubt about this, you can read in the source code where this is defined:
.option('q', {
group: 'Other:',
alias: 'quiet',
describe: 'Run ganache quietly (no logs)',
type: 'boolean',
default: false
})
The same is true for -account.
And I took away that it CAN mean standard input... if the authors of the bash program define it as such.
Yes, that's correct. I don't know what this software does, but if it's reading from STDIN, it's not because you told it to on the command line. It's because that's what it does.

sanitize user input for child_process.exec command

I'm writing a CLI using node and I've arrived at the part where I take user input and append it to a string that is the command for the child_process.exec function.
const CURL_CHILD = exec('npm view --json ' + process.argv[2] + ...
I am trying to figure out what I need to do to process.argv[2] before I pass it to the exec function. I've surfed around for a while and haven't found any questions or answers that address this specific case.
What is the best way to sanitize this user input for this particular use case? What is actually needed here?
Update
I'm still surfing around trying to learn and answer my own question and found this link which suggests I use js-string-escape (a node package). I'd really like to use something native/vanilla to do this. Does node have any tools for this?
Update 2
I finally stumbled upon the buzzwords "command injection" and found a slew of articles recommending the use of child_process.execFile or child_process.spawn. I'm still curious if there is a native way to sanitize the input, while still securing the full shell process created by child_process.exec. I am leaving this open in hopes someone can answer it.
Your user input arguments may contain variable chars that the shell is going to interpret them in its own way. So for instance, in Linux, $ has a special meaning.
If you want to use such argument as-is avoiding the shell interpretation, you have to escape them. The same we do with some special chars in HTML (eg. < and > has special meaning so we use to escape them in HTML like < and respectively >). The same applies here.
So the answer to your question is first to find out the special chars in your shell/environment and escape them.
A good rule of thumb is to escape chars like double-quote ", single-quote ', space , the dollar-sign $ (because it's an Illuminati symbol, right? ;-), the grave-accent ` and obviously the backslash \.
So let's suppose that your command is the one below. To escape it just use some simple regex like this:
cmd = "npm view --json " + process.argv[2];
escapedCmd = cmd.replace(/(["\s'$`\\])/g,'\\$1');
I hope it helps :-)
Try the npm package escape-it. Should work with *nix OSes, but has some support for Windows, too.

How to accept the 'Did you mean?' terminal/git suggestion

This is a simple question.
Sometimes on a Terminal when you make a small mistake the console asks ¿Did you mean ...? - ¿Is there a way to quicky accept the suggestion?.
For example:
$ git add . -all
error: did you mean `--all` (with two dashes ?)
Is there a command that repeats the last line, but with the two dashes?
If you forget to write sudo, you can just do sudo !! and it will solve your problem. I want to know if there is something similar but for the error: did you mean case.
In the case of...
$ git add . -all
error: did you mean `--all` (with two dashes ?)
...the message is written by git directly to the terminal. This means that bash has no way of knowing what message was written; it would be literally impossible to implement anything in the shell that could automate putting that correction in place without making programs run under the shell considerably less efficient (by routing their output through the shell rather than directly to the terminal) and changing their behavior (if they ever call isatty() on their stdout or stderr).
That said, you can certainly run
^-all^--all
...if you haven't turned history expansion off, as with set +H (if off, it can be reenabled with set -H). I typically do turn this functionality off, myself; it's often more trouble than it's worth (making commands which would work perfectly well in scripts break in interactive shells when they use characters that history expansion is sensitive to, particularly !).

Command to list word completions

I once found a built-in command that would take a prefix as an argument and return all words that could complete that word. So for example,
>> COMMAND cali
California
calibrate
calibration
........
of course it would list a lot more words, in alphanumerical order. It was really useful, and optionally took a file other than the default to look in.
I'm not just trying to produce this behavior: there are obviously a million ways to use grep, sed, awk, perl, or INSERT TURING-COMPLETE LANGUAGE HERE to get this. I'm looking for the command.
Unfortunately it's hard to google something when you don't remember the name, but while it might not have been POSIX standard it was definitely a very common Linux utility, does anyone know what this was called?
Found it: it's called look, and it seems to have been around Unix since V7. (The man page is dated 1993!)
It does a binary search on the optional second argument to find all matches, defaulting to /usr/share/dict/words.
Not really a builtin command, but there is /usr/share/dict/* and grep:
$ grep -i '^Cali' /usr/share/dict/words
Caliban
Calibanism
caliber
calibered
calibogus
calibrate
calibration
calibrator
calibre
Caliburn
...

What does "#$" mean in bash?

Say for example a script begins like this
#!/bin/bash
#$ -S /bin/bash
#$ -l hostname=qn*
and then later down the page the actual script comes into play. My question is what does the "#$" symbol mean or do?
Are you by any means running on a batch cluster? Like Sun Grid Engine? There might be special meanings in scripts intended to run as a batch job.
https://www.wiki.ed.ac.uk/display/EaStCHEMresearchwik/How+to+write+a+SGE+job+submission+script
Update:
above link blocks when used from stackoverflow.com (works from google.com)
alternatives:
http://www.cbi.utsa.edu/sge_tutorial
http://web.njit.edu/all_topics/HPC/basement/sge/SGE.html
Lines beginning with # are comments. The first line may begin with #!, but it's still a comment to bash and is merely used to indicate the interpreter to use for the file. All other lines beginning with # are absolutely unimportant to bash, whether the next character is $ or anything else.
They seem to be parameters for the Oracle (ex-Sun) Grid Engine, look at this SO question or this one.
They are heavily using these kind of comments.
Those line are important for queue systems like sbatch.

Resources