Back

Start all of your commands with a comma (2009)

495 points1 dayrhodesmill.org
TacticalCoder13 hours ago

I do something a bit special... Instead of naming my script foobarnator (and hence risking that another foobarnator may exist in the future and may clash with my script), I name my script foobarnatorToBeAliased.sh. Then in my list of aliases I alias foobarnator to foobarnatorToBeAliased.sh.

The alias itself looks a bit weird in that to pass arguments to an aliased command you need to use a function (in Bash at least AFACIT) but it all works fine.

As aliases aren't sourced when other scripts are running, I'm sure my scripts/commands ain't ever going to clash with anything.

I've been doing that since years.

It also works fine to add "wrappers" to existing commands: for example to add additional input sanitization catching common mistakes I'm making when calling some commands.

blep_11 hours ago

> The alias itself looks a bit weird in that to pass arguments to an aliased command you need to use a function (in Bash at least AFACIT) but it all works fine.

No you don't:

    $ alias say=echo
    $ say beep
    beep
You do need to do something special the other way around (if you wrap a command in a function it needs to explicitly pass the arguments on).
tomjakubowski9 hours ago

Another advantage of aliases: in zsh at least, autocompletions of the aliased command Just Work (it breaks in wrapper functions)

ta864513 hours ago

What has always been a blocker for me to follow your example, is the desire to use many such scripts from the command lines provided inside an $editor or $email client. There probably is a way to configure both of them to see the aliases, but it's more straightforward to just have everything in the PATH.

nequo12 hours ago

Yes, it seems cleaner to just put "export PATH=$HOME/bin:$PATH" in $HOME/.bashrc. That avoids collisions with /usr/bin and /usr/local/bin. (Or rather, resolves collisions in favor of your personal bin directory.)

rlkf11 hours ago

Porque no los dos? It seems that

    function ,foo() { printf "Fooo\n"; }
    ,foo
actually works! (at least in my bash 5.0.17 shell)
omaranto4 hours ago

I know this is unimportant, but the phrase is "¿Por qué no los dos?".

deathanatos10 hours ago

I used to do this, but it doesn't work with things like "watch".

chrisshroba10 hours ago

I actually just learned from a different HN thread yesterday [1] that aliases do get expanded if you add this to your shell's rc file:

    alias watch='watch '
Specifically, if an alias ends with a space, it will cause the subsequent arg to be expanded as well. For example, try running:

    alias beep=echo
    watch beep hello # This will fail
    alias watch='watch '
    watch beep hello # Now it works!
[1]: https://news.ycombinator.com/item?id=31830879
Jistern8 hours ago

I start my aliases with a period so that I have...

.foo1,.foo2, .foo3, and so on.

BiteCode_dev28 minutes ago

Can't you just declare:

    my() {
  script_name="$1"
  script_path="$HOME/.local/bin/my/$script_name"
  shift
  $script_path "$@"
    } 
So you have your namespace ? Of course that mean you must put all script in .local/bin, not anywhere in the PATH, and some more work is needed to figure out completion.

But it seems less weird than the comma.

Timpy14 hours ago

If I unknowingly named my command the same as some system command and the custom command ends up earlier in my path it doesn't really cause any problems does it? I wasn't using that system command anyways, and my custom command is only going to take priority if my .bashrc file was run first.

Taywee14 hours ago

It can if you are executing programs that then try to execute those commands and get your commands instead.

nerdponx13 hours ago

I wish it was easier to create "snapshots" of a particular set of environment variables in order to use them later as run environments. I also wish that Unix desktop environments generally made it easier to manage env vars, but that's another complaint. And don't get me started on PAM env vars...

fragmede12 hours ago
nerdponx8 hours ago

I use Direnv in all of my projects, but it doesn't make it any easier to manage consistent groups of env vars or assign different executables to run in different groups.

OJFord13 hours ago

Just env vars?

    env > "$(date +s).env-snapshot"
(And use it again slightly more awkwardly as

    <$file | xargs -I@ echo '"@"' | tr '\n' ' ' | xargs -I@ env @ cmd
or something more convenient to `cmd`.)
+1
sigjuice10 hours ago
LanternLight8311 hours ago

Direnv has been mentioned, and it meshes well with functional package managers like Nix and Guix, each of which include the concept of "Profiles". Each profile can access a specific set of programs via it's environment, but PATH is far from the last variable that you can use Direnv or Profiles to control.

verrp12 hours ago

> I wish it was easier to create "snapshots" of a particular set of environment variables in order to use them later as run environments.

docker gives you this (but only as part of a whole ecosystem, which for various reasons you might not want to hitch your horse to).

xigoi14 hours ago

Until you use a different machine and accidentally type your command without realizing it's not there.

tasuki14 hours ago

Yes, all of that. And if you later decide to start using the system command, you just rename your custom command.

eriner_13 hours ago

I use zsh and have the following alias (rather, function):

``` cp () { rsync -avhW --progress --inplace ${@} } ```

If I ever need to use the `cp` binary, I execute `=cp`, which evaluates to `/bin/cp`.

notaclevername37 minutes ago

I use a similar trick for text expansion. All my abbreviations start with a semicolon (;). It’s on the home row, it never occurs at the start of a word in normal typing so I never have a false positive expansion, and it’s easy to remember.

vimsee4 hours ago

I started creating wrapper-scripts or simple scripts that has the commands with my prefered options or a selection menu for said command. I have started calling those scripts my<command>

rsync becomes myrsync mount becomes mymount ssh becoms myssh

No collision and the naming convention empathise that it is indeed used be MYself.

prosaic-hacker14 hours ago

I have used a similar windows trick. I wanted to add to the default window system a place for my library of tools. Most are "portable" cmd apps from various sources (sysinternals, nirsoft). I put them all into a directory called ] in the root of a drive.

Because of some common layout of keyboards the \ and ] are near each other, or in reach of left and right pinkies I can type \]\ before the name of the tools. This means I don't even have add a dir to the path.

I am sure this violates someone sensibilities but it has saved time over the years as a consultant when I had to deal with a wonky machine and owner did not want permanent install of diagnostic tools.

lkxijlewlf12 hours ago

I put c:\tools in my path, then put shortcuts to all my tools in there (ie: shortcut to AgentRansack named ar). Now, I pull up the run command (WND+R) type ar and agent ransack opens.

RajT887 hours ago

Permissions!

Post-vista, c:\programdata\tools

Set yourself a %TOOLS% environment variable.

behnamoh5 hours ago

Unrelated but I heard it's possible to rename c:\ to /usr/bin or something, depending on your usage. I personally wouldn't mind renaming it to ~/<user-name> and be able to use some of my dotfiles in Windows.

top_kekeroni_m84 hours ago

It's possible, but 90% of software will break because of this lol

aendruk13 hours ago

I tend to give programs longer, more descriptive names and then do the short names as shell aliases. That way there’s little risk of name collision for the original program, scripts using the canonical name remain readable, and the shorthand is free to evolve to fit varying work habits.

quasarj13 hours ago

My keyboard came with a tab key, so I don't worry about my commands having short names.

keybored13 hours ago

Until you have five commands which all use the prefix `sort-incoming-` and then three commands named `sort-incoming-hourly` and `sort-incoming-monthly` etc.

layer813 hours ago

It would be nice to have camel-case completion in the shell, i.e. have “SIH” be completed to “SortIncomingHourly” and “SIM” to “SortIncomingMonthly”, etc. (only for upper-case characters). That way one could get more mileage out of the possible character combinations.

andra_nl11 hours ago

Well, not exactly tab completion, but I have `fzf`[0] tied to my history search.

That allows me to type `soriloco`, punch ctrl+r and be prompted with `some ridiculously long command` (if, of course, I've run it before).

Combined with infinite history this trick has saved me a bunch of typing and even proper remembering. :P

[0]: https://github.com/junegunn/fzf

bergenty10 hours ago

Why do the names have to be shorter, I never have to type it all out just the first couple of letters and then autocomplete. Dealing with aliases/“shortcuts” is such a pain plus I hate that pattern anyways.

jamespwilliams14 hours ago
scubbo12 hours ago

Do you know any of the history of why your link to `.../Shopify/...` redirects to `.../nix-community/...`? Is the latter an open-source contribution by Shopify?

jamespwilliams11 hours ago

I think it was originally developed and maintained by Shopify, but was then handed off to the nix community

leblancfg10 hours ago

Correct. Source: I used the shit out of that command. Thanks Burke

behnamoh5 hours ago

This is for Nix.

Taywee14 hours ago

Clever trick. Too bad there's no good way to namespace commands. It would be interesting if you could have, for instance:

  $ mkdir -p /tmp/bin/my
  $ printf '%s\n%s\n' '#!/bin/sh' 'echo hello' > /tmp/bin/my/hello
  $ chmod 755 /tmp/bin/my/hello
  $ PATH="/tmp/bin:$PATH"
  $ my/hello
  hello
floren13 hours ago

Plan 9 does that, I'm not sure why it never made it into Unix because I always loved it. Your networking-related commands were in `/bin/ip` and you'd run e.g. `ip/ping 1.1.1.1`. If you created the dir `$home/bin/rc/my` and put scripts in it, they would have been runnable as `my/hello` etc like in your example.

yellowapple11 hours ago

Plan 9 also more or less does away with the concept of $PATH in the first place; just union-mount (with `bind`) whatever you want onto `/bin` and call it a day. Yet another thing that would've been great for Unix-likes to pull in (I think some Linuxen can technically do it, but with some limitations).

theblazehen3 hours ago

I've tested it and it works on Linux (bash and zsh), at least for your custom commands

keyle10 hours ago

no matter which kind of twisted idea someone comes up with related to terminals, there is always a guy who chimes in with "in Plan 9 you can do that...". It makes me smile every time. :)

Someone2 hours ago

I think shells should support that, allowing you to do

  $ my hello
It would mean tools such as git, microk8s and aws wouldn’t have to implement that “look up first argument, check whether it’s a command I know, and if so, run it” on their own, and would have slightly simpler auto complete configs.

It also could mean launching fewer processes (for the case where ‘my’ is a script or executable that looks up the location of ‘hello’ and launches it)

gpderetta10 hours ago

What about:

  my hello
I.e. only my needs to be in the global namespace and all other commands are resolved by my itself.
layer813 hours ago

You could (ab)use home directories for that. I.e. place your hello into /home/my, and then you can invoke it as ~my/hello. You even get namespace completion for free after the `~`.

Beltalowda10 hours ago

In zsh you can do "hash -d my=/path/to/my" and then you can use "~my/hello" from anywhere, and it doesn't need to be in /home.

lou130613 hours ago

Ahem, technically there is one way (don't know if it is "good", though):

    $ export $MY = /tmp/my
    $ $MY/hello
    hello
woodruffw14 hours ago

I don't know if I would actually recommend this, but it works:

    $ touch foo::bar
    $ chmod +x foo::bar
    $ ./foo::bar && echo $?
It's an empty file so it does nothing, but most shells' lexers should be smart enough to not try and lex '::'.

Edit: Forgot to mention, this also works with bash functions and aliases. I'm not sure if POSIX sh will allow it. You can also do things like this (again, not sure I'd recommend it):

    $ alias +x='chmod +x'
ianthehenry11 hours ago

zsh can do this if you set the PATH_DIRS option, but if I remember right it doesn't autocomplete deeply nested directories, just one level.

I made a little tool that dispatches hierarchical commands in a slightly nicer way, with intelligent autocomplete with command descriptions: https://github.com/ianthehenry/sd

eurasiantiger14 hours ago

Just add another comma. Of course, this needs some deeper magic to work :)

    ,my,hello
jwilk13 hours ago

> mkdir -p /tmp/bin/my

This is not a secure way of using /tmp.

Taywee12 hours ago

Sure, but that's not the point. It's just an illustrative example, and I wanted a short absolute path that is easily recognizable to the reader. I'll fix it, though, to avoid having an example with bad security practices, though.

edit: Or I would fix it, but I guess I can't edit it. Oh well.

ZeroGravitas2 hours ago

Similar to the vim <leader> key concept which many people use comma for.

https://tuckerchapman.com/2018/06/16/how-to-use-the-vim-lead...

jedberg9 hours ago

Commas can also be used in filenames to help you sort things instead of using underscore as a separator, useful for the same reason -- you don't have to hit shift to type it.

ok_dad14 hours ago

I use this method for aliases in my `.*rc` file so I can remember what the heck I called things. Otherwise, I forget whether I have to type something like `COMMANDNAME-log` or `log-COMMANDNAME` or some other weird combo like `print-COMMANDNAME-log`. With a comma, I type `,<tab>` and get all of my custom commands listed easily.

gregnavis12 hours ago

I do something similar but 1. for aliases and 2. use period. For example, when working on a Rails project I define the following alias:

    function .routes() {
      if [[ $# -eq 0 ]]; then
        .rails routes
      else
        .rails routes | grep $@
      fi
    }
where .rails is another alias (for running bundle exec rails ...). I can then run ".routes webhook" and see all routes containing "webhook".

Last but not least, I automated the whole thing with bash-ctx (https://github.com/gregnavis/bash-ctx).

tlarkworthy43 minutes ago

I misadvertantly lower cased my functions names when working on .net, but it made it super easy to find my code in the stack traces. (.net idiom is capitalism the first case of a function name). Usually the cause of stack traces was my code so it was an unexpected productivity booster.

heynowheynow14 hours ago

Cool.

I have a script that creates new ~/bin scripts that checks for collisions locally (functions, builtins, and executables) and in linux distros.

For example, I have a ~/bin/up script on every box and platform to install updates. So far so good on collisions.

reidjs15 hours ago

This is a good trick to avoid collisions with system commands. Anytime you add one of your own executables to PATH, prefix it with a comma (,). This way you avoid name collisions and have a handy way of seeing what commands are available on your system using tab completion (, then tab lists all of your personal executables)

urmish14 hours ago

Is this comment from a bot? You just reiterated everything from the article.

heleninboodler13 hours ago

This is an explanation that the parent comment simply reiterated the point of the article rather than adding content.

scubbo12 hours ago

This is a link to a story titled "This is the title of this story, which is also found several times in the story itself": https://stuff.mit.edu/people/dpolicar/writing/prose/text/tit...

acomjean6 hours ago

You are right, but I’m guessing a lot of people don’t read the linked article. It’s a pretty good summation.

Though it doesn’t mention using ~/bin. I use that but don’t add it to my path, so I have to explicitly call my scripts.

The comment history suggests it isn’t a bit though.

behnamoh5 hours ago

Related to GP, here's an interesting article: https://rhodesmill.org/brandon/2009/commands-with-comma/

malkia12 hours ago

I almost always add "," in cmd.exe to anything I run from Windows Command Prompt? Why? Because cygwin, or mingw's `dir.exe` would be called instead of built-in dir (well, this is further complicated that I don't really use `cmd.exe` but FAR Commander), so if I want to enforce the built-in over external (same name) command I have to prepend it with "," - so I basically started typing "," in front of each of my commands...

dan353hehe14 hours ago

I do basically the same thing with any aliases or commands that I have just for me. Except I prefix with _ (an underscore.) Having some sort of prefix is extremely nice as it ensures you never override a built-in on accident, AND it makes it easy to tab complete just the ones that you want.

For example I have ‘_f’ aliased to a fuzzy find command that will launch vim on the selected files, and a different one for launching sql clients to various servers etc.

As a prefix, commas work great!

simias14 hours ago

Unfortunately zsh uses the underscore prefix heavily, _<TAB> results in hundreds of possible completions.

pxeger13 hours ago

In Zsh, you can used named "directories" (actually it works with normal files too) with tildes for the same effect, except that they must be explicitly defined, so there's no risk of collisions.

    hash -d e=/bin/echo
    ~e hello world
https://ato.pxeger.com/run?1=m724qjhjwYKlpSVpuhY3lTMSizMUdFM...
quickthrower25 hours ago

Finally, a weird tip that is really good!

avodonosov13 hours ago

Is it secure to have ~/bin/ it the PATH?

paulv13 hours ago

The issue is that an exploit could write a file in ~/bin/ and trick you in to executing it. But, if something malicious is writing files in your home directory, you've already lost.

syoc13 hours ago

If someone can write to your home directory they can also update your bashrc file and add whatever they want to PATH

suprjami13 hours ago

It's a default behaviour of at least bash. It's as secure as your home directory is.

parentheses7 hours ago

the aesthetics of the comma for daily use are not good

jrms12 hours ago

I just add the .sh suffix/extension to them... And I use j- as prefix for the "tab trick"

krnlpnc9 hours ago

I do the same thing but with prefix …

gumby13 hours ago

clever idea, but does it need such a long post to describe?

copperx11 hours ago

Two phone sized screenfuls of text is too long now?

I'm genuinely interested to know whether you read longform text at all.

gumby10 hours ago

I mostly read books. I don't want to pick on the author, but since you asked I will be more specific: this idea would fit in a tweet.* It's a good idea, but the long build up reminds me of recipe sites.

* I just use "tweet" as a unit of measure, like "the size of two elephants". I do not advocate the use of twitter.

vxNsr4 hours ago

twitter was still fairly new when this was published and only allowed 140 chars which definitely isn't enough.

keybored13 hours ago

Cool.

I’m gonna start them with `å` just to be a little different.

ghostly_s13 hours ago

I've never once had a problem with one of my commands shadowing a system command so I think I will continue on rather than solving this non-problem, thanks.

hdjjhhvvhga13 hours ago

In the comments, the author argues against the underscore by saying Bash/Zsh already uses it for completion. But it looks like it's a Zsh thing - at least my Bash install is pretty conservative about it.

kelnos13 hours ago

Not sure what I have installed/sourced, but "_<tab>" says there are 381 possibilities for me. (This is with bash.)

Also in the article itself, the author argues against any prefix char that requires using the shift key.

luispa8 hours ago

haha neat.

potiuper14 hours ago

Tomte, is there any reason why are you reposting this now? https://news.ycombinator.com/item?id=22778988 Such as some thing that was not covered before? To all the prejudiced bigots down voting this comment, the question does not imply that it should not have been posted.

dang13 hours ago

Reposts are ok after a year or so. This is in the FAQ: https://news.ycombinator.com/newsfaq.html.

Could you please review the site guidelines at https://news.ycombinator.com/newsguidelines.html and stick to them? Your last sentence there breaks more than one of the rules.

potiuper13 hours ago

Again, to reiterate, the original comment was not a statement that this should not have been reposted. I am not sure how I could make that clearer? I have read the site guidelines. Many of them are subjective and inconsistent with unknown applicability. If you, as the administrator, are unable to accept that evaluation, then please just delete this account and all associated posts.

NateEag6 hours ago

"Please don't comment about the voting on comments. It never does any good, and it makes boring reading."

That's what dang was referring to, I believe, not some hypothetical implication.

bravasaurus14 hours ago

That was long enough ago that I think it’s worthy of being reposted. It was new to me.

geph202112 hours ago

Tomte has >100k karma (that seems insanely high, but also a 10+ year-old account), and a plethora of reposts in his submission history.

If you wanted to juice-up your karma (I can't fathom why someone would bother doing this), it seems like simply reposting popular submissions from previous years is a very easy way to do that (if it was popular on HN in years past, then it's likely it would again). I'm not saying that's Tomte's motivation.

This would also result in interesting/popular submissions resurfacing again and again, which anecdotally I can say I've seen quite a bit on HN. I don't think that's necessarily a bad thing, but perhaps it can get tedious for some. For example, I had not read this post before and found it useful/interesting.

alar4414 hours ago

Oh no it was posted over 2 years ago

Maursault11 hours ago

The comma is employed in bash and other shell for brace expansion.[1] I can't see how this would conflict with OP's master plan, but I have fundamental objections towards the depths of OP's laziness. Lazy is ok, but there should not be competition to see who can be laziest. At some point, things just won't compress any further, and the attempt at further streamlining efficiency beyond what is useful has a negative effect on efficiency overall. Besides, tab completion is fine as it is and doesn't need what passes for a hack these days. To be clear, contrary to what OP has claimed about not being creative enough to come up with original script names that won't conflict with the flood of new Linux commands every update (wot? LOL), this is only about the OP not being satisfied with tab completion.

[1] https://superuser.com/a/184493

SrslyJosh8 hours ago

That's a lot of words to say "I don't like this" and insult folks who put time and effort into customizations that improve their own computing experience.

Maursault8 hours ago

> who put time and effort into customizations

I believe you have made my point quite well once it's understood you are here referring to none other than prefixing script names with a comma. Any words wasted on anything other than the subject is a waste of words, in your comment's case, both ad hominem and straw man fallacies.