diff options
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | tests | 7 | ||||
-rw-r--r-- | xe.1 | 8 | ||||
-rw-r--r-- | xe.c | 19 |
4 files changed, 23 insertions, 15 deletions
diff --git a/README.md b/README.md index 0c7d1ee..1f5c352 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,14 @@ Over apply: ## Usage: - xe [-0Rknv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND... + xe [-0FRnv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND... | -s SHELLSCRIPT | -a COMMAND... -- ARGS... | -A ARGSEP COMMAND... ARGSEP ARGS... * `-0`: input filenames are seperated by NUL bytes (default: newlines). +* `-F`: fatal: stop after first failing command. * `-R`: return with status 122 when no arguments have been passed. -* `-k`: keep going: don't stop when a command failed to execute. * `-n`: don't run the commands, just print them. * `-v`: print commands to standard error before running them. * `-I`: replace occurences of *arg* with the argument(s) (default: `{}`). diff --git a/tests b/tests index 51a47a4..b02b638 100755 --- a/tests +++ b/tests @@ -204,14 +204,15 @@ check_output 'exit code on empty input when run with -R' 'true | $XE -R echo a | 122 EOF -check_output 'stops on first error' 'necho a b c | $XE -s "if [ b = \$1 ]; then false; else echo \$1; fi" || echo $?' <<EOF +check_output 'doesn'\''t stop on errors by default' 'necho a b c | $XE -s "if [ b = \$1 ]; then false; else echo \$1; fi" || echo $?' <<EOF a +c 123 EOF -check_output 'doesn'\''t stop on errors with -k' 'necho a b c | $XE -k -s "if [ b = \$1 ]; then false; else echo \$1; fi"' <<EOF +check_output 'stops on first error with -F' 'necho a b c | $XE -F -s "if [ b = \$1 ]; then false; else echo \$1; fi" 2>/dev/null || echo $?' <<EOF a -c +123 EOF printf '# limit checks, expecting maximal POSIX limits available\n' diff --git a/xe.1 b/xe.1 index 8c232d6..81e3698 100644 --- a/xe.1 +++ b/xe.1 @@ -6,7 +6,7 @@ .Nd run command for each line or argument .Sh SYNOPSIS .Nm -.Op Fl 0Rknv +.Op Fl 0FRnv .Op Fl I Ar arg .Op Fl N Ar maxargs .Op Fl j Ar maxjobs @@ -69,11 +69,11 @@ The options are as follows: .It Fl 0 Input filenames are seperated by NUL bytes (instead of newlines, which is the default) +.It Fl F +Fatal: +stop and exit when a command execution failed. .It Fl R Return with status 122 when no arguments have been passed. -.It Fl k -Keep going: -Don't stop when a command failed to execute. .It Fl n Dry run: don't run the commands, just print them. .It Fl v diff --git a/xe.c b/xe.c index cab012e..77acdd7 100644 --- a/xe.c +++ b/xe.c @@ -28,7 +28,8 @@ static char *sflag; static int maxatonce = 1; static int maxjobs = 1; static int runjobs = 0; -static int Rflag, Aflag, aflag, kflag, nflag, vflag; +static int failed = 0; +static int Aflag, Fflag, Rflag, aflag, nflag, vflag; static long iterations = 0; static FILE *traceout; @@ -84,9 +85,13 @@ mywait() // no other error possible? } - if (WIFEXITED(status) && !kflag) { + if (WIFEXITED(status)) { if (WEXITSTATUS(status) >= 1 && WEXITSTATUS(status) <= 125) { - exit(123); + if (Fflag) { + fprintf(stderr, "xe: pid %d exited with status %d\n", pid, WEXITSTATUS(status)); + exit(123); + } + failed = 1; } else if (WEXITSTATUS(status) == 255) { fprintf(stderr, "xe: pid %d exited with status 255\n", pid); exit(124); @@ -275,22 +280,22 @@ main(int argc, char *argv[], char *envp[]) traceout = stdout; - while ((c = getopt(argc, argv, "+0A:I:N:Raj:kns:v")) != -1) + while ((c = getopt(argc, argv, "+0A:FI:N:Raj:ns:v")) != -1) switch(c) { case '0': delim = '\0'; break; case 'A': argsep = optarg; Aflag++; break; case 'I': replace = optarg; break; case 'N': maxatonce = atoi(optarg); break; + case 'F': Fflag++; break; case 'R': Rflag++; break; case 'a': aflag++; break; case 'j': maxjobs = parse_jobs(optarg); break; - case 'k': kflag++; break; case 'n': nflag++; break; case 's': sflag = optarg; break; case 'v': vflag++; traceout = stderr; break; default: fprintf(stderr, - "Usage: %s [-0Rknv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...\n" + "Usage: %s [-0FRnv] [-I arg] [-N maxargs] [-j maxjobs] COMMAND...\n" " | -s SHELLSCRIPT\n" " | -a COMMAND... -- ARGS...\n" " | -A ARGSEP COMMAND... ARGSEP ARGS...\n", @@ -376,5 +381,7 @@ main(int argc, char *argv[], char *envp[]) if (Rflag && iterations == 0) return 122; + if (failed) + return 123; return 0; } |