Return an error if input doesn't have exactly 1 line, otherwise pipe input to next step
Use read
. Here's a shell function that meets your specs:
exactly_one_line() { local line # Use to echo the line read -r line || return # Guarantee at least one line is read read && return 1 # Indicate failure if another line is successfully read echo "$line"}
Notes
- "One line" assumes a single line followed by a newline. If your input could be like, a file with contents but no newlines, then this will fail.
- Given a pipeline like
a|b
,a
cannot preventb
from running. At a minimum,b
needs to handle whena
produces no output.
Demo:
$ wc -l empty oneline twolines 0 empty 1 oneline 2 twolines 3 total$ exactly_one_line < empty; echo $?1$ exactly_one_line < oneline; echo $?oneline0$ exactly_one_line < twolines; echo $?1
First off, you should seriously consider adding the validation code to expects_one_line
. According to this post, each process starts in its own subshell, meaning that even if validate_one_line
fails, you will get an error in expects_one_line
because it will try to run with no input (or a blank line). That being said, here is a bash one-liner that you can insert into your pipe to validate:
should_create_one_line.sh | ( var="$(cat)"; [ $(echo "$var" | wc -l) -ne 1 ] && exit 1 || echo "$var") | expects_one_line.sh
The problem here is that when the validation subshell returns in the exit 1
case, expects_one_line.sh
will still get a single blank line. If this works for you, then great. If not, it would be better to just put the following into the beginning of expects_one_line.sh
:
input="$(cat)"[ $(echo "$var" | wc -l) -ne 1 ] && exit 1
This would guarantee that expects_one_line.sh
fails properly when getting a single line without having to wonder about what the empty line that the validation outputs will do to the script.
You may find this post helpful: How to read mutliline input from stdin into variable and how to print one out in shell(sh,bash)?
You can use a bash script to check the incoming data and call the other command when the input is only 1 line
The following code starts cat
when it is ONLY fet in 1 line
sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "$0" "$@"' cat
How this works
- Try reading a line, if failed go to step 5
- If variable $LINE is NOT empty, goto step 6
- Save line inside variable $LINE
- Goto step 1
- If $LINE is NOT empty, goto step 7
- Exit the program with status code 1
- Call our program and pass our $line to it using
printf
Example usage:
Printing out only if grep found 1 match:
grep .... | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "$0" "$@"' cat
Example of the question poster:
should_create_one_line | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "$0" "$@"' expects_one_line