와일드카드를 사용하여 mv를 호출할 때 오류가 발생했습니다.

와일드카드를 사용하여 mv를 호출할 때 오류가 발생했습니다.
#! /bin/bash

error_text=$(tail -n +1 /path/dir/folder/exc/a/update/Abd/ER/* | \
    grep 'Warning\|Loaded\|Event')
echo $error_text

nc 10.10.99.45 25 << EOF
ehlo mail.abc.pvt
mail from: [email protected]
rcpt to: [email protected]
data
subject: errors
$error_text
.
quit
EOF
mv Abc*.err /path/dir/folder/exc/a/update/Abd/ER/BkError/

내가 얻는 오류는 다음과 같습니다.

mv: cannot stat `ACQ*.err': No such file or directory

답변1

와일드카드를 사용하여 프로그램을 호출하면 사용 중인 셸은 와일드카드를 확장하고 확장된 파일 이름을 실행 파일에 대한 인수로 전달하려고 시도합니다. 확장이 불가능할 경우 쉘은 와일드카드 문자를 프로세스에 파일 이름으로 제공합니다.

다음 strace출력을 참조하십시오(파일이 있음).

user@host:~$ mv test* /tmp/
execve("/bin/mv", ["mv", "test", "test1", "test2", "test3", "/tmp"], [/* 19 vars */]) = 0

이제 다음이 strace출력됩니다(와일드카드와 일치하는 파일이 존재하지 않음).

user@host:~$ mv test* /tmp/
execve("/bin/mv", ["mv", "test*", "/tmp/"], [/* 19 vars */]) = 0

파일 이동을 사용할 때 mv프로그램은 mv먼저 파일 상태를 얻으려고 시도합니다. 이는 시스템 호출을 통해 수행됩니다 stat(참고자료 참조 man 2 stat). 파일(또는 귀하의 경우 여러 파일)의 상태를 수집할 수 없는 경우 프로세스 mv를 계속할 수 없습니다.

두 번째 경우에는 stat 시스템 호출이 실패합니다.

lstat("test*", 0x7fff20d26490)          = -1 ENOENT (No such file or directory)

긴 이야기 짧게: 이 문과 일치하는 파일이 없습니다 ACQ*.err.

답변2

와일드카드 패턴이 어떤 파일과도 일치하지 않으면 쉘은 이를 변경하지 않고 그대로 둡니다.

허위 오류를 방지하려면 먼저 일치 항목을 확장한 다음 결과가 존재하지 않는 파일인지 확인하세요. ¹ 위치 인수(일반적으로 스크립트에 전달된 인수 포함)를 파일 목록으로 설정할 수 있습니다. ²

set -- Abc*.err
if [ -e "$1" ]; then
  mv "$@" /path/dir/folder/exc/a/update/Abd/ER/BkError/
fi

Bash에서는 (일반은 아님) sh일치하지 않는 패턴을 변경하지 않고 빈 문자열로 확장하도록 구성을 변경할 수 있습니다.

shopt -s nullglob
err_files=(Abc*.err)
if ((${#err_files[@]} != 0)); then
  mv "${err_files[@]}" /path/dir/folder/exc/a/update/Abd/ER/BkError/
fi

1 결과적으로 포함될 수 있습니다 […]. 완전성을 위해 확장이 원래 값과 동일한지 테스트해야 합니다. ² '파일 이름 목록 처리 방법'을
참조하세요 .공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?더 많은 설명을 원하시면.

관련 정보