Hacker News

Uptrenda
Forget Flags and Scripts: Just Rename the File robertsdotpm.github.io

castral3 days ago

It feels wrong but I can't quite put my finger on the reason why... It will make version control more hectic, for sure. It also seems to be conflating identification with configuration which seems non-ideal. What about versioning and upgrading? How do I find a "well-known" entry point with a file name of flags? Every read now becomes an expensive find and grep lesson... Yeah, I don't like it.

IanCal3 days ago

There's a whole host of problems with it. I'm almost on the side of saying this is a well written troll post but...

To have two different things you need to run, now you need to have multiple copies of the same thing.

What does the parsing? How do you split out a URL, what order are the "flags" in? Do you have named arguments, etc? Well now you need to have your own custom parsing library instead of just using exactly what anyone else would use.

Where do you go for help? Do you rename it to my_program_help.exe then rerun it?

What about chaining things together? Anything dynamic? Is the caller script expected to rename your program before running it?

> fetch---api.github.com---repos/owner/project---q=stars>100---o=json.exe

Oh lord.

> Imagine install_PY3_MODULE_NAME.exe. It reads the filename, extracts the Python module name, downloads dependencies, sets up Python if needed, and creates a launcher. Rename it, and you have a new installer for a different project. Icons, mirrors, or other metadata can also live in the file as resources – all self-contained, all shareable.

Imagine changing that to "install_python.exe --module module_name".

The thing you really want to do instead is have a single executable, then have scripts or even aliases that are named for what they do that are super thing wrappers. One copy, no moving, renaming, anything.

`fetch---api.github.com---repos/owner/project---q=stars>100---o=json.exe`

and 50 different copies for various different projects, is replaced with

`fetch.exe`

and

`top_100_github_repos.exe`

`highest_rated_github_repos.exe`

`get_weather.exe`

Which are single line scripts that pass on arguments to the base program. Which also means you can fix any issues in one place.

tormeh3 days ago

It's unexpected. When trying to understand a system it's beneficial if it adheres to expectations, as it means we're not forced to consider the entire possibility space of what a program can be. Utilizing the entire possibility space is usually the domain of malware, which tries to be surprising.

antonyh3 days ago

The executed filename could be a symlink to a single common binary/script.

Ferret74462 days ago

It feels wrong because it's strictly less efficient and inconvenient.

Instead of doing foo --bar you are now doing ln foo foo--bar && foo--bar. It's less efficient on the file system level. It's less efficient on the program level. It's less efficient to type. Why

booleandilemma3 days ago

It feels wrong because it's a hack. You're using the name for something else.

vector_spaces3 days ago

This strikes me more as a matter of taste, i.e. more art than something which can be provably wrong, or correct for that matter. The concerns you outlined might be concerns the author doesn't have to worry about for whatever reason -- if this fits neatly and seamlessly into their existing workflows then that's great, and I for one appreciate learning about other peoples' approaches like this even if they don't immediately work for me

IMV it's a clever trick, and like you my instinct is that if I attempted to integrate this into my own workflows, I would endure some sort of hardship down the line but it's not immediately obvious when or how. Or maybe for certain things it would be fine and less painful than other options, like other similarly clever tricks I felt uneasy about at first

Charon773 days ago

If the rename changes the entire behavior (see busybox comment) it makes sense. But defining multiple arguments? Now the author had to use -- in the file name where using space would do (and the OS splits it for you)

And good luck trying to run the same programs with different arguments. You'll have to take turns renaming the file, or create hardlinks just for ephemeral arguments.

It can be useful but there's time and place to do it.

usrusr3 days ago

The beauty is that often used parameters don't live (and die) in .bash_history. They live on the file system. Sure, the same can be achieved by wrapping in a script, but that needs both a name and content and they better stay in sync on changes or else....

> And good luck trying to run the same programs with different arguments

I don't read the idea as trying to replace arguments as in remove, "don't ever use arguments anymore", but as a DSL for _allowing_ to pull supported arguments into the filename. Basically an args list preprocessor. That would only take away your freedom of including triple-dashes in your file name without there being consequences.

Ferret74462 days ago

You could just fix whatever is wrong with your bash history and/or learn to use the history properly. Bash also supports programmable completion so you could also use that than come up with some weird hack.

This smells like an XY problem

vaginaphobic3 days ago

[dead]

ycombiredd3 days ago

This just gave me a flashback to something I made a long time ago, which was a tool to create a file that was a named pipe - the contents of which were determined by the command in its filename. If I remember correctly (and its embedded man page would seem to validate this memory), the primary impetus for making this tool was to have dynamically generated file content for purposes of enabling a remote process execution over server daemons that did not explicitly allow for it, such as finger, etc, but were intended only to read a specific static file.

https://web.archive.org/web/19991109163128/http://www.dfw.ne...

Using named pipes in this manner also enabled a hackish method to create server-side dynamic web content by symlinking index.html to a file created in this manner, which was a secondary motivator, which seems kinda quaint and funny now, but at that time, it wasn't very long after just having finally decommed our gopher server, so fingerd was still a thing, Apache was fairly new, and I may still have been trying to convince management that the right move was not from ncsa httpd to Netscape Enteprise Server, but to Apache+mod_ssl. RSA patent licensing may still have been a thing too. Stronghold vaguely comes to mind, but I digress.

Yeah, programs that do stuff based on filename, like busybox. Oh, and this long forgotten artifact this article just reminded me of that I managed to find in the Wayback Machine, a tool to mknod a named pipe on a SunOS 4.1.4 machine, to get server-side dynamic content when remotely accessing a daemon that was supposed to return content from a single static file. Ah, memories.

CrendKing3 days ago

Yesterday I found an app that I need to keep my bluetooth headphone from entering sleep mode. It is Sound Keeper: https://veg.by/en/projects/soundkeeper/. And it uses exactly the same approach talked in this article. For example, normally its filename is SoundKeeper64.exe. But if you rename it to SoundKeeper64AllOpenOnly.exe, it switches behavior to operate on "All" devices with the "OpenOnly" mode.

trashb3 days ago

Funny idea and it may make sense in some special scenarios.

However I would like to point out that you are limited to path and filename length.

Maximum file path length in Windows is 260 characters. (32767 characters with longpath enabled). Individual filenames max out at 255 characters.

Maximum file path length in Linux/Unix generally is 4096 characters. On ext4 it seems max filename length is 255 bytes.

Additionally you will be constrained by the characters allowed in files. Therefore it will be strange to pass a filepath to a program like this.

cheevly2 days ago

That's what directories of files are for. The file system as a cognitive twitter.

krick3 days ago

Bonus points for originality, but that's really just some crackpot idea.

cheevly2 days ago

count_the_files_in_this_folder.bat

```

@echo off setlocal

set "PROMPT=%~n0"

setx OPENAI_API_KEY "sk-proj-x" >nul 2>&1

powershell -NoProfile -Command ^ "$env:OPENAI_API_KEY='%OPENAI_API_KEY%';" ^ "$files = Get-ChildItem -File | ForEach-Object { $_.Name };" ^ "$filesList = $files -join ', ';" ^ "$systemPrompt = 'You are only allowed to respond with executable PowerShell commands. The folder contains these files: ' + $filesList;" ^ "$userPrompt = '%PROMPT%';" ^ "$body = @{ model='gpt-5.4'; messages=@(@{role='system'; content=$systemPrompt}, @{role='user'; content=$userPrompt}) } | ConvertTo-Json -Depth 5;" ^ "$response = Invoke-RestMethod -Uri 'https://api.openai.com/v1/chat/completions' -Method Post -Headers @{ Authorization = 'Bearer ' + $env:OPENAI_API_KEY; 'Content-Type' = 'application/json' } -Body $body;" ^ "$psCommand = $response.choices[0].message.content;" ^ "Write-Host '---AI OUTPUT---';" ^ "Write-Host $psCommand;" ^ "Invoke-Expression $psCommand"

pause

```

japanuspus3 days ago

It should be trivial to combine ephemeral options with file name options, which seems like it would be the best of both world.

With some agreement on mapping (maybe just `%HH` for anything outside `A-Z a-z 0-9 . _ -`), this could be completely standardized and made part of standard library argument parsers.

I could see a bunch of my utility scripts replaced with a python script and a `uv` shebang if this was in argparse.

applfanboysbgon3 days ago

Or you could just use a config file. Many programming languages use something like a .csproj or .toml or whatever which is merely a fancy way of writing CLI arguments for the compiler that will be invoked during the build process; for a random executable it can be even simpler, just write a tiny library that parses a plaintext string into arguments and include it in each of your programs. You can even store multiple configs in one file this way, separated by linebreaks or whatever you choose.

foo.exe

foo.config

foo.config contents:

  --flag1 --flag3
  --flag2 --flag5 some_param
run: `foo.exe --config 2`

Compared to shell scripts, this is a portable solution that will work across different environments, and compared to including arguments in filenames, it's not insane and doesn't require duplicating the entire binary to maintain multiple configs. The only merit I see to the filename approach is that it gives you a single file instead of two (if you have exactly one config), but I don't think that tradeoff is worth it.

IanCal3 days ago

And you can then set things like "open with" if you want click -> launch with specific app.

The biggest thing for me is that you can name the configurations for what they're doing not how.

For example:

> fetch---api.github.com---repos/owner/project---q=stars>100---o=json.exe

could become something like

top_starred_repos.bat/exe/sh

This also removes the need to get myself and others to battle escaping problems as you start adding arbitrary arguments into this.

tehbeard3 days ago

This is the classname soup mess of TailwindCSS (when people don't precompile that away) manifested into the CLI...

Cthulhu_3 days ago

Careful, comments like that may actually sell people to the idea.

csb63 days ago

Seems a lot easier to have a --help flag that lists all of the options and their function. That is self-documenting (assuming the descriptions are useful) and helps with discovery. Changing the name of the file to foo--bar.exe doesn't seem any easier than writing foo.exe --bar

ziotom783 days ago

I too was perplexed, but the main use case seems to be when you want to share a particular configuration or need to be sure that you always use the same set of flags:

> Flags are ephemeral – you have to share the command line or wrap it in a script. Scripts depend on environment, which can break portability. Filenames solve both: the program describes itself, requires zero setup, and any configuration can be shared by simply renaming the file.

[Emphasis added] Although I find a script that wraps the command and calls it more versatile, there might be some value in this idea for some very simple cases, like example #4.

Cthulhu_3 days ago

I suppose scripts are OS specific (mainly Windows and "everything else", because #/bin/sh is everywhere else).

That said, apparently there's cursed methods of having a universal shell/batch file of sorts, according to https://stackoverflow.com/questions/17510688/single-script-t....

Anyway, I'd argue for the vast majority of cases, a shell script that wraps the command and its flags is fine.

themafia3 days ago

> you have to share the command line or wrap it in a script. Scripts depend on environment, which can break portability

I get the problems but I don't think I've ever had both at once. A need to portably wrap and share a specific command line for a specific program?

For the case of broadcast it seems easiest to just document the proper command line options. For the case of "unicast" I can just ask the other person what their environment is so I can craft the appropriate wrapper for them.

The area of overlap in the Venn diagram is infinitesimally narrow.

IanCal3 days ago

Also, you can share the generic program and then share wrapper scripts that are named for what they do rather than a series of flags. Then to share, you're just sharing a config file, script or similar that calls "whatever.exe --dir=./blah --run=12 --batch=false"

csb63 days ago

It just doesn't seem that hard to send someone a message stating: "Run foo.exe --bar from command prompt/the terminal"

ziotom782 days ago

True, but what if you need to re-run that command several months later and you can no longer find the message?

nxpnsv3 days ago

I guess you could rename it to foo--bar--help.exe to get the help. An awkward workflow indeed

unixzii3 days ago

That reminds me of self-extracting archives. Perhaps we could also create self- mutating programs that modify themselves to embed the flags.

neRok3 days ago

That would actually be handy, because I'm personally sick of all the ~2KB ini files that "portable" programs* leave all over the place. It would be awesome if they instead came with a few KB internal padding that was used to store the config (so the filesize doesn't change, to not affect simplistic sync/backup routines), and then silently updated their config on-the-fly.

* ini spawning programs include CPU-Z, HWMon, HWiNFO, BulkRenameUtility, HxD (newer versions spawn a settings folder), seemingly every NirSoft + O&O tool - and the master of all spawners: explorer.exe dropping desktop.ini's.

neRok3 days ago

Thinking more, Microsoft should definitely implement this as a standard feature. They should be able to implement it quite quickly, and then promote it as a win for Windows AND dotnet - and they need some wins!

So there would need to be standard defined, whereby the exe would basically embed a "protobuf" definition in it's header area, and then a maximally sized "message" could be tacked on to the end of the exe. In the Explorer>file-Properties screen, there could be a config tab that shows the current config (and maybe allows direct editing), plus buttons for import/export/clear config. And as part of the standard, options could be defined as public/shared or private, and thus private fields would get encrypted by the OS/TPM, which means sharing an exe with sensitive info embedded would "not be a risk". The config tab could even have a "meta" option for things like "config changes update this executables modified date" (again for the sync/backup aspect).

brzezmac2 days ago

Somehow i get this as I find myself either creating or using a generic e.g. "run.sh" which I then wrap into other scripts which call the generic one with the most common use cases / configurations.

abrookewood3 days ago

You could skip the underlying mechanism by renaming Claude.exe and then it just passes the name as a new chat.

blacklion3 days ago

exiftool uses this method (among others) for many years. I'm surprised nobody mentioned this.

JetSetIlly3 days ago

Yes, there are a few tools that do this. Looking at /bin and the softlinks that are there, the various xz tools do it (unxz, lzcat, etc.). Also, vim. vimdiff and view are just softlinks to vim.

The only difference is that those tools have chosen easy to remember names rather than embedding the arguments as metadata in the filename.

As a generalisation of the idea though, the blog post is neat.

blacklion3 days ago

exiftool can embed options to executable name, not only main mode of work like grep/egrep/zgrep — it is main difference. Like running `exiftoo(-k)` is equivalent `exiftool -k`.

JetSetIlly3 days ago

In that case I misunderstood.

It's an interesting idea. I think I prefer the exiftool syntax over what's suggested in the blog. Thanks for bringing it to my attention.

eternauta3k3 days ago

I love it because it's horrible, but in real life I'd just put the options inside the script (which is what you do anyway when you're too lazy to import argparse).

runlaszlorun3 days ago

I'll confess to only have skimmed TFA but I love this idea.

endymion-light3 days ago

this feels slightly insane and horrible but at the same time I can definitely see me using this for a phd project

r4ppz3 days ago

this is new to me tbh

Quarrelsome3 days ago

this is satire, right?

usefulcat3 days ago

It may be a bit uncommon, but it's not at all new. For example, on a Linux system I have, there are several files in /usr/bin that use hard links to refer to the same file (inode) by different names:

bunzip2 / bzcat / bzip2

gunzip / uncompress

unzip / zipinfo

pigz / unpigz

pkg-config / x86_64-pc-linux-gnu-pkg-config

perlbug / perlthanks

Use ls -li to show the inode number for each file or directory. For example:

    $ ls -li /usr/bin/{bzip2,bunzip2,bzcat}
    23069197 -rwxr-xr-x 3 root root 39144 Sep  5  2019 /usr/bin/bunzip2
    23069197 -rwxr-xr-x 3 root root 39144 Sep  5  2019 /usr/bin/bzcat
    23069197 -rwxr-xr-x 3 root root 39144 Sep  5  2019 /usr/bin/bzip2

tehbeard3 days ago

That's more a case of providing the distinct "APIs" ( bzip2 , gunzip etc) to userland / scripts, while the implementation for all is just one binary; than it being "Configuration via name..."

Somewhat similar to how busybox does its thing.

belkinpower3 days ago

This is already how busybox works. These examples are taking it to a more extreme level but it's not _that_ crazy.

zahlman3 days ago

AIUI, on Windows, pip (via the vendored `distlib`) also makes stub executables that work this way to implement the "entry points" defined in installed wheels. See: https://github.com/pypa/distlib/blob/master/PC/ReadMe.txt

Cthulhu_3 days ago

I'd say "kind of", because it's ridiculous on the surface but could be a handy trick. If only to be aware that an executable gets told its own name.

frizlab3 days ago

I have used that in a project of my own[0] for convenience (avoid duplicated code), but it is uncommon, yes.

I truly think it should be avoided in general, especially when what you actually want (in OP’s article) is a config file.

[0] https://github.com/Frizlab/frizlabs-conf/blob/44030f4123e683... (w/ that, also see the aliases in the folder of the script)

huflungdung3 days ago

[dead]

rajesh_me2910913 days ago

[dead]

RobertH505717583 days ago

[dead]

hn-front (c) 2024 voximity
source