mdfind 출력을 bash의 if else 문으로 리디렉션하는 방법

mdfind 출력을 bash의 if else 문으로 리디렉션하는 방법

입력 파일에 나열된 일부 파일을 컴퓨터 전체에서 살펴본 다음 해당 파일을 특정 폴더에 복사하는 스크립트를 만들려고 합니다. 지금까지 for 루프와 mdfind "command" xargs를 사용하면 모든 것이 잘 작동합니다. 그러나 mdfind가 찾지 못한 파일 목록이 포함된 출력 파일을 생성하기 위해 if 문을 추가하면 문제가 발생합니다. 이것은 내 실제 코드입니다.

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

출력을 리디렉션하기 위해 $?를 사용하고 있습니다.

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

그러나 입력 파일에 나열된 파일 중 하나를 찾을 수 없는 경우에도 항상 = 0입니다.

누구든지 오류가 어디에 있는지 이해하도록 도와줄 수 있나요?

감사합니다!

답변1

를 실행한 후 mdfind ... | xargs cp ...의 오류 코드는 파이프라인의 마지막 명령이므로 $?오류 코드 입니다. 실행된 명령이 실패하면 123을 반환하지만 출력이 생성 되지 않으면 아무 작업도 수행하지 않으므로 실패하지 않습니다.xargsxargsmdfindxargs

그러나 Bash에서는 마지막 파이프에서 모든 명령의 종료 코드를 찾을 수 있습니다.배열 변수 PIPESTATUS. 첫 번째 명령의 종료 코드는 ${PIPESTATUS[0]}다음과 같습니다.

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

따라서 $?종료 상태를 제공하는 메서드를 사용하는 대신 종료 상태를 제공하는 메서드를 사용할 수 있습니다. 또는 배치를 다른 변수에 저장하고 둘 다 테스트하십시오. ( )xargs${PIPESTATUS[0]}mdfindsaved=("${PIPESTATUS[@]}")

또는 파이프라인에서 마지막으로 실패한 명령 중 하나라도 실패한 경우 해당 명령의 종료 코드를 제공 set -o pipefail하도록 사용하십시오. $?( false | true결과는 $?=1.)

관련 정보