
이 스크립트는 때때로 실패하고 때로는 성공합니다(매우 짜증나는 상황).
#!/bin/bash
set -Eeuxo pipefail
test_dir="$(mktemp -d)"
touch "$test_dir/file"{001..312}
latest_file="$(find $test_dir -type f | sort -r | head -n1)"
echo $latest_file
성공하면 다음과 같이 기록됩니다.
++ mktemp -d
+ test_dir=/tmp/tmp.yWelcpBYB7
+ touch /tmp/tmp.yWelcpBYB7/file001 /tmp/tmp.yWelcpBYB7/file002 ... /tmp/tmp.yWelcpBYB7/file312
++ find /tmp/tmp.yWelcpBYB7 -type f
++ head -n1
++ sort -r
+ latest_file=/tmp/tmp.yWelcpBYB7/file312
+ echo /tmp/tmp.yWelcpBYB7/file312
/tmp/tmp.yWelcpBYB7/file312
실패하면 다음과 같이 기록됩니다.
++ mktemp -d
+ test_dir=/tmp/tmp.VzTqmgpZyG
+ touch /tmp/tmp.VzTqmgpZyG/file001 /tmp/tmp.VzTqmgpZyG/file002 ... /tmp/tmp.VzTqmgpZyG/file312
++ find /tmp/tmp.VzTqmgpZyG -type f
++ sort -r
++ head -n1
+ latest_file=/tmp/tmp.VzTqmgpZyG/file312
echo $latest_file
라인 은 다음 과 같습니다.~ 아니다xtrace에 나타나더라도 여기서 실행됩니다.
10,000개의 파일을 사용하면 성공적으로 실행될 수 없으므로 이것이 무엇인가 관련이 있는 것으로 의심됩니다.머리멎는찾다일찍.
#!/bin/bash
set -Eeuxo pipefail
test_dir="$(mktemp -d)"
touch "$test_dir/file"{0000..9999}
latest_file="$(find $test_dir -type f | sort -r | head -n1)"
echo $latest_file
오류 발생 시 중지를 억제하는 경우(사용세트 +e), 성공합니다:
#!/bin/bash
set -Eeuxo pipefail
test_dir="$(mktemp -d)"
touch "$test_dir/file"{0000..9999}
set +e
latest_file="$(find $test_dir -type f | sort -r | head -n1)"
set -e
echo $latest_file
이 스크립트가 최신 파일을 안정적으로 기록하지 못하는 이유는 무엇입니까?
답변1
문제는 -e
. 왜? -e
프로세스가 0이 아닌 종료 코드로 종료되는 경우 bash를 중단합니다(전체 규칙은 좀 더 복잡합니다). 파이프가 있으면 마지막 명령만 계산됩니다.
의 나머지 출력을 무시하려면 head -n1
파이프를 끊어야 하기 때문에( 로 확인할 수 있음) 내부적으로 오류 상황이 발생 합니다 .strace
sort
따라서 스크립트가 에서 안정적으로 작동하도록 하려면 파이프 끝에 -e
를 추가할 수 있습니다 . 여전히 파이프가 끊어지지만 더 이상 파이프의 마지막 명령이 아니기 때문에 에서는 고려되지 않습니다 . 파이프에 대해서는 작동하지 않습니다.cat
head
-e
cat
#!/bin/bash
set -Eeuxo pipefail
test_dir="$(mktemp -d)"
touch "$test_dir/file"{0000..9999}
latest_file="$(find $test_dir -type f | sort -r | head -n1 | cat)"
echo $latest_file
확인해주십시오set -e(또는 set -o errexit 또는 트랩 ERR)가 예상한 대로 수행되지 않는 이유는 무엇입니까?-e
왜 그렇게 불안정한 기능인지, 그리고 어떤 종류의 문제가 발생할 수 있는지 알아보세요 . 마지막에는 많은 예가 있습니다. 내가 좋아하는 것:
#!/bin/bash
set -e
foo=$(expr 1 - 1)
echo survived
그럴 것이다~ 아니다인쇄살아남았다, 해당 줄은 실행되지 않습니다. 하지만 가 있었다면 foo=$(expr 2 - 1)
이 echo
실행될 것입니다!
자체 오류 검사를 구현하는 것이 더 나을 것입니다. -e
최고의 솔루션은 아닙니다.