명령이 빈 문자열을 출력하는지 어떻게 테스트 할 수 있습니까?
ifne
를 가지고 있습니다. joeyh.name/code/moreutils
명령이 빈 문자열을 출력하는지 어떻게 테스트 할 수 있습니까?
ifne
를 가지고 있습니다. joeyh.name/code/moreutils
답변:
이전에는 디렉토리에 파일이 있는지 확인하는 방법에 대한 질문이있었습니다. 다음 코드는이를 달성하지만 더 나은 솔루션 은 rsp의 답변 을 참조하십시오 .
명령은 값을 반환 하지 않고 출력합니다. 명령 대체 를 사용하여이 출력을 캡처 할 수 있습니다 . 예 $(ls -A)
. Bash에서 비어 있지 않은 문자열을 다음과 같이 테스트 할 수 있습니다.
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
심볼릭 현재 ( ) 및 부모 ( ) 디렉토리 항목 이 생략되어 있기 때문에 내가 -A
아닌 사용 -a
했습니다 ..
..
참고 : 주석에서 지적했듯이 명령 대체 는 후행 줄 바꿈을 캡처하지 않습니다 . 따라서 명령이 개행 만 출력 하면 대체는 아무것도 캡처하지 않고 테스트는 false를 리턴합니다. 아주 드물지만 위의 예에서는 단일 줄 바꿈이 유효한 파일 이름이므로 가능합니다! 이 답변에 대한 자세한 정보 .
명령이 성공적으로 완료되었는지 확인 $?
하려면 마지막 명령의 종료 코드 (성공의 경우 0, 실패의 경우 0이 아님)를 포함하는 inspect를 검사 할 수 있습니다 . 예를 들면 다음과 같습니다.
files=$(ls -A)
if [[ $? != 0 ]]; then
echo "Command failed."
elif [[ $files ]]; then
echo "Files found."
else
echo "No files found."
fi
자세한 내용은 여기를 참조하십시오 .
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then ...; fi
원본을 개선 할 것을 제안 하는 netj 에게 감사드립니다 .if [[ $(ls -A | wc -c) -ne 0 ]]; then ...; fi
이것은 오래된 질문이지만 개선이 필요하거나 설명이 필요한 두 가지 이상이 있습니다.
내가 본 첫 번째 문제는 여기에 제공된 대부분의 예제가 작동하지 않는다는 것 입니다. 빈 디렉토리에 비어 있지 않은 문자열을 출력 하는 ls -al
및 ls -Al
명령을 사용합니다 . 이러한 예제 는 파일 이없는 경우에도 항상 파일이 있다고보고합니다 .
이러한 이유로 당신은 그냥 사용해야합니다 ls -A
-왜 -l
출력이 있는지 여부에 관계없이 원하는 것이 테스트 될 때 누군가가 "긴 목록 형식 사용"을 의미 하는 스위치를 사용하고 싶습니까?
따라서 대부분의 대답은 간단하지 않습니다.
두 번째 문제는 동안이다 일부 답변이 잘 작동 (사람들을 그 않는 사용 ls -al
또는 ls -Al
하지만 ls -A
그들은 모두 같은 것을 할 대신) :
내가 대신 제안하는 것은 다음과 같습니다.
using head -c1
예를 들어 다음 대신
if [[ $(ls -A) ]]
나는 사용할 것이다 :
if [[ $(ls -A | wc -c) -ne 0 ]]
# or:
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]
대신에:
if [ -z "$(ls -lA)" ]
나는 사용할 것이다 :
if [ $(ls -lA | wc -c) -eq 0 ]
# or:
if [ $(ls -lA | head -c1 | wc -c) -eq 0 ]
등등.
작은 출력의 경우 문제가되지 않지만 큰 출력의 경우 차이가 클 수 있습니다.
$ time [ -z "$(seq 1 10000000)" ]
real 0m2.703s
user 0m2.485s
sys 0m0.347s
그것을 다음과 비교하십시오.
$ time [ $(seq 1 10000000 | wc -c) -eq 0 ]
real 0m0.128s
user 0m0.081s
sys 0m0.105s
그리고 더 나은 :
$ time [ $(seq 1 10000000 | head -c1 | wc -c) -eq 0 ]
real 0m0.004s
user 0m0.000s
sys 0m0.007s
Will Vousden의 답변에서 업데이트 된 예 :
if [[ $(ls -A | wc -c) -ne 0 ]]; then
echo "there are files"
else
echo "no files found"
fi
netj의 제안 후 다시 업데이트되었습니다 .
if [[ $(ls -A | head -c1 | wc -c) -ne 0 ]]; then
echo "there are files"
else
echo "no files found"
fi
jakeonfire의 추가 업데이트 :
grep
일치하지 않으면 실패와 함께 종료됩니다. 구문을 약간 단순화하기 위해이를 활용할 수 있습니다.
if ls -A | head -c1 | grep -E '.'; then
echo "there are files"
fi
if ! ls -A | head -c1 | grep -E '.'; then
echo "no files found"
fi
테스트중인 명령이 빈 문자열로 처리 할 공백을 출력 할 수있는 경우 대신 다음을 수행하십시오.
| wc -c
당신은 사용할 수 있습니다 :
| tr -d ' \n\r\t ' | wc -c
또는 함께 head -c1
:
| tr -d ' \n\r\t ' | head -c1 | wc -c
또는 그런 것.
먼저 작동 하는 명령을 사용하십시오 .
둘째, 불필요한 RAM 저장 및 잠재적으로 큰 데이터 처리를 피하십시오.
답은 출력이 항상 작다는 것을 명시하지 않았으므로 큰 출력의 가능성도 고려해야합니다.
[[ $(... | head -c | wc -c) -gt 0 ]]
또는 명령의 전체 출력을 사용해야 [[ -n $(... | head -c1) ]]
하므로 더 좋습니다 wc -c
.
if [ -z "$(ls -lA)" ]; then
echo "no files found"
else
echo "There are files"
fi
명령을 실행하고 반환 된 출력 (문자열)의 길이가 0인지 확인합니다. 다른 플래그에 대해서는 'test'매뉴얼 페이지 를 확인하십시오 .
검사중인 인수 주위에 ""를 사용하십시오. 그렇지 않으면 빈 검사 결과에 두 번째 인수 (확인)가 없으므로 구문 오류가 발생합니다!
참고 : 것을 ls -la
항상 반환 .
하고 ..
그래서하지 않습니다 작업을 사용하여이 참조 LS에게 매뉴얼 페이지를 . 또한 이것이 편리하고 쉬운 것처럼 보이지만 쉽게 깨질 것이라고 생각합니다. 결과에 따라 0 또는 1을 반환하는 작은 스크립트 / 응용 프로그램을 작성하는 것이 훨씬 더 안정적입니다!
$(
, 대신 역 인용 부호로 인해 $(
더 나은 둥지
우아하고 bash 버전 독립적 인 솔루션을 원하거나 (현대 다른 쉘에서 작동해야 함) 빠른 작업을 위해 하나의 라이너를 사용하는 것을 좋아하는 사람들을 위해. 우리는 간다!
ls | grep . && echo 'files found' || echo 'files not found'
(주 코멘트 중 하나를 언급 한 바와 같이, ls -al
사실, 단지 -l
및 -a
모든 반환 뭔가, 그래서 내 대답에 나는 간단한을 사용합니다ls
grep -q ^
대신, 줄 바꿈 문자도 일치하며, GREP은 표준 출력에 아무것도 인쇄되지 않습니다. 또한 입력 스트림이 끝나기를 기다리지 않고 입력을받는 즉시 종료됩니다.
ls -A
도트 파일 (또는 디렉토리)을 포함하려면 먼저 시작해야합니다.
-z string
True if the length of string is zero.
-n string
string
True if the length of string is non-zero.
속기 버전을 사용할 수 있습니다.
if [[ $(ls -A) ]]; then
echo "there are files"
else
echo "no files found"
fi
string
의 동의어 일뿐 입니다 -n string
.
Jon Lin이 언급했듯이 ls -al
항상 (for .
및 ..
)을 출력 합니다. ls -Al
이 두 디렉토리를 피 하려고 합니다.
예를 들어 명령 출력을 쉘 변수에 넣을 수 있습니다.
v=$(ls -Al)
더 오래된, 중첩 할 수없는 표기법은
v=`ls -Al`
하지만 중첩 가능한 표기법을 선호합니다 $(
...)
해당 변수가 비어 있지 않은지 테스트 할 수 있습니다
if [ -n "$v" ]; then
echo there are files
else
echo no files
fi
그리고 당신은 둘 다를 결합 할 수 있습니다 if [ -n "$(ls -Al)" ]; then
나는 당신이 ls -al
명령 의 출력을 원한다고 추측한다 . 그래서 bash에서는 다음과 같은 것을 가질 것이다.
LS=`ls -la`
if [ -n "$LS" ]; then
echo "there are files"
else
echo "no files found"
fi
ls
이 실행되지 않습니다. 변수 의 확장이LS
비어 있지 않은지 확인하십시오 .
-a
스위치 (이 파일입니다 여부 즉,이 내용을 반환합니다) 항상 암시가 있기 때문에 어떤 내용을 반환하지 않습니다 .
및 ..
디렉토리 존재.
지금까지 제공된 모든 대답 은 비어 있지 않은 문자열 을 종료 하고 출력하는 명령을 처리 합니다.
대부분의 의미는 다음과 같습니다.
yes
.이러한 모든 문제를 해결하고 다음 질문에 효율적으로 답변하려면
명령이 빈 문자열을 출력하는지 어떻게 테스트 할 수 있습니까?
당신이 사용할 수있는:
if read -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
read
의 -t
옵션을 사용하여 명령이 주어진 시간 내에 비어 있지 않은 문자열을 출력하는지 테스트하기 위해 시간 초과를 추가 할 수도 있습니다 . 예를 들어, 2.5 초 시간 초과 :
if read -t2.5 -n1 -d '' < <(command_here); then
echo "Command outputs something"
else
echo "Command doesn't output anything"
fi
말. 명령이 비어 있지 않은 문자열을 출력하는지 여부를 결정해야한다면 XY 문제 일 가능성이 큽니다.
seq 1 10000000
, seq 1 20
및 printf""
). 이 읽기 접근 방식이 이기지 못한 유일한 매치업 -z "$(command)"
은 빈 입력에 대한 접근 방식입니다. 그렇더라도 약 10-15 % 만 손실됩니다. 그들은 심지어 주위를 깰 것 같다 seq 1 10
. 그럼에도 불구 하고 입력 크기가 커질 -z "$(command)"
수록 접근 방식이 너무 느려져 가변 크기 입력에 사용하지 않는 것이 좋습니다.
다음은 일부 명령의 std-out 및 std-err에 임시 파일을 쓴 다음 해당 파일이 비어 있는지 확인하는 대체 방법입니다. 이 방법의 장점은 두 출력을 모두 캡처하고 하위 셸 또는 파이프를 사용하지 않는다는 것입니다. 후자의 측면은 bash 종료 처리 트래핑을 방해 할 수 있으므로 중요합니다 (예 : 여기 )
tmpfile=$(mktemp)
some-command &> "$tmpfile"
if [[ $? != 0 ]]; then
echo "Command failed"
elif [[ -s "$tmpfile" ]]; then
echo "Command generated output"
else
echo "Command has no output"
fi
rm -f "$tmpfile"