Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: pass watched files as command line arg/flag (NOT via pipe) #33

Closed
maiamcc opened this issue Apr 20, 2020 · 10 comments
Closed

Comments

@maiamcc
Copy link

maiamcc commented Apr 20, 2020

(Unless of course this feature already exists, in which case, great!)

I'd like to be able to use entr on Docker images without bash/sh, which means that piping won't be available to me; ideally I would be able to specify files to watch as an arg, e.g.

["entr", "--files=a.txt,b.txt,c.txt", "-rz", "my_util.sh"]

(A smaller point in favor of this feature is that while piping makes perfect sense for a call like ls | entr ..., if i just want to watch a single file, it looks a little silly to say echo one-file.txt | entr ...)

@maiamcc maiamcc changed the title Feature request: pass watched files via flag (NOT via pipe) Feature request: pass watched files as command line arg/flag (NOT via pipe) Apr 20, 2020
@eradman
Copy link
Owner

eradman commented Apr 22, 2020

I probably will not add this feature, but similar requests have come up before, and this has some merit. My approach has been to design a tool that did one thing and do it well. Reading the list of files on STDIN came with some limitations I did not anticipate:

  1. The assumption was that standard tools like ls(1) or find(1) should be used to generate a list of filenames. In reality, common unix tools are difficult to use in many cases. See
    How to exclude/ignore hidden files and directories in a wildcard-embedded “find” search?

  2. The scripting philosophy I have often had to recommend involves a while loop. When you specify -d entr exits so that external tools can rescan a directory tree.

  3. While you can of course construct pipes with other scripting languages, in practice you will nearly always run entr in a shell.

Should I finally let go of this approach? Some alternate approaches might be

# specify a list of files
entr -f a.txt,b.txt,c.txt

# provide a file list as an optional input
entr -f filelist.txt

# provide built-in glob search
entr -f '*.txt'

# provide built-in regex search
entr -f '.txt$'

# allow an external tool to be used to find files
entr -f 'ag -l -G .txt$'

The problem will all these examples is that they only solve a small set of problems, they introduce yet more to read in the man page. Instead I have been steering people to use non-standard file search tools such as

ack -f ... 
fnd ...
ag -l

Back to your feature request: nearly always you can just run a shell

sh -c 'ls *.txt | entr -n ...'

And for just one file, there is special syntax (/_) to make it quick to type:

echo my.sql | entr psql -f /_

I know this was a simple request, but

  • I want to stick with the UNIX philosophy, e.g. xargs(1)
  • I want to keep the number of options and length of the man page as short as possible
  • There are a bunch of usability problems that I want to solve

That last point is the one that bothers me the most. I almost expect someone fork entr and redesign parts of it around this idea, but this hasn't happened yet to my knowledge.

@matti
Copy link
Contributor

matti commented Apr 26, 2020

https://github.com/jakolehm/nightwatch implements this now:

nightwatch --find-cmd="find ." ping google.com

since there is no pipeline (there can be, it also supports STDIN), it's also easier to terminate in a shell script.

@maiamcc
Copy link
Author

maiamcc commented Apr 28, 2020

Thanks for your thorough explanation @eradman. This all makes sense, and I've found a workaround for my use case.

Back to your feature request: nearly always you can just run a shell

Unfortunately this is one case we can't :-/ I've found a workaround though. Here's my use case/solution in case you're curious, but it's nothing you need to worry about if not!

Basically I want to run entr as the command of a Kubernetes pod, and have it be compatible with the pod args as well (see docs). In practice that looks like this:

apiVersion: v1
kind: Pod
...
spec:
  containers:
  ...
  command: ["sh", "-c", "echo restart-process.txt | entr -rz my_util.sh"]
  args: ["arg1", "arg2", "--someFlag"]

In the pod itself, that results in a call:

["sh", "-c", "echo a.txt | entr -rz my_util.sh", "arg1", "arg2", "--someFlag"]

The way this gets evaluated, the args/flags specified apply to sh, not to my_util.sh!

The solution was a precompiled binary that takes a file(s) as an arg and calls out to entr that can be invoked as:

command: ["restart-wrapper"]
args: ["--restartFile=restart-process.txt", "arg1", "arg2", "--someFlag"]

Here's the wrapper I wrote, if you're curious.

Again, this is all nerdy context on my issue but nothing you need to take action on--I'm all set for now :)

@eradman
Copy link
Owner

eradman commented Apr 28, 2020

@maiamcc that is some very good context.

I'm going to leave this ticket open for now in case anyone else wants to chime in with ideas

@bfrg
Copy link

bfrg commented Jun 28, 2020

What about reading the watched files from an external file (one per line) as an alternative to STDIN? Something like entr -f FILE or entr --file=FILE.

@iamleot
Copy link
Contributor

iamleot commented Jun 29, 2020 via email

@iamleot
Copy link
Contributor

iamleot commented Jun 29, 2020

@bfrg Nevermind, I was completely out of context because I've read that via email and missed previous discussions.

@bfrg
Copy link

bfrg commented Jun 29, 2020

@iamleot I personally don't need this feature at the moment but I thought I mention it as an alternative since it hasn't been brought up yet. Parsing a file is probably easier than parsing command-line arguments. Besides, the file can be arbitrarily large whereas command-line arguments are limited by (I think) ARG_MAX in the Linux Kernel. See:
https://wiki.debian.org/CommonErrorMessages/ArgumentListTooLong

@xordspar0
Copy link

Parsing a file is probably easier than parsing command-line arguments.

Parsing a file is also trivially easy for a program that already parses stdin, which is just another file from the perspective of a C program. Still, I resonate with @eradman's hesitation to add this. Even though it does make certain use cases easier, it's not as flexible and useful as a pipe.

I mention it as an alternative since it hasn't been brought up yet.

It was mentioned1:

# provide a file list as an optional input
entr -f filelist.txt

@eradman
Copy link
Owner

eradman commented Jul 2, 2020

Thanks for the feedback all! The pipe is a problem in some corner cases, but it also provides flexibility for most cases. Closing

@eradman eradman closed this as completed Jul 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants