Is there a way to catch a failure in piped commands? [duplicate] - bash

This question already has answers here:
How do you catch error codes in a shell pipe?
(5 answers)
Closed 9 years ago.
Here's an example of what I'm trying to achieve:
#!/bin/bash
set -e # abort if error
...
command1 2>&1 | command2
...
And I notice that sometimes command1 fails but command2 does not and the shell script happily continues...
if I did not have to use the pipe here, the set -e would have been sufficient but now it does not work with the pipe there...
Any thoughts?
Thanks

Since you are using bash, other than set -e you can also add set -o pipefail to get the results you want...

Related

echo and read with pipe issue [duplicate]

This question already has answers here:
Read values into a shell variable from a pipe
(17 answers)
Why variable values are lost after terminating the loop in bash? [duplicate]
(1 answer)
Closed 17 days ago.
First of all, I am sorry, I am learning the bash and I am a newbie.
Please find the below script.
grep "error" /var/log/syslog | while read line
do
echo $line
done
If I am not wrong,The above script will grep the keyword "error" in /var/log/syslog and will send it inside the while loop as STDIN and output will be displayed.
Also please loop the below script.
echo "hello" | read hi
echo $hi
So when I run this script I am not getting any output, why is that?
should I use any loop? only then I will get output?

evaluating expression with bash [duplicate]

This question already has answers here:
What's the point of eval/bash -c as opposed to just evaluating a variable?
(3 answers)
The 'eval' command in Bash and its typical uses
(11 answers)
Closed 2 years ago.
There is something i do not understand with strings in bash:
Look at this script:
#!/bin/bash
tmp="ls"
"$tmp"
This script executes ls command and display result in the console.
Now look at this script:
#!/bin/bash
tmp="ls > out.txt"
"$tmp"
This second script does not execute ls and displays this error:
line 3: ls > out.txt: command not found
I just want to understand. I do not want to understand how to run ls command. I want to understand why the first script works and not the second.
Thanks

Need help capturing the output of a command that is itself a variable in linux bash [duplicate]

This question already has answers here:
How to run script commands from variables?
(3 answers)
Execute command in a variable don't execute the latter part of a pipe
(1 answer)
Running a command that is stored in a variable (including pipes and redirects)
(3 answers)
Closed 5 years ago.
#!/bin/bash
# 1st part
ret=$(ps aux | grep -v grep) # thats OK
echo $ret
# 2nd part
cmd="ps aux | grep -v grep" # a problem with the pipe |
ret=$($cmd)
echo $ret
How can I use a command-string as I have in the 2nd part? Think the pipe is the problem. Tried to escape it but it did not help. Get some snytax error of ps.
Thanks!
You need eval:
ret=$(eval "$cmd")
Using eval is not recommended here. It can lead to unexpected results, especially when variables can be read from untrusted sources (See BashFAQ/048 - Eval command and security issues.
You can solve this in a simple way by defining and calling a function as below
ps_cmd() {
ps aux | grep -v grep
}
and use it in the script as
output="$(ps_cmd)"
echo "$output"
Also a good read would be to see why storing commands in a variable is not a good idea and has a lot of potential pitfalls - BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!

Bash: execute content of variable including pipe [duplicate]

This question already has answers here:
How to run script commands from variables?
(3 answers)
Execute command in a variable don't execute the latter part of a pipe
(1 answer)
Running a command that is stored in a variable (including pipes and redirects)
(3 answers)
Closed 5 years ago.
#!/bin/bash
# 1st part
ret=$(ps aux | grep -v grep) # thats OK
echo $ret
# 2nd part
cmd="ps aux | grep -v grep" # a problem with the pipe |
ret=$($cmd)
echo $ret
How can I use a command-string as I have in the 2nd part? Think the pipe is the problem. Tried to escape it but it did not help. Get some snytax error of ps.
Thanks!
You need eval:
ret=$(eval "$cmd")
Using eval is not recommended here. It can lead to unexpected results, especially when variables can be read from untrusted sources (See BashFAQ/048 - Eval command and security issues.
You can solve this in a simple way by defining and calling a function as below
ps_cmd() {
ps aux | grep -v grep
}
and use it in the script as
output="$(ps_cmd)"
echo "$output"
Also a good read would be to see why storing commands in a variable is not a good idea and has a lot of potential pitfalls - BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!

bash script and command definition [duplicate]

This question already has answers here:
Reading quoted/escaped arguments correctly from a string
(4 answers)
Closed 3 years ago.
Got a little bash script like so:
#!/bin/bash
TIME_CMD='/usr/bin/time -f "%E execution time"'
${TIME_CMD} ls
Only problem: doesn't work:
/usr/bin/time: cannot run execution: No such file or directory
Command exited with non-zero status 127
"0:00.00
What am I doing wrong?
Try making it...
#!/bin/bash
TIME_CMD='/usr/bin/time -f "%E execution time"'
eval "$TIME_CMD ls"
This will utilize bash to re-parse the command string after it has been constructed, so that the quoted argument will be recognized properly.
Storing commands in variables is generally a bad idea (see BashFAQ #050 for details). The reason it's not working as you expect is that quoting inside variable values is ignored (unless you run it through something like eval, which then tends to lead to other parsing oddities).
In your case, I see three fairly straightforward ways to do it. First, you can use an alias instead of a variable:
alias TIME_CMD='/usr/bin/time -f "%E execution time"'
TIME_CMD ls
Second, you can use a function:
TIME_CMD() { /usr/bin/time -f "%E execution time" "$#"; }
TIME_CMD ls
Third, you can use an array rather than a simple variable:
TIME_CMD=(/usr/bin/time -f "%E execution time")
"${TIME_CMD[#]}" ls
Note that with an array, you need to expand it with the "${array[#]}" idiom to preserve word breaks properly.

Resources