miserlou / loop Goto Github PK
View Code? Open in Web Editor NEWUNIX's missing `loop` command
Home Page: https://github.com/Miserlou/Loop
License: MIT License
UNIX's missing `loop` command
Home Page: https://github.com/Miserlou/Loop
License: MIT License
Are they equivalent or is there a typo?
Hello @Miserlou
I used loop
some times for running tests etc and it's very very useful. A missing feature for me has always been that the output is not printed immediately and just after the program exits. Furthermore the stdout
and stderr
is merged which is sometimes bad.
I tried to fix those things but ended up with a more or less rewrite of loop
based on tokio for the io and child process handling. The CLI interface is almost the same. I pushed it and I'm using it since a couple of days. I probably needs some more polishing but in general works.
Let me know if you're interested in this branch.
Thanks for the missing loop command
;-)
Attempting to install via cargo install loop-rs
gives the following compilation errors:
error[E0631]: type mismatch in function arguments
--> /Users/wmcgann/.cargo/registry/src/github.com-1ecc6299db9ec823/loop-rs-0.6.1/src/main.rs:216:10
|
216 | #[derive(StructOpt, Debug)]
| ^^^^^^^^^ expected signature of `fn(&str) -> _`
...
322 | fn get_values(input: &&str) -> Vec<String> {
| ------------------------------------------ found signature of `for<'r, 's> fn(&'r &'s str) -> _`
error[E0631]: type mismatch in function arguments
--> /Users/wmcgann/.cargo/registry/src/github.com-1ecc6299db9ec823/loop-rs-0.6.1/src/main.rs:216:10
|
216 | #[derive(StructOpt, Debug)]
| ^^^^^^^^^ expected signature of `fn(&str) -> _`
...
314 | fn get_error_code(input: &&str) -> ErrorCode {
| -------------------------------------------- found signature of `for<'r, 's> fn(&'r &'s str) -> _`
error: aborting due to 2 previous errors
$ cargo version && rustc --version
cargo 1.35.0 (6f3e9c367 2019-04-04)
rustc 1.35.0 (3c235d560 2019-05-20)
Cloning and buliding/installing the master branch works without issue.
Maybe something like..
$ loop 'echo $VALUE > $KEY' --for-dict "{'hello', 'world'}"
$ cat hello
world
I want loop
to be in Debian and Ubuntu! Let's make that happen!
Required first:
This would be useful.
I want to build a package for alpine linux therefor I need a release...
$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home: /home/foobar/.rustup
stable-x86_64-unknown-linux-gnu (default)
rustc 1.63.0 (4b91a6ea7 2022-08-08)
$ cargo test
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 11 tests
test item ... ok
test no_of_iterations ... ok
test only_last ... ok
test summary ... FAILED
test until_changes ... ok
test until_error ... FAILED
test until_contains ... ok
test until_fail ... FAILED
test until_success ... FAILED
test until_same ... FAILED
test counter ... ok
failures:
---- summary stdout ----
thread 'summary' panicked at 'Unexpected stdout, failed diff original var
├── original: Total runs: 3
│ Successes: 2
│ Failures: 1 (-1)
├── diff:
│ --- orig
│ +++ var
│ @@ -3 +3 @@
│ -Failures: 1 (-1)
│ +Failures: 1 (1)
└── var as str: Total runs: 3
Successes: 2
Failures: 1 (1)
command=`"/home/foobar/src/contrib/Loop/target/debug/loop" "--for=true,false,true" "--summary" "--" "$ITEM"`
code=0
stdout=```"Total runs:\t3\nSuccesses:\t2\nFailures:\t1 (1)\n"```
stderr=```""```
', /home/foobar/.cargo/registry/src/github.com-1ecc6299db9ec823/assert_cmd-1.0.8/src/assert.rs:124:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- until_error stdout ----
thread 'until_error' panicked at 'Unexpected failure.
code-1
stderr=```"error: The argument \'--until-error <until_error>\' requires a value but none was supplied\n\nUSAGE:\n loop --count-by <count_by> --every <every> --for <ffor> --offset <offset> --summary --until-error <until_error>\n\nFor more information try --help\n"```
command=`"/home/foobar/src/contrib/Loop/target/debug/loop" "--for=true,true,false,true,true,true" "--until-error" "--summary" "--" "$ITEM"`
code=1
stdout=```""```
stderr=```"error: The argument \'--until-error <until_error>\' requires a value but none was supplied\n\nUSAGE:\n loop --count-by <count_by> --every <every> --for <ffor> --offset <offset> --summary --until-error <until_error>\n\nFor more information try --help\n"```
', /home/foobar/.cargo/registry/src/github.com-1ecc6299db9ec823/assert_cmd-1.0.8/src/assert.rs:124:9
---- until_fail stdout ----
thread 'until_fail' panicked at 'Unexpected stdout, failed diff original var
├── original: Total runs: 3
│ Successes: 2
│ Failures: 1 (-1)
├── diff:
│ --- orig
│ +++ var
│ @@ -3 +3 @@
│ -Failures: 1 (-1)
│ +Failures: 1 (1)
└── var as str: Total runs: 3
Successes: 2
Failures: 1 (1)
command=`"/home/foobar/src/contrib/Loop/target/debug/loop" "--for=true,true,false,true,true,true" "--until-fail" "--summary" "--" "$ITEM"`
code=0
stdout=```"Total runs:\t3\nSuccesses:\t2\nFailures:\t1 (1)\n"```
stderr=```""```
', /home/foobar/.cargo/registry/src/github.com-1ecc6299db9ec823/assert_cmd-1.0.8/src/assert.rs:124:9
---- until_success stdout ----
thread 'until_success' panicked at 'Unexpected stdout, failed diff original var
├── original: Total runs: 4
│ Successes: 1
│ Failures: 3 (-1, -1, -1)
├── diff:
│ --- orig
│ +++ var
│ @@ -3 +3 @@
│ -Failures: 3 (-1, -1, -1)
│ +Failures: 3 (1, 1, 1)
└── var as str: Total runs: 4
Successes: 1
Failures: 3 (1, 1, 1)
command=`"/home/foobar/src/contrib/Loop/target/debug/loop" "--for=false,false,false,true,false,false" "--until-success" "--summary" "--" "$ITEM"`
code=0
stdout=```"Total runs:\t4\nSuccesses:\t1\nFailures:\t3 (1, 1, 1)\n"```
stderr=```""```
', /home/foobar/.cargo/registry/src/github.com-1ecc6299db9ec823/assert_cmd-1.0.8/src/assert.rs:124:9
---- until_same stdout ----
thread 'until_same' panicked at 'Unexpected stdout, failed diff original var
├── original: 5
├── diff:
│ --- orig
│ +++ var
│ @@ -1 +1 @@
│ -5
│ +7
└── var as str: 7
command=`"/home/foobar/src/contrib/Loop/target/debug/loop" "--for=1,2,3,4,5,5,6,7" "--until-same" "--only-last" "--" "echo $ITEM"`
code=0
stdout=```"7\n"```
stderr=```""```
', /home/foobar/.cargo/registry/src/github.com-1ecc6299db9ec823/assert_cmd-1.0.8/src/assert.rs:124:9
failures:
summary
until_error
until_fail
until_same
until_success
test result: FAILED. 6 passed; 5 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
Hey
I have observed that you have put the entire code inside main()
. It is better to split them in different methods which allows the code to be more readable.
When loop is piped to some program that only takes a subset of loop's output the program prints throws a panic message that may confuse people when used as part of a long command chain.
Example:
user@pc $ loop 'echo $COUNT' | head -n 2
0
1
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', libstd/io/stdio.rs:692:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
The expected behaviour is that loop exits gracefully upon detecting the pipe is closed.
I get the following error when I try to do cargo install loop-rs
on Windows 7:
Compiling loop-rs v0.3.3
error[E0432]: unresolved import `isatty::stdin_isatty`
--> src\main.rs:16:14
|
16 | use isatty::{stdin_isatty};
| ^^^^^^^^^^^^ no `stdin_isatty` in the root. Did you mean to use `stderr_isatty`?
Here is my rustup show
output:
Default host: x86_64-pc-windows-msvc
installed toolchains
--------------------
stable-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc
active toolchain
----------------
stable-x86_64-pc-windows-msvc (default)
rustc 1.27.0 (3eda71b00 2018-06-19)
via this comment:
Lovely idea. I have a small amount of "issue" with the way you're doing the command line though. It's more typical to see commandlines of the form:
loop --every 15s --until-success --num 5 ./do_thing.sh
i.e. where you give the command "last" and where if you want to give that command arguments, you use -- to separate:
loop --until-success -- ping -c5 myserver
As a long-time CLI user, having to put the command, and its arguments, first just feels wrong.
Well done on your project though, and +1 for using clap :-)
Curious what you think of this feature request. With the --until-*
options, sometimes I only care about the output of the last command. It would be nice if there was a flag that enabled this behaviour. I'd imagine it would work by redirecting standard error and standard output to files and then printing the files after the last command runs.
We use loop 'ls'
formatting in some places and loop -- ls
other places. We should normalize this to one or the other, now I'm leaning towards the latter.
This a tricky but important one.
Current behavior is this:
$ loop "date; sleep 5; " --every 2s
Fri Jun 15 16:08:58 EDT 2018
Fri Jun 15 16:09:03 EDT 2018
Fri Jun 15 16:09:08 EDT 2018
I want a way to:
$ loop "date; sleep 5; " --every 2s --detach
Fri Jun 15 16:08:58 EDT 2018
Fri Jun 15 16:09:00 EDT 2018
Fri Jun 15 16:09:02 EDT 2018
If this is incompatible with --until-*
that's okay, although obviously that'd be preferred.
n/t
It would be nice if loop-rs
could run the loop body in parallel (using num-cpu).
Suggestion for the flag name: --parallel
-p
.
Ex:
loop 'touch $ITEM.txt' --for red,blue,green
I'm new to Rust. I feel like I'm using mut
in places I shouldn't. I need Rust pro to help me with code review.
This is a really basic one that used to work that appears not to work for me anymore?
Ran $ cargo build
and rustc (ver 1.24.1) output the following:
Compiling loop-rs v0.4.0 (file:///home/um-li/Downloads/Loop)
error: non-reference pattern used to match a reference (see issue #42640)
--> src/main.rs:99:20
|
99 | if let Some(string) = &opt.until_contains {
| ^^^^^^^^^^^^ help: consider using a reference: `&Some(string)`
error: non-reference pattern used to match a reference (see issue #42640)
--> src/main.rs:106:20
|
106 | if let Some(regex) = &opt.until_match {
| ^^^^^^^^^^^ help: consider using a reference: `&Some(regex)`
error: non-reference pattern used to match a reference (see issue #42640)
--> src/main.rs:114:16
|
114 | if let Some(error_code) = &opt.until_error {
| ^^^^^^^^^^^^^^^^ help: consider using a reference: `&Some(error_code)`
error: non-reference pattern used to match a reference (see issue #42640)
--> src/main.rs:116:17
|
116 | ErrorCode::Any => if !result.exit_status.success() {
| ^^^^^^^^^^^^^^ help: consider using a reference: `&ErrorCode::Any`
error: non-reference pattern used to match a reference (see issue #42640)
--> src/main.rs:119:17
|
119 | ErrorCode::Code(code) => {
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&ErrorCode::Code(code)`
error: aborting due to 5 previous errors
error: Could not compile `loop-rs`.
When using the --until-time
flag the timestamps you use are implicitly in UTC. It would be nice to this default to the computer's local time, or have a flag to specify the timezone.
Goddammit
ls | loop -- "cat $ITEM"
That used to work and now it doesn't, motherfuck.
find
and xargs
allow to pass to them commands in such ways:
find . -exec ls -l ';'
xargs echo 3 4 5
This is arguably better than find . -exec "ls -l"
because this way you don't have to think as much about the nested strings that can already be a pain when using the shell.
So it would greatly simplify life in some complex cases if loop
supported syntax like loop [options here] -- command arg1 arg
.
I think this tool is useful, but I've let it rot. Need a maintainer to triage and get a version release ready.
I think stdin will be easy but stdout will be hard.
I use looper to smoke out flaky tests.
As such, I run loop 'npm run test:acceptance' --num 5
and I look what the output is.
It would be awesome if at the end I could get a summary of success (0
exit code) vs unsuccessful (non-zero exit code) completions.
$ loop 'npm run test:acceptance' --num 5 --summary
...
Total: 5
Success: 4
Fail: 1
And then I'll know to take a closer look.
This would probably also work nicely with the other --until-*
With a bit of guidance I could give this a try 😄
This command gives weird behavior:
cargo run "echo $ITEM" --for "`cat README.md`"
It'd be great to have a better example for this use case, either a) fixing this behavior, b) explicitly adding the ability to read in a file from stdin c) adding explicit reading of a file or d) all of the above.
error[E0631]: type mismatch in function arguments
--> /Users/marcin/.cargo/registry/src/github.com-1ecc6299db9ec823/loop-rs-0.6.1/src/main.rs:238:48
|
238 | #[structopt(long = "for", parse(from_str = "get_values"))]
| ^^^^^^^^^^^^ expected signature of `fn(&str) -> _`
...
322 | fn get_values(input: &&str) -> Vec<String> {
| ------------------------------------------ found signature of `for<'r, 's> fn(&'r &'s str) -> _`
error[E0631]: type mismatch in function arguments
--> /Users/marcin/.cargo/registry/src/github.com-1ecc6299db9ec823/loop-rs-0.6.1/src/main.rs:266:69
|
266 | #[structopt(short = "r", long = "until-error", parse(from_str = "get_error_code"))]
| ^^^^^^^^^^^^^^^^ expected signature of `fn(&str) -> _`
...
314 | fn get_error_code(input: &&str) -> ErrorCode {
| -------------------------------------------- found signature of `for<'r, 's> fn(&'r &'s str) -> _`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0631`.
error: failed to compile `loop-rs v0.6.1`, intermediate artifacts can be found at `/var/folders/gw/053czpm957z2rq6k8xqvnxx00000gn/T/cargo-installBihqf5`
Caused by:
could not compile `loop-rs`
My rust version:
$ rustup show
Default host: x86_64-apple-darwin
rustup home: /Users/marcin/.rustup
installed toolchains
--------------------
stable-x86_64-apple-darwin (default)
nightly-x86_64-apple-darwin
active toolchain
----------------
stable-x86_64-apple-darwin (default)
rustc 1.54.0 (a178d0322 2021-07-26)
Error codes of executed commands are reported in summary with minus sign as shown bellow:
loop --for=0,1,2,3,4,5 --until-error 5 --summary -- exit '$ITEM'
returns
Total runs: 6 Successes: 1 Failures: 5 (-1, -2, -3, -4, -5)
I would expect to return
Total runs: 6 Successes: 1 Failures: 5 (1, 2, 3, 4, 5)
The README makes it seem that --until-error
does not require an argument:
Or until it fails with --until-error (which also accepts an optional error code):
But when I try it without an argument, I get this:
error: The argument '--until-error <until_error>' requires a value but none was supplied
USAGE:
loop <input> --count-by <count_by> --every <every> --offset <offset> --until-error <until_error>
So I think that maybe --until-fail
is what I want, based on this:
Or, if you have a list of files but need to find the one which causes your program to fail:
$ ls | loop './my_program $ITEM' --until-fail;
But I get this:
error: Found argument '--until-fail' which wasn't expected, or isn't valid in this context
And I still don't know how to run a command until it fails. Seems like it is currently impossible.
A number of options I want here:
--until-contains
: loops until output contains a string--until-match
: loops until output matches a pattern--until-error
: loops until there is a non-success error code--until-success
: loops until there is a success error code$ loop 'echo $COUNT' --count-by 1.1
0
1.1
2.2
3.3000000000000003
4.4
5.5
6.6
7.699999999999999
8.799999999999999
9.899999999999999
grrr
We have a bunch of images that need to be pushed to a registry so often, so we do them all in one big script. Problem is Gitlab's container registry constantly fails all the time so loop
is a perfect fit for this.
Trying something like:
loop -s --summary -- scripts/push-images.sh
(tried with -i
as well)
But the problem is that there is zero output.
Whereas normally our scripts/push-images.sh
outputs something like:
Pushing registry.gitlab.com/thing:prod
The push refers to repository [registry.gitlab.com/thing]
8850e5e866c3: Preparing
6d1eb370deee: Preparing
e6a9e93f2e3d: Preparing
f721b22510f1: Preparing
371e12a4bca7: Preparing
c97278a08a46: Preparing
7bff100f35cb: Preparing
c97278a08a46: Waiting
And updates as the scripts progress through each image.
Is there anyway to keep that stdout and print it to term live as loop
receives it from the subprocess?
Readme includes this:
$ loop 'echo $COUNT' --count-by 2 --offset 10
10
12
14
[ .. ]
When I run it on Mac OS X 10.12.6 with loop 0.3.3 installed per brew instructions I get...
$ loop 'echo $COUNT' --count-by 2 --offset 10
0
1
2
3
4
5
6
7
8
9
10
11
[..]
offset and count-by are not working as expected.
~/Projects/Loop/looper $ loop 'date' --for-duration 8s --every 2s
Mon Feb 4 16:12:33 EST 2019
Mon Feb 4 16:12:35 EST 2019
Mon Feb 4 16:12:37 EST 2019
Mon Feb 4 16:12:39 EST 2019
Mon Feb 4 16:12:41 EST 2019
~/Projects/Loop/looper $ loop 'date -u' --until-time '2018-05-25 20:50:00' --every 5s
Mon Feb 4 21:13:01 UTC 2019
Again, I think this was caused by blindly accepting that "refactor" to make the code "better"
The official recommendation is that this should be committed into the repository. Since it's a binary, compatibility with other versions of libraries isn't important and having the lock file around can potentially help avoid annoying breakages in the future.
A feature request that would be immensely useful to me since I often find myself waiting for something to change.
Let's say I want to be notified when my packages are finally synced to maven. Then I could do
loop --until-changes 'curl https://repo1.maven.org/maven2/com/github/dkhalansky/paradisenglib_2.12.3/'
This invocation would then first run the specified curl
command, remembering some hash of the output, and then run the command periodically until the hash of the output changes. After that, the execution would end.
Or I could wait for anyone to log into my system or log out of it. Then I could do loop --until-changes 'w -hs'
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.