명령이 빈 문자열을 출력하는지 어떻게 테스트 할 수 있습니까?
답변
이전에는 디렉토리에 파일이 있는지 확인하는 방법에 대한 질문이있었습니다. 다음 코드는이를 달성하지만 더 나은 솔루션 은 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
자세한 내용은 여기를 참조하십시오 .
답변
TL; DR
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
그들은 모두 같은 것을 할 대신) :
- 명령을 실행
- 전체 출력을 RAM에 버퍼링
- 출력을 거대한 단일 행 문자열로 변환
- 해당 문자열을 빈 문자열과 비교
내가 대신 제안하는 것은 다음과 같습니다.
- 명령을 실행
- 저장하지 않고 출력에서 문자를 계산
- 또는 더 나은-최대 1 자의 수를 세십시오
using head -c1
( 아래 의견 에이 아이디어를 게시 한 netj 덕분에 )
- 또는 더 나은-최대 1 자의 수를 세십시오
- 그 숫자를 0과 비교
예를 들어 다음 대신
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 저장 및 잠재적으로 큰 데이터 처리를 피하십시오.
답은 출력이 항상 작다는 것을 명시하지 않았으므로 큰 출력의 가능성도 고려해야합니다.
답변
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
답변
6.4 배쉬 조건식
-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
답변
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