How to redirect mdfind output to if else statament in bash

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I am trying to create a script that look for some files, listed in an input file, all over the computer and then copy those files in a specific folder.
So far all ok with a for loop and mdfind "command" | xargs.
But the if i add an if statement to create an output file with the list of the files that mdfind didn't find, here comes the problems.
Here is my actual code:



if [ $# -eq 0 ]
then
echo "Please introduce the name of the input file after runnig the command.
For this script you need an INPUT.txt file containing only the list of the
samples you want to copy."
else
for i in $(cat $1);
do mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp ''
/Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;
if [ $? -eq 0 ]
then
echo $i >> extractions_not_found.txt
else
echo $i >> extractions_found.txt
fi
done
fi


I am using $? to redirect the output of



 mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp '' /Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;


but it is alway = 0, even when it cant find the one file listed in the input file.



Anyone can help me understand where is the error??



Thank you!







share|improve this question




















  • This is because $? is getting the exit code of xargs, not of cp or mdfind.
    – DopeGhoti
    Jan 23 at 18:25














up vote
0
down vote

favorite












I am trying to create a script that look for some files, listed in an input file, all over the computer and then copy those files in a specific folder.
So far all ok with a for loop and mdfind "command" | xargs.
But the if i add an if statement to create an output file with the list of the files that mdfind didn't find, here comes the problems.
Here is my actual code:



if [ $# -eq 0 ]
then
echo "Please introduce the name of the input file after runnig the command.
For this script you need an INPUT.txt file containing only the list of the
samples you want to copy."
else
for i in $(cat $1);
do mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp ''
/Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;
if [ $? -eq 0 ]
then
echo $i >> extractions_not_found.txt
else
echo $i >> extractions_found.txt
fi
done
fi


I am using $? to redirect the output of



 mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp '' /Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;


but it is alway = 0, even when it cant find the one file listed in the input file.



Anyone can help me understand where is the error??



Thank you!







share|improve this question




















  • This is because $? is getting the exit code of xargs, not of cp or mdfind.
    – DopeGhoti
    Jan 23 at 18:25












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am trying to create a script that look for some files, listed in an input file, all over the computer and then copy those files in a specific folder.
So far all ok with a for loop and mdfind "command" | xargs.
But the if i add an if statement to create an output file with the list of the files that mdfind didn't find, here comes the problems.
Here is my actual code:



if [ $# -eq 0 ]
then
echo "Please introduce the name of the input file after runnig the command.
For this script you need an INPUT.txt file containing only the list of the
samples you want to copy."
else
for i in $(cat $1);
do mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp ''
/Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;
if [ $? -eq 0 ]
then
echo $i >> extractions_not_found.txt
else
echo $i >> extractions_found.txt
fi
done
fi


I am using $? to redirect the output of



 mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp '' /Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;


but it is alway = 0, even when it cant find the one file listed in the input file.



Anyone can help me understand where is the error??



Thank you!







share|improve this question












I am trying to create a script that look for some files, listed in an input file, all over the computer and then copy those files in a specific folder.
So far all ok with a for loop and mdfind "command" | xargs.
But the if i add an if statement to create an output file with the list of the files that mdfind didn't find, here comes the problems.
Here is my actual code:



if [ $# -eq 0 ]
then
echo "Please introduce the name of the input file after runnig the command.
For this script you need an INPUT.txt file containing only the list of the
samples you want to copy."
else
for i in $(cat $1);
do mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp ''
/Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;
if [ $? -eq 0 ]
then
echo $i >> extractions_not_found.txt
else
echo $i >> extractions_found.txt
fi
done
fi


I am using $? to redirect the output of



 mdfind "kMDItemDisplayName == $i*.ab1" | xargs -I '' cp '' /Users/xxxxx/xxxxx/xxxxx/xxxxxxx/test_moving/;


but it is alway = 0, even when it cant find the one file listed in the input file.



Anyone can help me understand where is the error??



Thank you!









share|improve this question











share|improve this question




share|improve this question










asked Jan 23 at 18:00









WalterC85

1




1











  • This is because $? is getting the exit code of xargs, not of cp or mdfind.
    – DopeGhoti
    Jan 23 at 18:25
















  • This is because $? is getting the exit code of xargs, not of cp or mdfind.
    – DopeGhoti
    Jan 23 at 18:25















This is because $? is getting the exit code of xargs, not of cp or mdfind.
– DopeGhoti
Jan 23 at 18:25




This is because $? is getting the exit code of xargs, not of cp or mdfind.
– DopeGhoti
Jan 23 at 18:25










1 Answer
1






active

oldest

votes

















up vote
1
down vote













After you run mdfind ... | xargs cp ..., the error code in $? is that of xargs, since it's the last command in the pipeline. xargs returns 123 if any command it executed failed, but if mdfind doesn't produce any output, then xargs doesn't do anything, so it also doesn't fail.



However, in Bash, you can find the exit codes of all commands in the last pipeline in the array variable PIPESTATUS. The exit code of the first command is $PIPESTATUS[0] etc.



$ false | true | xargs false
$ echo "$PIPESTATUS[*]"
1 0 123


So, instead of using $?, which gives you the exit status of xargs, you could use $PIPESTATUS[0] giving you the exit status of mdfind. Or save the lot to another variable and test both. (saved=("$PIPESTATUS[@]"))



Alternatively, use set -o pipefail so that $? gives you the exit code of last failing command of the pipeline, if any of them fail. (false | true would result in $?=1.)






share|improve this answer






















  • You can also set -o pipefail and set -e.
    – DopeGhoti
    Jan 23 at 20:47










  • @DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
    – ilkkachu
    Jan 23 at 20:51










  • so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
    – WalterC85
    Jan 23 at 22:15











Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f419151%2fhow-to-redirect-mdfind-output-to-if-else-statament-in-bash%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













After you run mdfind ... | xargs cp ..., the error code in $? is that of xargs, since it's the last command in the pipeline. xargs returns 123 if any command it executed failed, but if mdfind doesn't produce any output, then xargs doesn't do anything, so it also doesn't fail.



However, in Bash, you can find the exit codes of all commands in the last pipeline in the array variable PIPESTATUS. The exit code of the first command is $PIPESTATUS[0] etc.



$ false | true | xargs false
$ echo "$PIPESTATUS[*]"
1 0 123


So, instead of using $?, which gives you the exit status of xargs, you could use $PIPESTATUS[0] giving you the exit status of mdfind. Or save the lot to another variable and test both. (saved=("$PIPESTATUS[@]"))



Alternatively, use set -o pipefail so that $? gives you the exit code of last failing command of the pipeline, if any of them fail. (false | true would result in $?=1.)






share|improve this answer






















  • You can also set -o pipefail and set -e.
    – DopeGhoti
    Jan 23 at 20:47










  • @DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
    – ilkkachu
    Jan 23 at 20:51










  • so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
    – WalterC85
    Jan 23 at 22:15















up vote
1
down vote













After you run mdfind ... | xargs cp ..., the error code in $? is that of xargs, since it's the last command in the pipeline. xargs returns 123 if any command it executed failed, but if mdfind doesn't produce any output, then xargs doesn't do anything, so it also doesn't fail.



However, in Bash, you can find the exit codes of all commands in the last pipeline in the array variable PIPESTATUS. The exit code of the first command is $PIPESTATUS[0] etc.



$ false | true | xargs false
$ echo "$PIPESTATUS[*]"
1 0 123


So, instead of using $?, which gives you the exit status of xargs, you could use $PIPESTATUS[0] giving you the exit status of mdfind. Or save the lot to another variable and test both. (saved=("$PIPESTATUS[@]"))



Alternatively, use set -o pipefail so that $? gives you the exit code of last failing command of the pipeline, if any of them fail. (false | true would result in $?=1.)






share|improve this answer






















  • You can also set -o pipefail and set -e.
    – DopeGhoti
    Jan 23 at 20:47










  • @DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
    – ilkkachu
    Jan 23 at 20:51










  • so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
    – WalterC85
    Jan 23 at 22:15













up vote
1
down vote










up vote
1
down vote









After you run mdfind ... | xargs cp ..., the error code in $? is that of xargs, since it's the last command in the pipeline. xargs returns 123 if any command it executed failed, but if mdfind doesn't produce any output, then xargs doesn't do anything, so it also doesn't fail.



However, in Bash, you can find the exit codes of all commands in the last pipeline in the array variable PIPESTATUS. The exit code of the first command is $PIPESTATUS[0] etc.



$ false | true | xargs false
$ echo "$PIPESTATUS[*]"
1 0 123


So, instead of using $?, which gives you the exit status of xargs, you could use $PIPESTATUS[0] giving you the exit status of mdfind. Or save the lot to another variable and test both. (saved=("$PIPESTATUS[@]"))



Alternatively, use set -o pipefail so that $? gives you the exit code of last failing command of the pipeline, if any of them fail. (false | true would result in $?=1.)






share|improve this answer














After you run mdfind ... | xargs cp ..., the error code in $? is that of xargs, since it's the last command in the pipeline. xargs returns 123 if any command it executed failed, but if mdfind doesn't produce any output, then xargs doesn't do anything, so it also doesn't fail.



However, in Bash, you can find the exit codes of all commands in the last pipeline in the array variable PIPESTATUS. The exit code of the first command is $PIPESTATUS[0] etc.



$ false | true | xargs false
$ echo "$PIPESTATUS[*]"
1 0 123


So, instead of using $?, which gives you the exit status of xargs, you could use $PIPESTATUS[0] giving you the exit status of mdfind. Or save the lot to another variable and test both. (saved=("$PIPESTATUS[@]"))



Alternatively, use set -o pipefail so that $? gives you the exit code of last failing command of the pipeline, if any of them fail. (false | true would result in $?=1.)







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 23 at 20:49

























answered Jan 23 at 20:41









ilkkachu

49.8k674137




49.8k674137











  • You can also set -o pipefail and set -e.
    – DopeGhoti
    Jan 23 at 20:47










  • @DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
    – ilkkachu
    Jan 23 at 20:51










  • so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
    – WalterC85
    Jan 23 at 22:15

















  • You can also set -o pipefail and set -e.
    – DopeGhoti
    Jan 23 at 20:47










  • @DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
    – ilkkachu
    Jan 23 at 20:51










  • so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
    – WalterC85
    Jan 23 at 22:15
















You can also set -o pipefail and set -e.
– DopeGhoti
Jan 23 at 20:47




You can also set -o pipefail and set -e.
– DopeGhoti
Jan 23 at 20:47












@DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
– ilkkachu
Jan 23 at 20:51




@DopeGhoti, ah pipefail of course, thanks. set -e only helps here with pipefail, but I don't think they want that at all.
– ilkkachu
Jan 23 at 20:51












so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
– WalterC85
Jan 23 at 22:15





so i did the echo $PIPESTATUS[@] and this is how it looks like: 0 0 0 0 0 0 0 0 0 0 so basically is always 0 even if is not copying any file because mdfind didn't found (in my case i have an input file with 5 files to look for and the last file doesn't exist on my computer so cant be find and/or copied)
– WalterC85
Jan 23 at 22:15













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f419151%2fhow-to-redirect-mdfind-output-to-if-else-statament-in-bash%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?